From 4a4c2fc578605d8417e97b200333a160b3e4ca86 Mon Sep 17 00:00:00 2001 From: devon Date: Sun, 23 Sep 2018 11:37:51 +0800 Subject: [PATCH 01/11] Update README.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index de443cc..c337322 100644 --- a/README.md +++ b/README.md @@ -1 +1,2 @@ # python exercise +2018-09-23 From e70c920fb3eb7476bc4676db141ac2e7c38cda13 Mon Sep 17 00:00:00 2001 From: devon Date: Sun, 23 Sep 2018 12:08:02 +0800 Subject: [PATCH 02/11] Update README.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index c337322..1c0566f 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,3 @@ # python exercise 2018-09-23 +test From 23e69f78caa421bf105a9f63cf5005a6ea211848 Mon Sep 17 00:00:00 2001 From: devon6686 Date: Sun, 23 Sep 2018 12:13:20 +0800 Subject: [PATCH 03/11] add test.txt --- test.txt | 1 + 1 file changed, 1 insertion(+) create mode 100644 test.txt diff --git a/test.txt b/test.txt new file mode 100644 index 0000000..9daeafb --- /dev/null +++ b/test.txt @@ -0,0 +1 @@ +test From 0c619409e152a1b598169eab28c36943ace43e1a Mon Sep 17 00:00:00 2001 From: devon Date: Sun, 23 Sep 2018 12:33:37 +0800 Subject: [PATCH 04/11] Update test.txt --- test.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/test.txt b/test.txt index 9daeafb..72167ef 100644 --- a/test.txt +++ b/test.txt @@ -1 +1,2 @@ test +111 From a59fff1e08cae9befb6786c5d9f150d243d96f61 Mon Sep 17 00:00:00 2001 From: devon Date: Sun, 23 Sep 2018 13:21:03 +0800 Subject: [PATCH 05/11] Update test.txt --- test.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/test.txt b/test.txt index 72167ef..3c0c0b4 100644 --- a/test.txt +++ b/test.txt @@ -1,2 +1,3 @@ test 111 +123 From 2f287eec56796363fcb2bbdd90c1feebe41176dc Mon Sep 17 00:00:00 2001 From: devon6686 Date: Mon, 24 Sep 2018 09:01:49 +0800 Subject: [PATCH 06/11] Merge remote-tracking branch 'origin/master' Signed-off-by: devon6686 --- package.py | 110 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 110 insertions(+) create mode 100644 package.py diff --git a/package.py b/package.py new file mode 100644 index 0000000..b5c4512 --- /dev/null +++ b/package.py @@ -0,0 +1,110 @@ +#!/usr/bin/env python3 +""" +replace settings file path of product package(war, jar) and re-archive packages for dmz-cloud environment +war: 'WEB-INF/classes/spring-config.xml' +jar: 'spring-config.xml' +pattern: 'nfs/wanjia/settings' -> 'nfs/wanjia/cloud-settings' +""" + +import argparse +import configparser +import os +import re +import shutil +from datetime import datetime +from pathlib import Path +from zipfile import ZipFile + + +def make_package(pkg, configfile, workdir, keyword='nfs/wanjia/settings', srcdir='/data', dstdir='/project/cloud/data'): + def unarchive_pkg(srcpkg, workdir): + flag = True + if Path(srcpkg).exists(): + shutil.rmtree(workdir) if Path(workdir).exists() else print('Dir: {} will be delete'.format(workdir)) + Path(workdir).mkdir(parents=True) + shutil.copy2(srcpkg, workdir) + if Path(workdir).exists(): + with ZipFile(srcpkg) as zf: + zf.extractall(workdir) + print('succeed unarchive package: {}'.format(srcpkg)) + else: + flag = False + print('Error! src pkg: {} not found'.format(srcpkg)) + return flag + + def rep_conf_file(conf_file, keyword: str, oldstr='settings', newstr='cloud-settings'): + flag = True + pattern = re.compile(keyword) + dst_file = str(Path(workdir) / Path(conf_file)) + if Path(dst_file).exists(): + new_conf_file = dst_file + '.new' + with open(new_conf_file, mode='a+') as nf: + with open(dst_file) as of: + for line in of: + if pattern.findall(line): + line = line.replace(oldstr, newstr) + nf.write(line) + Path(new_conf_file).rename(dst_file) + else: + flag = False + print('Error! config file: {} not found'.format(str(conf_file))) + return flag + + def archive_pkg(pkg, workdir, config_file): + os.chdir(workdir) + zf = ZipFile(pkg, 'a') + zf.write(config_file) + zf.close() + shutil.copy(pkg, dst_dir) + print('New Package: {}'.format(pkg)) + print('>>' * 20) + + src_pkg = str(Path(srcdir) / Path(pkg)) + + if unarchive_pkg(src_pkg, workdir): + if len(configfile) == 1: + archive_pkg(pkg, workdir, configfile) if rep_conf_file(configfile, keyword) else print('Error') + else: + for conf_file in configfile: + archive_pkg(pkg, workdir, conf_file) if rep_conf_file(conf_file, keyword) else print('Error') + + +if __name__ == '__main__': + parser = argparse.ArgumentParser(description='replcae spring-config.xml') + group = parser.add_mutually_exclusive_group() + group.add_argument('-p', metavar='project_name', dest='project', help='project name') + group.add_argument('-a', action='store_true', dest='all', help='all projects') + args = parser.parse_args() + + cfg = configparser.ConfigParser() + project_file = "projects.ini" + cfg.read(project_file) + + dst_dir = '/project/cloud/data' + print(args) + if args.all: + print('Replace All projects') + print('--' * 20) + fail_pkg = [] + success_pkg = [] + for project in cfg.sections(): + pkg_name = cfg.get(project, 'package') + config = cfg.get(project, 'configFile').split(',') + flag = datetime.now().strftime('%Y%m%d/%H%M%S') + ts = datetime.now().strftime('%Y%m%d/%H%M%S') + workdir = str(Path(dst_dir) / Path(ts)) + try: + make_package(pkg_name, config, workdir) + except: + fail_pkg.append(pkg_name) + else: + success_pkg.append(pkg_name) + print('Success Projects: ', success_pkg) + print('Failed Projects: ', fail_pkg) + else: + pkg_name = cfg.get(args.project, 'package') + config = cfg.get(args.project, 'configFile').split(',') + ts = datetime.now().strftime('%Y%m%d/%H%M%S') + workdir = str(Path(dst_dir) / Path(ts)) + print('pkg: {} config_file: {} workdir:{}'.format(pkg_name, config, workdir)) + make_package(pkg_name, config, workdir) From b49df2d47064a95a7f85f03511fdd05e573570fc Mon Sep 17 00:00:00 2001 From: devon6686 Date: Sun, 7 Oct 2018 00:04:05 +0800 Subject: [PATCH 07/11] Merge remote-tracking branch 'origin/master' Signed-off-by: devon6686 --- week/threading/ex1.py | 50 +++++++++++++++++++++++++++++++++++++++++++ week/threading/ex2.py | 17 +++++++++++++++ week/threading/ex3.py | 16 ++++++++++++++ 3 files changed, 83 insertions(+) create mode 100644 week/threading/ex1.py create mode 100644 week/threading/ex2.py create mode 100644 week/threading/ex3.py diff --git a/week/threading/ex1.py b/week/threading/ex1.py new file mode 100644 index 0000000..6fb7c08 --- /dev/null +++ b/week/threading/ex1.py @@ -0,0 +1,50 @@ +#!/usr/bin/env python3 +import time + +import threading + + +class MyThread(threading.Thread): + + def start(self) -> None: + print('start') + super().start() + + def run(self) -> None: + print('run') + super().run() + + +def worker1(n=5): + print('current_thread\n\t', threading.current_thread()) + print('Main_thread\n\t', threading.main_thread()) + print(threading.active_count()) + print('enumerate\n\t', threading.enumerate()) + for _ in range(n): + time.sleep(1) + print('t1: hello world') + print('Thread over') + + +def worker(n=5): + print(threading.current_thread()) + for _ in range(n): + time.sleep(1) + print('hello world2') + print('Thread Over') + + +# print(threading.current_thread(), '-----') +# t = threading.Thread(target=worker1, name='worker') +# t.start() +# print('enumerate\n\t', threading.enumerate(), '********') + + +t = MyThread(target=worker, name='w1') +# t.run() +t.start() +print('~~~~~' * 20) + +t1 = MyThread(target=worker, name='w2') +# t.run() # start方法是多线程,run方法只是普通的函数调用 +t1.start() diff --git a/week/threading/ex2.py b/week/threading/ex2.py new file mode 100644 index 0000000..2cb0bbe --- /dev/null +++ b/week/threading/ex2.py @@ -0,0 +1,17 @@ +#!/usr/bin/env python3 +import threading + +X = 'abc' +ctx = threading.local() +ctx.x = 123 +print(type(ctx), type(ctx.x)) + + +def worker(): + print(X) + print(ctx) + # ctx.x = 567 # 线程间资源隔离,threading.local相当于本地局部变量的作用 + print(ctx.x) + + +threading.Thread(target=worker).start() diff --git a/week/threading/ex3.py b/week/threading/ex3.py new file mode 100644 index 0000000..d7a6be2 --- /dev/null +++ b/week/threading/ex3.py @@ -0,0 +1,16 @@ +import logging +import threading + +FORMAT = "%(asctime)s %(thread)d %(message)s %(test)s" +logging.basicConfig(level=logging.INFO, format=FORMAT, datefmt="%Y-%m-%d-%H:%M:%S") +d = {'test': 'hello world'} + + +def fadd(x, y): + logging.warning("{} {}".format(threading.enumerate(), x + y)) + logging.info("%s %s", x, y, extra=d) + logging.info("{} {}".format(threading.enumerate(), x + y), extra=d) # 日志级别和格式字符串扩展, dict + + +t = threading.Timer(1, fadd, args=[4, 5]) +t.start() From fd67b0e0741b82cff266d46c9e20646c14c3f2be Mon Sep 17 00:00:00 2001 From: devon6686 Date: Sun, 2 Dec 2018 20:28:51 +0800 Subject: [PATCH 08/11] add nee --- .gitignore | 2 + .idea/encodings.xml | 4 + .idea/vcs.xml | 6 + crawlers/crawler.py | 94 ++++++++++++++++ crawlers/test.py | 24 ++++ exercise/__pycache__/inspect.cpython-36.pyc | Bin 0 -> 671 bytes exercise/chinese_str.py | 44 ++++++++ exercise/file/directory.py | 24 ++++ exercise/file/file_csv.py | 24 ++++ exercise/inspect.py | 26 +++++ exercise/list-comp/ex_1.py | 2 +- exercise/tree/heap_sort1.py | 76 +++++++++++-- gitlab_api/group_info.py | 88 +++++++++++++++ gitlab_api/set_branch.py | 62 +++++++++++ gitlab_api/test.py | 23 ++++ jumpserver/assets.py | 21 +++- spiderdemo/scrapy.cfg | 11 ++ spiderdemo/spiderdemo/__init__.py | 0 .../__pycache__/__init__.cpython-36.pyc | Bin 0 -> 153 bytes .../__pycache__/settings.cpython-36.pyc | Bin 0 -> 267 bytes spiderdemo/spiderdemo/items.py | 14 +++ spiderdemo/spiderdemo/middlewares.py | 103 ++++++++++++++++++ spiderdemo/spiderdemo/pipelines.py | 11 ++ spiderdemo/spiderdemo/settings.py | 90 +++++++++++++++ spiderdemo/spiderdemo/spiders/__init__.py | 4 + .../__pycache__/__init__.cpython-36.pyc | Bin 0 -> 161 bytes .../__pycache__/example.cpython-36.pyc | Bin 0 -> 569 bytes spiderdemo/spiderdemo/spiders/example.py | 11 ++ web/web1.py | 50 +++++++++ week/logging/ex1.py | 43 ++++++++ week/month1.py | 14 +++ week/threading/cups.py | 35 ++++++ week/threading/ex3.py | 40 +++++-- week/threading/newcups.py | 28 +++++ week/threading/timer.py | 47 ++++++++ week/threading/wait.py | 16 +++ week/week2/ex1.py | 9 ++ "week/\345\274\202\345\270\270/ex1.py" | 24 ++++ "week/\345\274\202\345\270\270/ex2.py" | 29 +++++ "week/\345\274\202\345\270\270/ex3.py" | 20 ++++ .../StaticMethod.py" | 43 ++++++++ .../ex1-2.py" | 50 +++++++++ .../ex1.py" | 31 ++++++ 43 files changed, 1218 insertions(+), 25 deletions(-) create mode 100644 .gitignore create mode 100644 .idea/encodings.xml create mode 100644 .idea/vcs.xml create mode 100644 crawlers/crawler.py create mode 100644 crawlers/test.py create mode 100644 exercise/__pycache__/inspect.cpython-36.pyc create mode 100644 exercise/chinese_str.py create mode 100644 exercise/file/directory.py create mode 100644 exercise/file/file_csv.py create mode 100644 exercise/inspect.py create mode 100644 gitlab_api/group_info.py create mode 100644 gitlab_api/set_branch.py create mode 100644 gitlab_api/test.py create mode 100644 spiderdemo/scrapy.cfg create mode 100644 spiderdemo/spiderdemo/__init__.py create mode 100644 spiderdemo/spiderdemo/__pycache__/__init__.cpython-36.pyc create mode 100644 spiderdemo/spiderdemo/__pycache__/settings.cpython-36.pyc create mode 100644 spiderdemo/spiderdemo/items.py create mode 100644 spiderdemo/spiderdemo/middlewares.py create mode 100644 spiderdemo/spiderdemo/pipelines.py create mode 100644 spiderdemo/spiderdemo/settings.py create mode 100644 spiderdemo/spiderdemo/spiders/__init__.py create mode 100644 spiderdemo/spiderdemo/spiders/__pycache__/__init__.cpython-36.pyc create mode 100644 spiderdemo/spiderdemo/spiders/__pycache__/example.cpython-36.pyc create mode 100644 spiderdemo/spiderdemo/spiders/example.py create mode 100644 web/web1.py create mode 100644 week/logging/ex1.py create mode 100644 week/month1.py create mode 100644 week/threading/cups.py create mode 100644 week/threading/newcups.py create mode 100644 week/threading/timer.py create mode 100644 week/threading/wait.py create mode 100644 week/week2/ex1.py create mode 100644 "week/\345\274\202\345\270\270/ex1.py" create mode 100644 "week/\345\274\202\345\270\270/ex2.py" create mode 100644 "week/\345\274\202\345\270\270/ex3.py" create mode 100644 "week/\346\217\217\350\277\260\345\231\250/StaticMethod.py" create mode 100644 "week/\346\217\217\350\277\260\345\231\250/ex1-2.py" create mode 100644 "week/\346\217\217\350\277\260\345\231\250/ex1.py" diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..f32e31a --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +.idea/ +.DS_Store diff --git a/.idea/encodings.xml b/.idea/encodings.xml new file mode 100644 index 0000000..15a15b2 --- /dev/null +++ b/.idea/encodings.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..94a25f7 --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/crawlers/crawler.py b/crawlers/crawler.py new file mode 100644 index 0000000..d1084c7 --- /dev/null +++ b/crawlers/crawler.py @@ -0,0 +1,94 @@ +""" +爬取如下站点所有文件: +https://npm.taobao.org/mirrors/node-sass/ +https://npm.taobao.org/dist +https://npm.taobao.org/mirrors/phantomjs +https://npm.taobao.org/mirrors/electron +https://npm.taobao.org/mirrors/fsevents +""" +import re +import time +import requests +from bs4 import BeautifulSoup +import logging +import threading +from queue import Queue +from pathlib import Path +from concurrent.futures import ThreadPoolExecutor + + +FORMAT = "%(levelname)s %(asctime)s %(thread)s %(message)s" +logging.basicConfig(level=logging.INFO, format=FORMAT) +log = logging.getLogger('crawler') +handler = logging.FileHandler('./crawler.log') +handler.setLevel(logging.INFO) +log.addHandler(handler) + +BASE_URL = "https://npm.taobao.org/" +uri_list = ["mirrors/node-sass/2331/", ] +ua = "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.75 Safari/537.36" +headers = {'User-Agent': ua} + +urls = Queue() # 存取待下载文件的url +outputs = Queue() + +event = threading.Event() +store_dir = "./" + + +# 1. 获取url +def crawler_urls(uri: str): + pattern = re.compile('.+/$') + url = BASE_URL + uri + if pattern.match(uri): + try: + result = requests.get(url, headers=headers).text + soup = BeautifulSoup(result, features="html.parser") + for element in soup.find_all(href=re.compile(uri)): + for child in element.descendants: + sub_uri = uri + child + if pattern.match(child): + crawler_urls(sub_uri) + else: + sub_url = url + child + urls.put(sub_url) + except Exception as e: + log.error(e) + else: + urls.put(url) + + +# 2.下载文件 +def download(): + while not event.is_set(): + try: + url = urls.get(True, 1) + with requests.get(url, headers=headers, stream=True) as response: + uri_path = url.split(BASE_URL)[-1] + full_path = Path(store_dir)/Path(uri_path) + print(uri_path) + if not full_path.parent.exists(): + full_path.parent.mkdir(parents=True) + with open(str(full_path), 'wb') as fd: + for chunk in response.iter_content(chunk_size=1024): + fd.write(chunk) + except Exception as e: + log.error(e) + else: + log.info("ok: {}".format(url)) + + +executor = ThreadPoolExecutor(max_workers=10) + +for uri in uri_list: + executor.submit(crawler_urls, uri) +for i in range(5): + executor.submit(download) + +while True: + inp = input('>>>') + if inp.strip() == 'q': + event.set() + print("Stop Crawler!") + time.sleep(5) + break diff --git a/crawlers/test.py b/crawlers/test.py new file mode 100644 index 0000000..e370d32 --- /dev/null +++ b/crawlers/test.py @@ -0,0 +1,24 @@ +import requests +from bs4 import BeautifulSoup +import re + +test_url = "https://npm.taobao.org/mirrors/node-sass/2331/win32-ia32-11_binding.node" +test_uri = "mirrors/node-sass/2331/win32-ia32-11_binding.node" +uri1 = "mirrors/node-sass/" +url1 = "https://npm.taobao.org/mirrors/node-sass/" +ua = "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.75 Safari/537.36" +headers = {'User-Agent': ua} +r = requests.get(test_url, headers=headers).text +soup = BeautifulSoup(r, features="html.parser") +print(soup.find_all(href=re.compile(test_uri))) +# for element in soup.find_all(href=re.compile(test_uri)): +# for i in element.descendants: +# print(i) +# # print(soup.find_all(href=re.compile('https:.+/$'))) + +# base_url = "https://npm.taobao.org/" +# print(test_url.split(base_url)) +# +# from pathlib import Path +# filepath = '/ttt/ssss/ssddd' +# print(Path(filepath).parent, type(Path(filepath).parent)) diff --git a/exercise/__pycache__/inspect.cpython-36.pyc b/exercise/__pycache__/inspect.cpython-36.pyc new file mode 100644 index 0000000000000000000000000000000000000000..4a89a518267c78d6ca7930849b35fd73095f2f61 GIT binary patch literal 671 zcmY*VyKWRQ6t%~m$2!?ff+CT0v{NjjC>@HT6f`uUKs3{gMr$X`Bx{dsZ^-6REfO?H zG<5s`1ri+%@F8wdK>3AKxtd`ELC0zqdu4@JbII_5D?){zKj!3;xm#Cvrt!aAAZJI-3( z`_H|`mo`zSwrqJ5)$9T9FQ~v4)WL!ZtW){QE0nHI1~3AI(}*>hoztZK4Gt6Gd~)=cdiCAaT?aVqqvG9s&_X&~Tf zGlk5YZ}lLTY1_h@0X_@QFWLF!85s_T*R5mFl)4-X3&oy20flw5c-(f_^&0!e{3QG7 zl8cLit5H$7_^zDx6&$IgZHqVpD{^6@!Qr9W%7t7cpb089o)ZLN@=4@ literal 0 HcmV?d00001 diff --git a/exercise/chinese_str.py b/exercise/chinese_str.py new file mode 100644 index 0000000..3fc4cf2 --- /dev/null +++ b/exercise/chinese_str.py @@ -0,0 +1,44 @@ +#!/usr/bin/env python3 +from pathlib import Path +import re + + +def check_chinese(file: str, regex): + try: + with open(file, "r", encoding='utf-8') as f: + for line in f: + num = 0 + rt = regex.findall(line) + if rt: + num += len(rt) + print("\tchinese:", end=" ") + print(rt) + # for content in rt: + # print("\t{}".format(content)) + if num > 1: + print("\nRESULT:\n\tFile: {}\tLineNumber:{}\n".format(file, num)) + except UnicodeDecodeError as e: + print("File: {} could not be decoding with 'utf-8'".format(file)) + + +def check_file(file_path: Path, regex1, regex2): + if file_path.is_dir(): + for file in file_path.iterdir(): + if file.is_file(): + if not regex1.match(str(file)): + check_chinese(str(file), regex2) + elif file.is_dir(): + check_file(file, regex1, regex2) + elif file_path.is_file(): + if not regex1.match(str(file_path)): + check_chinese(file_path, regex2) + + +f1 = "/Users/devon/Desktop/project/" +pattern1 = '.*(\/\.|\.pyc).*' +regex1 = re.compile(pattern1) + +pattern2 = '[\u4e00-\u9fa5]+' # 中文字符 +regex2 = re.compile(pattern2) + +check_file(Path(f1), regex1, regex2) \ No newline at end of file diff --git a/exercise/file/directory.py b/exercise/file/directory.py new file mode 100644 index 0000000..4f396e2 --- /dev/null +++ b/exercise/file/directory.py @@ -0,0 +1,24 @@ +#!/usr/bin/env python3 +""" +遍历并判断文件类型,如果是目录是否可以判断其是否为空? +""" + +from pathlib import Path + + +file = '/tmp/test/1.txt' +p = Path(file) + +for x in p.parents[len(p.parents)-2].iterdir(): + print(x, end='\t') + + if x.is_dir(): + flag = False + for _ in x.iterdir(): + flag = True + break + print('dir', 'Not Empty' if flag else 'Empty', sep='\t') + elif x.is_file(): + print('file') + else: + print('other file') \ No newline at end of file diff --git a/exercise/file/file_csv.py b/exercise/file/file_csv.py new file mode 100644 index 0000000..866d8e1 --- /dev/null +++ b/exercise/file/file_csv.py @@ -0,0 +1,24 @@ +#!/usr/bin/env python3 + +from pathlib import Path +import csv + +file = '/tmp/test.csv' +p = Path(file) + + +with open(str(p)) as f: + reader = csv.reader(f) + print(next(reader)) + print(next(reader)) + +row = ['1', 'jim', '22', 'China'] +rows = [ + ('2', 'tom', '18', 'Japan'), + ('3', 'lisa', '20', 'Africa') +] + +with open(str(p), mode='a+') as f: + write = csv.writer(f) + write.writerow(row) + write.writerows(rows) \ No newline at end of file diff --git a/exercise/inspect.py b/exercise/inspect.py new file mode 100644 index 0000000..901be39 --- /dev/null +++ b/exercise/inspect.py @@ -0,0 +1,26 @@ +#!/usr/bin/env python3 +""" +函数签名 +""" + +from inspect import signature + + +def add1(x:int, y:int, *args, **kwargs) -> int : + return x + y + + +sig = signature(add1) +print('{}\n{}'.format('---'*10, sig)) +print('parameters: {}'.format(sig.parameters)) # OrderedDict +print('return: {}'.format(sig.return_annotation)) +print(sig.parameters['y']) +print(sig.parameters['x'].annotation) +print(sig.parameters['args']) +print(sig.parameters['args'].annotation) +print(sig.parameters['kwargs']) +print(sig.parameters['kwargs'].annotation) + + + + diff --git a/exercise/list-comp/ex_1.py b/exercise/list-comp/ex_1.py index 58c3f2c..6f151ea 100644 --- a/exercise/list-comp/ex_1.py +++ b/exercise/list-comp/ex_1.py @@ -9,7 +9,7 @@ # square(1,10) -nums = [i**2 for i in range(1,11)] +nums = [i**2 for i in range(1, 11)] print(nums) # new list diff --git a/exercise/tree/heap_sort1.py b/exercise/tree/heap_sort1.py index 84a1133..99f3600 100644 --- a/exercise/tree/heap_sort1.py +++ b/exercise/tree/heap_sort1.py @@ -33,27 +33,29 @@ def print_tree2(array): print() -origin = [0, 30, 50, 10, 70, 80, 20, 90, 40, 60] +# origin = [0, 30, 50, 10, 40, 80, 20, 90, 70, 60] +origin = [0, 40, 50, 70, 60, 90, 10, 30, 80, 20] + +length = len(origin) - 1 -total = len(origin) - 1 print(origin) print_tree2(origin) -def heap_adjust(n, i, array:list): +def heap_adjust(n, i, array: list): """ 调整当前结点(核心算法) - 调整的结点的起点在n//2,保证所有调整的结点都有孩子结点 + 调整的结点的起点在n//2,保证所有调整的结点都有孩子结点,该结点是父结点; :param n:待比较数个数 :param i:当前结点的下标 :param array:待排序数据 :return: """ - while 2*i < n: + while 2*i <= n: # 孩子结点判断,2i为左孩子,2i+1为右孩子 lchild_index = 2 * i - max_child_index = lchild_index # n = 2i - if n > lchild_index and array[lchild_index + 1] > array[lchild_index]: # n>2i说明还有右孩子 + max_child_index = lchild_index # n = 2i + if n > lchild_index and array[lchild_index + 1] > array[lchild_index]: # n>2i说明还有右孩子 max_child_index = lchild_index + 1 # 和子树的根结点比较 @@ -62,10 +64,16 @@ def heap_adjust(n, i, array:list): i = max_child_index # 被交换后,还需要判断是否需要调整 else: break - # print_tree2(array) # 到目前为止,只是解决了单个结点的调整(70, 40, 60),下面使用循环依次解决比起始结点编号小的结点; + # print('~'*20) + # print_tree2(array) + + +""" + 到目前为止,只是解决了单个结点的调整,下面使用循环依次解决比起始结点编号小的结点; +""" -heap_adjust(total, total//2, origin) +# heap_adjust(length, length//2, origin) # print(origin) # print_tree2(origin) @@ -76,14 +84,60 @@ def heap_adjust(n, i, array:list): 从最下层最右边叶子结点的父结点开始,由于构造了一个前置的0,所以编号和索引相等,但是元素个数等于长度-1; 下一个结点: 按照二叉树性质5编号的结点,从起点开始找编号逐个递减的结点,直至编号为1; + 大顶堆不稳定; """ -def max_heap(total, array:list): +def max_heap(total, array: list): for i in range(total//2, 0, -1): heap_adjust(total, i, array) + print_tree2(array) + return array + + +print('{}1{}'.format('-'*10, '-'*10)) +print_tree2(max_heap(length, origin)) + + +""" +排序: + 思路: + 1.在大顶堆的基础上,每次都要让堆顶的元素和最后一个元素结点交换,然后排除最后一个元素,形成一个新的被破坏的堆; + 因为列表origin被影子copy,元素顺序发生变化; + 2.让它重新调整,调整后,堆顶一定是最大元素; + 3.再次重复1,2步,直至剩余最后一个元素; +""" + + +def sort1(total, array: list): + while total > 1: + array[1], array[total] = array[total], array[1] + total -= 1 + + heap_adjust(total, 1, array) + print(array) return array -print_tree2(max_heap(total, origin)) +print('{}2{}'.format('-'*10, '-'*10)) +print_tree2(sort1(length, origin)) + + +""" +改进: + 如果只剩最后2个元素了,如果后一个结点比堆顶大,就不用调整了; +""" + + +def sort2(total, array: list): + while total > 1: + array[1], array[total] = array[total], array[1] + total -= 1 + if total == 2 and array[total] >= array[total - 1]: + break + heap_adjust(total, 1, array) + return array + +# print('{}3{}'.format('-'*10, '-'*10)) +# print_tree2(sort2(length, origin)) diff --git a/gitlab_api/group_info.py b/gitlab_api/group_info.py new file mode 100644 index 0000000..25ece60 --- /dev/null +++ b/gitlab_api/group_info.py @@ -0,0 +1,88 @@ +import gitlab + +gitlab_url = "http://127.0.0.1" +user = "root" +private_token = "WZ3x9_W3wAqpzrB5Z4xs" +gl = gitlab.Gitlab(gitlab_url, private_token, api_version='4') + +# gitlab.GUEST_ACCESS = 10 +# gitlab.REPORTER_ACCESS = 20 +# gitlab.DEVELOPER_ACCESS = 30 +# gitlab.MASTER_ACCESS = 40 +# gitlab.OWNER_ACCESS = 50 + +# 遍历组的成员信息 username是登陆账号 +# groups = gl.groups.list() +# for g in groups: +# print(g.attributes["name"], g.attributes["id"], g.attributes["web_url"]) + +# group = gl.groups.get(5) +# print(type(group)) +# projects = group.projects.list() +# print(type(projects) +# +# projects_info = [] +# for project in projects: +# # print(project, project.__dict__) +# projects_info.append(project.attributes["id"]) +# +# print(projects_info) +# +# members_username = [] +# members = group.members.list() +# for m in members: +# print(m.attributes["id"], m.attributes["username"]) + + +def grant_privileges(username: str, groupname: str, glu: gitlab.Gitlab): + def _get_groups(): + groups_info = {} + for g in gl.groups.list(): + groups_info[g.attributes["name"]] = g.get_id() + return groups_info + + def _get_members(group_id: int): + group = gl.groups.get(group_id) + members_info = {} + for m in group.members.list(): + members_info[m.attributes["username"]] = m.get_id() + return members_info + + # def _get_projects(group_id: int): + # group = gl.groups.get(group_id) + # projects_info = {} + # for p in group.projects.list(visibility='private'): + # projects_info[p.attributes["name"]] = p.get_id() + # return projects_info + + def _get_projects(): + projects_info = {} + for p in gl.projects.list(): + projects_info[p.attributes["namespace"]["name"]] = p.get_id() + return projects_info + + groups = _get_groups() + group_id = groups[groupname] + members_info = _get_members(group_id) + projects_info = _get_projects() + project_id = projects_info[groupname] + + # 判断用户是否属于这个组 + if username in members_info.keys(): + raise("Error, {} already exists in {}".format(username, groupname)) + + +# grant_privileges("devon123", "admin", gl) +# print(gl.projects.list()[0].attributes["namespace"]["name"]) +# for p in gl.projects.list(): +# print(p) + +project = gl.projects.get(5) +branch = project.branches.get("master") +branch.protect() +print(branch) + + + + + diff --git a/gitlab_api/set_branch.py b/gitlab_api/set_branch.py new file mode 100644 index 0000000..a48c623 --- /dev/null +++ b/gitlab_api/set_branch.py @@ -0,0 +1,62 @@ +import gitlab +import logging + +gitlab_url = "http://127.0.0.1" +user = "root" +private_token = "WZ3x9_W3wAqpzrB5Z4xs" +gl = gitlab.Gitlab(gitlab_url, private_token) + +log = logging.basicConfig(level=logging.INFO) +# def create_branch(project_id: int, branch_name, gl): +# project = gl.projects.get(project_id) +# +branch_name_master = "master-i18n" +branch_name_develop = "develop-i18n" +# project = gl.projects.get(5) +master_i18n_info = {'branch': branch_name_master, 'ref': 'master'} +develop_i18n_info = {'branch': branch_name_develop, 'ref': branch_name_master} + + +def set_protected_branch(project, branch_name): + try: + project.branches.get(branch_name) + except gitlab.exceptions.GitlabGetError: + logging.error("{} not exists!".format(branch_name)) + else: + try: + project.protectedbranches.get(branch_name) + except gitlab.exceptions.GitlabGetError: + logging.info("{} will be set protected".format(branch_name)) + project.protectedbranches.create({ + 'name': 'master-i18n', + 'merge_access_level': gitlab.MASTER_ACCESS, + 'push_access_level': gitlab.MASTER_ACCESS + }) + else: + logging.info("{} already is a protected branch".format(branch_name)) + + +def create_branch(project, branch_name_master, branch_name_develop): + try: + project.branches.get(branch_name_master) + except gitlab.exceptions.GitlabGetError: + # logging.error("Branch: {} not found".format(branch_name_master)) + logging.info("###Project: {} Branch: {} and {} will be created!".format(project.attributes["name"], branch_name_master, branch_name_develop)) + project.branches.create(master_i18n_info) + set_protected_branch(project, branch_name_master) + project.branches.create(develop_i18n_info) + else: + logging.info("----Project: {} already have branch: {}".format(project.attributes["name"], branch_name_master)) + set_protected_branch(project, branch_name_master) + try: + project.branches.get(branch_name_develop) + except gitlab.exceptions.GitlabGetError: + logging.info("###Project: {} Branch: {} will be created!".format(project.attributes["name"], branch_name_develop)) + project.branches.create(develop_i18n_info) + else: + logging.info("****Project: {} already have branches: {} and {}".format(project.attributes["name"], branch_name_master, branch_name_develop)) + + +project_name = "360/p361" +project = gl.projects.get(project_name) +create_branch(project, branch_name_master, branch_name_develop) diff --git a/gitlab_api/test.py b/gitlab_api/test.py new file mode 100644 index 0000000..cfa9d0d --- /dev/null +++ b/gitlab_api/test.py @@ -0,0 +1,23 @@ +import gitlab +import requests + + +gitlab_url = "http://127.0.0.1" +user = "root" +private_token = "WZ3x9_W3wAqpzrB5Z4xs" +gl = gitlab.Gitlab(gitlab_url, private_token, api_version='4') + +# print(len(gl.projects.list(all=True))) +# +project_name = "360/p361" +# p = gl.projects.get(project_name) +# print(p) +# print(p.protectedbranches.list()) +# print(p.protectedbranches.get('master')) + +payload = {'private_token': private_token} +uri = '/api/v3/projects/5/repository/branches/master' +url = gitlab_url + uri +r = requests.get(url, params=payload) +print(r.text) + diff --git a/jumpserver/assets.py b/jumpserver/assets.py index 8096b67..04064a9 100644 --- a/jumpserver/assets.py +++ b/jumpserver/assets.py @@ -6,10 +6,10 @@ import uuid -assets_file = "/Users/devon/Downloads/assets.csv" -hosts_file = "/Users/devon/Downloads/hosts.txt" - +assets_file = "/Users/devon/Desktop/test/assets.csv" +hosts_file = "/Users/devon/Desktop/test/ip.txt" +""" def gen_record(host_id, ip, host_name, port=22): cluster = "Default" active = "True" @@ -24,16 +24,25 @@ def gen_record(host_id, ip, host_name, port=22): property_part2 = ','*22 row = property_part1 + property_part2 + assets_group return row +""" + + +def gen_record(host_id, host_name, address, public_ip, port=22, active_status='True', user='root', code_num='none'): + property_list = [host_id, host_name, address, port, active_status, user, public_ip, code_num] + part1 = ','.join(str(i) for i in property_list) + row = part1 + ',' * 10 + 'Linux' + ',' * 6 + 'WJ_vhost' + return row record_list = [] with open(hosts_file) as hosts_list: hosts = hosts_list.read().split('\n') for host in hosts: - ip = host - hostname = ip + hostname = host.strip(' ') + ip = host.strip(' ') + publicIp = host.strip(' ') hostId = uuid.uuid4() - record_list.append(gen_record(hostId, ip, hostname)) + record_list.append(gen_record(hostId, hostname, ip, publicIp)) print(record_list) diff --git a/spiderdemo/scrapy.cfg b/spiderdemo/scrapy.cfg new file mode 100644 index 0000000..61c9b4f --- /dev/null +++ b/spiderdemo/scrapy.cfg @@ -0,0 +1,11 @@ +# Automatically created by: scrapy startproject +# +# For more information about the [deploy] section see: +# https://scrapyd.readthedocs.io/en/latest/deploy.html + +[settings] +default = spiderdemo.settings + +[deploy] +#url = http://localhost:6800/ +project = spiderdemo diff --git a/spiderdemo/spiderdemo/__init__.py b/spiderdemo/spiderdemo/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/spiderdemo/spiderdemo/__pycache__/__init__.cpython-36.pyc b/spiderdemo/spiderdemo/__pycache__/__init__.cpython-36.pyc new file mode 100644 index 0000000000000000000000000000000000000000..4773431e8eef0076957391e09c64aa0abdbab895 GIT binary patch literal 153 zcmXr!<>k7P_A{CR2p)q77+?f49Dul(1xTbY1T$zd`mJOr0tq9CUvB!L#i>Qb`YEYp z`FZ*-sm0kP`33p~Mfq8&$tC&)l_eSZdB*z11(_+SMJcJd`N+)p_{_Y_lK6PNg34PQ SHo5sJr8%i~AoGiXm;nGcStv6A literal 0 HcmV?d00001 diff --git a/spiderdemo/spiderdemo/__pycache__/settings.cpython-36.pyc b/spiderdemo/spiderdemo/__pycache__/settings.cpython-36.pyc new file mode 100644 index 0000000000000000000000000000000000000000..26467c7c97c3517de7d9066326af71e69a0f42f0 GIT binary patch literal 267 zcmXr!<>gv7=~uK44+Fzv1|+};WIF(Hu^5m@VTfW#VN7R?VoYI-VoG6(VoqTWX3%7b z;wmo4Oi3+DNzKi#5<;-`Ak5+rKTVcf98Ufr@qUiJuDAGt13X<^gW`StT|#|agKr7= zxrU<%-Qo-K2dWMZi3o}JcXEwf$xy@!v>r_Sa?=kjPAw|dPf0Dy&(n8FEzT~m1B E0JFzTSpWb4 literal 0 HcmV?d00001 diff --git a/spiderdemo/spiderdemo/items.py b/spiderdemo/spiderdemo/items.py new file mode 100644 index 0000000..94853fc --- /dev/null +++ b/spiderdemo/spiderdemo/items.py @@ -0,0 +1,14 @@ +# -*- coding: utf-8 -*- + +# Define here the models for your scraped items +# +# See documentation in: +# https://doc.scrapy.org/en/latest/topics/items.html + +import scrapy + + +class SpiderdemoItem(scrapy.Item): + # define the fields for your item here like: + # name = scrapy.Field() + pass diff --git a/spiderdemo/spiderdemo/middlewares.py b/spiderdemo/spiderdemo/middlewares.py new file mode 100644 index 0000000..71d5650 --- /dev/null +++ b/spiderdemo/spiderdemo/middlewares.py @@ -0,0 +1,103 @@ +# -*- coding: utf-8 -*- + +# Define here the models for your spider middleware +# +# See documentation in: +# https://doc.scrapy.org/en/latest/topics/spider-middleware.html + +from scrapy import signals + + +class SpiderdemoSpiderMiddleware(object): + # Not all methods need to be defined. If a method is not defined, + # scrapy acts as if the spider middleware does not modify the + # passed objects. + + @classmethod + def from_crawler(cls, crawler): + # This method is used by Scrapy to create your spiders. + s = cls() + crawler.signals.connect(s.spider_opened, signal=signals.spider_opened) + return s + + def process_spider_input(self, response, spider): + # Called for each response that goes through the spider + # middleware and into the spider. + + # Should return None or raise an exception. + return None + + def process_spider_output(self, response, result, spider): + # Called with the results returned from the Spider, after + # it has processed the response. + + # Must return an iterable of Request, dict or Item objects. + for i in result: + yield i + + def process_spider_exception(self, response, exception, spider): + # Called when a spider or process_spider_input() method + # (from other spider middleware) raises an exception. + + # Should return either None or an iterable of Response, dict + # or Item objects. + pass + + def process_start_requests(self, start_requests, spider): + # Called with the start requests of the spider, and works + # similarly to the process_spider_output() method, except + # that it doesn’t have a response associated. + + # Must return only requests (not items). + for r in start_requests: + yield r + + def spider_opened(self, spider): + spider.logger.info('Spider opened: %s' % spider.name) + + +class SpiderdemoDownloaderMiddleware(object): + # Not all methods need to be defined. If a method is not defined, + # scrapy acts as if the downloader middleware does not modify the + # passed objects. + + @classmethod + def from_crawler(cls, crawler): + # This method is used by Scrapy to create your spiders. + s = cls() + crawler.signals.connect(s.spider_opened, signal=signals.spider_opened) + return s + + def process_request(self, request, spider): + # Called for each request that goes through the downloader + # middleware. + + # Must either: + # - return None: continue processing this request + # - or return a Response object + # - or return a Request object + # - or raise IgnoreRequest: process_exception() methods of + # installed downloader middleware will be called + return None + + def process_response(self, request, response, spider): + # Called with the response returned from the downloader. + + # Must either; + # - return a Response object + # - return a Request object + # - or raise IgnoreRequest + return response + + def process_exception(self, request, exception, spider): + # Called when a download handler or a process_request() + # (from other downloader middleware) raises an exception. + + # Must either: + # - return None: continue processing this exception + # - return a Response object: stops process_exception() chain + # - return a Request object: stops process_exception() chain + pass + + def spider_opened(self, spider): + spider.logger.info('Spider opened: %s' % spider.name) diff --git a/spiderdemo/spiderdemo/pipelines.py b/spiderdemo/spiderdemo/pipelines.py new file mode 100644 index 0000000..3bcab47 --- /dev/null +++ b/spiderdemo/spiderdemo/pipelines.py @@ -0,0 +1,11 @@ +# -*- coding: utf-8 -*- + +# Define your item pipelines here +# +# Don't forget to add your pipeline to the ITEM_PIPELINES setting +# See: https://doc.scrapy.org/en/latest/topics/item-pipeline.html + + +class SpiderdemoPipeline(object): + def process_item(self, item, spider): + return item diff --git a/spiderdemo/spiderdemo/settings.py b/spiderdemo/spiderdemo/settings.py new file mode 100644 index 0000000..6e6eff0 --- /dev/null +++ b/spiderdemo/spiderdemo/settings.py @@ -0,0 +1,90 @@ +# -*- coding: utf-8 -*- + +# Scrapy settings for spiderdemo project +# +# For simplicity, this file contains only settings considered important or +# commonly used. You can find more settings consulting the documentation: +# +# https://doc.scrapy.org/en/latest/topics/settings.html +# https://doc.scrapy.org/en/latest/topics/downloader-middleware.html +# https://doc.scrapy.org/en/latest/topics/spider-middleware.html + +BOT_NAME = 'spiderdemo' + +SPIDER_MODULES = ['spiderdemo.spiders'] +NEWSPIDER_MODULE = 'spiderdemo.spiders' + + +# Crawl responsibly by identifying yourself (and your website) on the user-agent +#USER_AGENT = 'spiderdemo (+http://www.yourdomain.com)' + +# Obey robots.txt rules +ROBOTSTXT_OBEY = True + +# Configure maximum concurrent requests performed by Scrapy (default: 16) +#CONCURRENT_REQUESTS = 32 + +# Configure a delay for requests for the same website (default: 0) +# See https://doc.scrapy.org/en/latest/topics/settings.html#download-delay +# See also autothrottle settings and docs +#DOWNLOAD_DELAY = 3 +# The download delay setting will honor only one of: +#CONCURRENT_REQUESTS_PER_DOMAIN = 16 +#CONCURRENT_REQUESTS_PER_IP = 16 + +# Disable cookies (enabled by default) +#COOKIES_ENABLED = False + +# Disable Telnet Console (enabled by default) +#TELNETCONSOLE_ENABLED = False + +# Override the default request headers: +#DEFAULT_REQUEST_HEADERS = { +# 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8', +# 'Accept-Language': 'en', +#} + +# Enable or disable spider middlewares +# See https://doc.scrapy.org/en/latest/topics/spider-middleware.html +#SPIDER_MIDDLEWARES = { +# 'spiderdemo.middlewares.SpiderdemoSpiderMiddleware': 543, +#} + +# Enable or disable downloader middlewares +# See https://doc.scrapy.org/en/latest/topics/downloader-middleware.html +#DOWNLOADER_MIDDLEWARES = { +# 'spiderdemo.middlewares.SpiderdemoDownloaderMiddleware': 543, +#} + +# Enable or disable extensions +# See https://doc.scrapy.org/en/latest/topics/extensions.html +#EXTENSIONS = { +# 'scrapy.extensions.telnet.TelnetConsole': None, +#} + +# Configure item pipelines +# See https://doc.scrapy.org/en/latest/topics/item-pipeline.html +#ITEM_PIPELINES = { +# 'spiderdemo.pipelines.SpiderdemoPipeline': 300, +#} + +# Enable and configure the AutoThrottle extension (disabled by default) +# See https://doc.scrapy.org/en/latest/topics/autothrottle.html +#AUTOTHROTTLE_ENABLED = True +# The initial download delay +#AUTOTHROTTLE_START_DELAY = 5 +# The maximum download delay to be set in case of high latencies +#AUTOTHROTTLE_MAX_DELAY = 60 +# The average number of requests Scrapy should be sending in parallel to +# each remote server +#AUTOTHROTTLE_TARGET_CONCURRENCY = 1.0 +# Enable showing throttling stats for every response received: +#AUTOTHROTTLE_DEBUG = False + +# Enable and configure HTTP caching (disabled by default) +# See https://doc.scrapy.org/en/latest/topics/downloader-middleware.html#httpcache-middleware-settings +#HTTPCACHE_ENABLED = True +#HTTPCACHE_EXPIRATION_SECS = 0 +#HTTPCACHE_DIR = 'httpcache' +#HTTPCACHE_IGNORE_HTTP_CODES = [] +#HTTPCACHE_STORAGE = 'scrapy.extensions.httpcache.FilesystemCacheStorage' diff --git a/spiderdemo/spiderdemo/spiders/__init__.py b/spiderdemo/spiderdemo/spiders/__init__.py new file mode 100644 index 0000000..ebd689a --- /dev/null +++ b/spiderdemo/spiderdemo/spiders/__init__.py @@ -0,0 +1,4 @@ +# This package will contain the spiders of your Scrapy project +# +# Please refer to the documentation for information on how to create and manage +# your spiders. diff --git a/spiderdemo/spiderdemo/spiders/__pycache__/__init__.cpython-36.pyc b/spiderdemo/spiderdemo/spiders/__pycache__/__init__.cpython-36.pyc new file mode 100644 index 0000000000000000000000000000000000000000..de757661e6af3f8ab7290edf50dfe8ba32443e0f GIT binary patch literal 161 zcmXr!<>k7P_A`1R0|UcjAcg}*Aj<)Wi&=m~3PUi1CZpd~vm6}|lUrY&&W_zh#86E@ z=(Hu)*Tumm>E^Or9FOZ-oiVmoW4U|Hg*z$Y5@DPLAh?+hK1j#2ff2>X##$I9D<;gSfq0e`yAtNHmWnAYry{SJn%84l^_Xd7fhgtw)a>-AxeZmOjYyn^Mi^Zj z|8drB`U7+vb6#bo;M^vhml9@$%MUq!nq|eN6S&hJWkn%h1aOdLHmQtFOr7bP&vapQ zYwP6Kla5@?Js&z9F;Ywe8qvsWsvX}(Cf6Ctjn@C&l=l`i-{ZE}_ Response: + return self.ROUTETABLE.get(request.path, self.notfound)(request) + + +def index(request: Request): + res = Response() + res.body = "

homepage

".encode() + return res + + +def showpython(request: Request): + res = Response() + res.body = "

Python

".encode() + return res + + +# 注册 +Application.register('/', index) +Application.register('/python', showpython) + +if __name__ == '__main__': + ip = '127.0.0.1' + port = 9000 + server = make_server(ip, port, Application()) + try: + server.serve_forever() + except KeyboardInterrupt: + pass + finally: + server.server_close() + diff --git a/week/logging/ex1.py b/week/logging/ex1.py new file mode 100644 index 0000000..8a89129 --- /dev/null +++ b/week/logging/ex1.py @@ -0,0 +1,43 @@ +import logging + + +FORMAT = "%(asctime)s %(thread)d %(message)s " +logging.basicConfig(format=FORMAT, datefmt="%Y-%m-%d %H:%M:%S", level=logging.INFO) +# logging.basicConfig 实际上是创建root log格式; default log level: WARNING + +root = logging.getLogger() +print(root, id(root)) + +log1 = logging.getLogger('s') +# log1 = logging.getLogger(__name__) # 保证不同名;不同模块,如果同名,实例对象就是同一个 +log1.setLevel(logging.INFO) +print(log1.getEffectiveLevel()) + +handler1 = logging.FileHandler('./log_error.log') +handler1.setLevel(logging.ERROR) +fmtr = logging.Formatter('%(levelname)s %(asctime)s %(thread)d %(threadName)s %(message)s') +handler1.setFormatter(fmtr) +log1.addHandler(handler1) + +log2 = logging.getLogger('s.s1') +log2.setLevel(30) +print(log2.getEffectiveLevel()) + +handler2 = logging.FileHandler('./log_warning.log') +handler2.setLevel(logging.WARNING) +log2.addHandler(handler2) + +log3 = logging.getLogger('s.s1.s11') +log3.setLevel(10) +print(log3.getEffectiveLevel()) + +handler3 = logging.FileHandler('./log_info.log') +handler3.setLevel(logging.INFO) +log3.addHandler(handler3) + +log3.info('log3 info') +log2.warning('log2 warning') +log1.error('log1 error') + + + diff --git a/week/month1.py b/week/month1.py new file mode 100644 index 0000000..92a4d7c --- /dev/null +++ b/week/month1.py @@ -0,0 +1,14 @@ +#!/usr/bin/env python3 + +# ex1 +import random +origin_nums = {5, 10, 3, 8, 6, 10, 9, 15, 24, 30, 27, 48, 24} +new_nums = [] +count = 0 + +while count < 10: + num = random.choice(list(origin_nums)) + if num % 3 == 0 and num % 4 != 0: + new_nums.append(num) + count += 1 +print(new_nums) \ No newline at end of file diff --git a/week/threading/cups.py b/week/threading/cups.py new file mode 100644 index 0000000..7d574b4 --- /dev/null +++ b/week/threading/cups.py @@ -0,0 +1,35 @@ +"""老板雇佣一个工人,让他生产杯子,老板一直等着工人,直到工人生产10个杯子""" +from threading import Thread, Event +import logging +import time + + +FORMAT = '%(asctime)s %(threadName)s %(thread)d %(message)s' +logging.basicConfig(level=logging.INFO, datefmt=FORMAT) + + +def boss(event: Event): + # logging.info('I am boss, waiting for U') + event.wait() + logging.info('Good Job.') + + +def worker(event: Event, count=10): + logging.info("I am working for U") + cups = [] + while True: + logging.info('make 1') + time.sleep(0.5) + cups.append(1) + if len(cups) >= count: + event.set() + break + logging.info("I finished my job, cups={}".format(len(cups))) + + +event = Event() +w = Thread(target=worker, args=(event,)) +b = Thread(target=boss, args=(event,)) + +w.start() +b.start() \ No newline at end of file diff --git a/week/threading/ex3.py b/week/threading/ex3.py index d7a6be2..621f205 100644 --- a/week/threading/ex3.py +++ b/week/threading/ex3.py @@ -1,16 +1,42 @@ import logging import threading -FORMAT = "%(asctime)s %(thread)d %(message)s %(test)s" +# FORMAT = "%(asctime)s %(thread)d %(message)s %(test)s" # 添加扩展字符串key +FORMAT = "%(asctime)s %(thread)d %(message)s " logging.basicConfig(level=logging.INFO, format=FORMAT, datefmt="%Y-%m-%d-%H:%M:%S") d = {'test': 'hello world'} +help(logging.basicConfig) -def fadd(x, y): - logging.warning("{} {}".format(threading.enumerate(), x + y)) - logging.info("%s %s", x, y, extra=d) - logging.info("{} {}".format(threading.enumerate(), x + y), extra=d) # 日志级别和格式字符串扩展, dict +# def fadd(x, y): +# logging.warning("{} {}".format(threading.enumerate(), x + y)) +# logging.info("%s %s", x, y, extra=d) +# logging.info("{} {}".format(threading.enumerate(), x + y), extra=d) # 日志级别和格式字符串扩展, dict -t = threading.Timer(1, fadd, args=[4, 5]) -t.start() +# t = threading.Timer(1, fadd, args=[4, 5]) +# t.start() + +# log = logging.getLogger('') +# print(log.name) +# print(log, type(log)) + +def testadd(x, y): + log = logging.getLogger('a') + print(log.name) + print(log, type(log), log.parent) + + logging.warning("{} {}".format(threading.enumerate(), x+y)) + + +# t = threading.Timer(1, testadd, args=[1, 2]) +# t.start() + +root = logging.getLogger() +print(root, id(root)) + +loga = logging.getLogger('a') +print(loga, id(loga), id(loga.parent)) + +logb = logging.getLogger('a.b') +print(logb, id(logb), id(logb.parent)) \ No newline at end of file diff --git a/week/threading/newcups.py b/week/threading/newcups.py new file mode 100644 index 0000000..6fa1ad1 --- /dev/null +++ b/week/threading/newcups.py @@ -0,0 +1,28 @@ +"""10个人生产100个杯子""" +import threading +import logging + +logging.basicConfig(level=logging.INFO) + +cups = [] +locker = threading.Lock() + + +def worker(lock: threading.Lock, task=100): + while True: + lock.acquire() + count = len(cups) + # lock.release() + logging.info(count) + if count >= task: + lock.release() + break # no release lock + # lock.acquire() + cups.append(1) + lock.release() + logging.info("{} make 1".format(threading.current_thread().name)) + logging.info("result: {}".format(len(cups))) + + +for x in range(10): + threading.Thread(target=worker, args=(locker, 100)).start() diff --git a/week/threading/timer.py b/week/threading/timer.py new file mode 100644 index 0000000..e73efb4 --- /dev/null +++ b/week/threading/timer.py @@ -0,0 +1,47 @@ +""" +实现Timer,延时执行的线程 +延时计算add(x,y) +""" +from threading import Thread, Event +import datetime +import logging +logging.basicConfig(level=logging.INFO) + + +def nadd(x: int, y: int): + logging.info(x + y) + + +class Timer: + def __init__(self, interval, fn, *args, **kwargs): + self.interval = interval + self.fn = fn + self.args = args + self.kwargs = kwargs + self.event = Event() + + def start(self): + Thread(target=self.__run).start() + + def cancel(self): + """set event为 True""" + self.event.set() + logging.info('cancel') + + def __run(self): + start = datetime.datetime.now() + logging.info('waiting') + + self.event.wait(self.interval) + """当event标记不为True时,执行函数""" + if not self.event.is_set(): + self.fn(*self.args, **self.kwargs) + delta = (datetime.datetime.now() - start).total_seconds() + logging.info('finished {}'.format(delta)) + + +t = Timer(10, nadd, 4, 50) +t.start() +e = Event() +e.wait(4) # 由于未设置event标记状态,所以等待4s后返回event标记为False +# t.cancel() diff --git a/week/threading/wait.py b/week/threading/wait.py new file mode 100644 index 0000000..5497ca7 --- /dev/null +++ b/week/threading/wait.py @@ -0,0 +1,16 @@ +from threading import Thread, Event +import logging +logging.basicConfig(level=logging.INFO) + + +def do(event: Event, interval: int): + while not event.wait(interval): + logging.info('do something.') + + +e = Event() +Thread(target=do, args=(e, 3)).start() + +e.wait(30) +e.set() +print('main process exit') \ No newline at end of file diff --git a/week/week2/ex1.py b/week/week2/ex1.py new file mode 100644 index 0000000..0c11e99 --- /dev/null +++ b/week/week2/ex1.py @@ -0,0 +1,9 @@ +#!/usr/bin/env python3 +""" +在用户管理功能中添加密码信息: + 增、改添加用户密码输入 + 显示时将用户密码显示为N(密码长度)个* + 用户验证修改为用户名和密码 + 输入list后提示用户排序字段(name, age, tel),根据用户输入字段进行排序(升序)后将结果输入 + +""" diff --git "a/week/\345\274\202\345\270\270/ex1.py" "b/week/\345\274\202\345\270\270/ex1.py" new file mode 100644 index 0000000..458ac1f --- /dev/null +++ "b/week/\345\274\202\345\270\270/ex1.py" @@ -0,0 +1,24 @@ +#!/usr/bin/env python3 + + +# f = None #可以事先定义变量f为None + +try: + f = open('test1') +# except MyException as e: +# print(e) +# except OSError as e: +# print('InterruptedError') +except Exception as e: + print(e, type(e)) +finally: # finally语句是最后执行的语句,不管前面是否出现异常; + print("clean work") + try: + f.close() # 第9行如果文件不存在错误,会导致f变量没有定义,因此需要在finally语句在执行清理操作的时候注意变量f; + except NameError: + print('NameError: f') + +print(dir()) # 查看当前环境或模块中所有的变量 +print('outer') + + diff --git "a/week/\345\274\202\345\270\270/ex2.py" "b/week/\345\274\202\345\270\270/ex2.py" new file mode 100644 index 0000000..5041e21 --- /dev/null +++ "b/week/\345\274\202\345\270\270/ex2.py" @@ -0,0 +1,29 @@ +#!/use/bin/env python3 +import time + + +def foo1(): + try: # 一般来说try最多不超过3层 + 1/0 + finally: + print('fool1 fin') + # return # finally不建议使用return,否则异常会被吞并; + + +def foo2(): + time.sleep(3) + foo1() + + while True: + print('--'*10) + time.sleep(1) + + +try: + foo2() +except Exception as e: + print('outer', e) +finally: + print('outer fin') # 内层异常如果没有处理就会继续向外抛出,直到主线程退出; + + diff --git "a/week/\345\274\202\345\270\270/ex3.py" "b/week/\345\274\202\345\270\270/ex3.py" new file mode 100644 index 0000000..b40b88b --- /dev/null +++ "b/week/\345\274\202\345\270\270/ex3.py" @@ -0,0 +1,20 @@ +#!/usr/bin/env python3 + +try: + 1/0 +except ArithmeticError: + print('ArithmeticError') +except: + print('except') +else: # 异常没有发生时执行的语句 + print('else') +finally: + print('fin') + + +# try的工作原理: +# 1、如果try中语句执行时发生异常,搜索except子句,并执行第一个匹配该异常的except子句; +# 2、如果try中语句执行时发生异常,却没有匹配的except子句,异常将被递交到外层的try,如果外层不处理这个异常,异常将继续向外层传递; +# 如果都不处理该异常,则会传递到最外层,如果还没有处理,就终止异常所在的线程; +# 3、如果在try执行时没有发生异常,将会执行else子句中的语句; +# 4、无论try中是否发生异常,finally子句最终都会执行; diff --git "a/week/\346\217\217\350\277\260\345\231\250/StaticMethod.py" "b/week/\346\217\217\350\277\260\345\231\250/StaticMethod.py" new file mode 100644 index 0000000..f2bd98a --- /dev/null +++ "b/week/\346\217\217\350\277\260\345\231\250/StaticMethod.py" @@ -0,0 +1,43 @@ +#!/usr/bin/env python3 +from functools import partial + + +class StaticMethod: + def __init__(self, fn): + # print(fn) + self.fn = fn + + def __get__(self, instance, owner): + print(self, instance, owner) + return self.fn + + +class ClassMethod: + def __init__(self, fn): + # print(fn) + self.fn = fn + + def __get__(self, instance, cls): + print(self, instance, cls) + # return self.fn(owner) + return partial(self.fn, cls) + + +class A: + + @StaticMethod + def foo(): + print('static') + + @ClassMethod + def bar(cls): + print(cls.__name__) + + +# f = A.foo +# print(f) +# f() + +f = A.bar +print(f) +f() \ No newline at end of file diff --git "a/week/\346\217\217\350\277\260\345\231\250/ex1-2.py" "b/week/\346\217\217\350\277\260\345\231\250/ex1-2.py" new file mode 100644 index 0000000..1e7548f --- /dev/null +++ "b/week/\346\217\217\350\277\260\345\231\250/ex1-2.py" @@ -0,0 +1,50 @@ +#!/usr/bin/env python3 +""" +对实例的数据进行校验 +""" +import inspect + + +class Typed: + def __init__(self, ttype): + self.ttype = ttype + + def __get__(self, instance, owner): + pass + + def __set__(self, instance, value): + print('T_set', self, instance, value) + if not isinstance(value, self.ttype): + raise ValueError(value) + + +class TypeAssert: + def __init__(self, cls): + self.cls = cls + params = inspect.signature(self.cls).parameters + print(params) + for name, param in params.items(): + print(name, param.annotation) + if param.annotation != param.empty: + setattr(self.cls, name, Typed(param.annotation)) + print(self.cls.__dict__) + + def __call__(self, name, age): + p = self.cls(name, age) + return p + + +@TypeAssert +class Person: + # name = Typed(str) + # age = Typed(int) + + def __init__(self, name: str, age: int): + self.name = name + self.age = age + + +# p1 = Person('tom', 18) +p2 = Person('tom', '18') + + diff --git "a/week/\346\217\217\350\277\260\345\231\250/ex1.py" "b/week/\346\217\217\350\277\260\345\231\250/ex1.py" new file mode 100644 index 0000000..dcce688 --- /dev/null +++ "b/week/\346\217\217\350\277\260\345\231\250/ex1.py" @@ -0,0 +1,31 @@ +#!/usr/bin/env python3 +""" +对实例的数据进行校验 +""" + + +class Typed: + def __init__(self, ttype): + self.ttype = ttype + + def __get__(self, instance, owner): + pass + + def __set__(self, instance, value): + print('T_set', self, instance, value) + if not isinstance(value, self.ttype): + raise ValueError(value) + + +class Person: + name = Typed(str) + age = Typed(int) + + def __init__(self, name: str, age: int): + self.name = name + self.age = age + + +# p1 = Person('tom', '18') + + From e7fbe3bb2406815af85c23b6c04cb5dd776f0784 Mon Sep 17 00:00:00 2001 From: devon6686 Date: Sun, 3 Mar 2019 22:08:32 +0800 Subject: [PATCH 09/11] gitlab 11.8.0 api --- gitlab_api/git.py | 368 +++++++++++++++++++++++ gitlab_api/gitlab.cfg | 9 + gitlab_api/group_info.py | 88 ------ gitlab_api/set_branch.py | 62 ---- gitlab_api/test.py | 23 -- mysite/polls/templates/polls/detail.html | 10 + mysite/polls/templates/polls/index.html | 10 + mysite/polls/urls.py | 0 mysql/mysql-crud.py | 79 +++++ web/web2.py | 0 10 files changed, 476 insertions(+), 173 deletions(-) create mode 100644 gitlab_api/git.py create mode 100644 gitlab_api/gitlab.cfg delete mode 100644 gitlab_api/group_info.py delete mode 100644 gitlab_api/set_branch.py delete mode 100644 gitlab_api/test.py create mode 100644 mysite/polls/templates/polls/detail.html create mode 100644 mysite/polls/templates/polls/index.html create mode 100644 mysite/polls/urls.py create mode 100644 mysql/mysql-crud.py create mode 100644 web/web2.py diff --git a/gitlab_api/git.py b/gitlab_api/git.py new file mode 100644 index 0000000..2f2bfc2 --- /dev/null +++ b/gitlab_api/git.py @@ -0,0 +1,368 @@ +import gitlab +import logging +import time + + +FORMAT = '%(levelname)s %(asctime)s %(message)s' +logging.basicConfig(level=logging.INFO) +log = logging.getLogger('gitlab') +handler = logging.FileHandler('./git.log') +fmt = logging.Formatter('%(levelname)s %(asctime)s %(message)s') +handler.setFormatter(fmt) +log.addHandler(handler) + + +gl = gitlab.Gitlab.from_config('local', ['./gitlab.cfg']) +privileges = {'20': gitlab.REPORTER_ACCESS, '30': gitlab.DEVELOPER_ACCESS} + +# manipulate group + + +def get_groups(): + groups = gl.groups.list(all=True, as_list=False) + if groups: + groups_info = {} + for group in groups: + groups_info[group.attributes['name']] = group.get_id() + return groups_info + else: + log.error("no group find in gitlab!") + return False + + +def create_group(name, path, **kwargs): + group_info = {'name': name, 'path': path} + if kwargs: + group_info.update(kwargs) + try: + group = gl.groups.create(group_info) + except gitlab.exceptions.GitlabError as e: + log.error('failed to create group:{}!'.format(name)) + log.error(e) + return False + else: + log.info('succeed to create group:{}!'.format(name)) + return group + + +def delete_group_from_name(name): + name = str(name) + groups_info = get_groups() + if name in groups_info.keys(): + try: + gl.groups.delete(groups_info[name]) + except gitlab.exceptions.GitlabError as e: + log.error('failed to delete group:{}!'.format(name)) + log.error(e) + return False + else: + log.info('succeed to delete group:{}'.format(name)) + return True + else: + log.info('group:{} not exists in gitlab!'.format(name)) + return True + + +def get_group_id_from_name(name): + try: + group = gl.groups.get(name) + except gitlab.exceptions.GitlabError as e: + log.error("group:{} not find!".format(name)) + log.error(e) + return False + else: + group_id = group.get_id() + return group_id + + +# manipulate user +def get_users(): + users = gl.users.list(all=True, as_list=False) + if users: + users_info = {} + for user in users: + users_info[user.attributes['username']] = user.get_id() + return users_info + else: + log.error("No user find in gitlab!") + return False + + +def get_user_id_from_username(username): + users = get_users() + if str(username) in users.keys(): + return users[str(username)] + else: + log.error("user:{} not exists!".format(str(username))) + return False + + +def create_user(username, name, email, **kwargs): + # username is login name + user_info = {'username': username, 'name': name, 'email': email} + if kwargs: + user_info.update(kwargs) + try: + user = gl.users.create(user_info) + except gitlab.exceptions.GitlabError as e: + log.error('failed to create user:{} !'.format(username)) + log.error(e) + return False + else: + log.info('succeed to create user:{} !'.format(username)) + return user + + +def delete_user(username): + users = get_users() + if str(username) in users.keys(): + try: + gl.users.delete(users[str(username)]) + except gitlab.exceptions.GitlabError as e: + log.error("failed to delete user:{} !".format(str(username))) + log.error(e) + return False + else: + log.info("succeed to delete user:{} !".format(str(username))) + return True + else: + log.info("user:{} not exists!".format(username)) + return True + + +# manipulate project +def get_projects(): + try: + projects = gl.projects.list(all=True, as_list=False, order_by='name') + except gitlab.exceptions.GitlabError as e: + log.error(e) + return False + else: + if projects: + projects_info = {} + for project in projects: + projects_info[project.attributes['name']] = (project.get_id(), project.attributes['path']) + return projects_info + else: + log.error("not find any project in gitlab") + return False + + +def create_project_with_import(project_name, group_name): + template_file = './scm_repo-template-3_export.tar.gz' + group_id = get_group_id_from_name(group_name) + try: + output = gl.projects.import_project(open(template_file, 'rb'), path=project_name, namespace=group_id) + except gitlab.exceptions.GitlabError as e: + log.error(e) + return False + else: + project_import = gl.projects.get(output['id'], lazy=True).imports.get() + while project_import.import_status != 'finished': + time.sleep(1) + project_import.refresh() + log.info("succeed to import project:{} to group:{}".format(project_name, group_name)) + return True + + +def create_project_in_group(name, group_msg, **kwargs): + if type(group_msg) == int: + namespace_id = group_msg + elif type(group_msg) == str: + namespace_id = get_group_id_from_name(group_msg) + else: + log.critical("second parameter type error!") + return False + + project_info = {'name': str(name), 'namespace_id': namespace_id} + if kwargs: + project_info.update(kwargs) + try: + project = gl.projects.create(project_info) + except gitlab.exceptions.GitlabError as e: + log.error("failed to create project:{}".format(name)) + log.error(e) + return False + else: + log.info('succeed to create project:{} in group:{}'.format(str(name), str(group_msg))) + return project + + +def get_project_members(project_msg): + if type(project_msg) == str: + project_id = get_project_id_from_name(project_msg) + elif type(project_msg) == int: + project_id = project_msg + else: + log.critical('parameter type error!') + return False + + try: + project = gl.projects.get(project_id) + members = project.members.all(all=True) + except gitlab.exceptions.GitlabError as e: + log.critical(e) + return False + else: + members_info = {} + if members: + for member in members: + members_info[member.attributes['username']] = member.get_id() + return members_info + + +def get_project_id_from_name(project_name): + projects = get_projects() + if str(project_name) in projects.keys(): + project_id = projects[str(project_name)][0] + return project_id + else: + return False + + +def judge_project_member(username, project_name): + project_id = get_project_id_from_name(project_name) + user_id = get_user_id_from_username(username) + try: + project = gl.projects.get(project_id) + project.members.get(user_id) + except gitlab.exceptions.GitlabError as e: + log.critical(e) + return False + else: + log.info("user:{} exists in project:{}!".format(username, project_name)) + return True + + +def manipulate_project_user(operate, username, project_name, **kwargs): + user_id = get_user_id_from_username(username) + project_id = get_project_id_from_name(project_name) + project = gl.projects.get(project_id) + + try: + if operate == 'add': + privilege = privileges[str(kwargs['access_level'])] + user_info = {'user_id': user_id, 'access_level': privilege} + project.members.create(user_info) + elif operate == 'edit': + privilege = privileges[str(kwargs['access_level'])] + member = project.members.get(user_id) + member.access_level = privilege + member.save() + elif operate == 'remove': + project.members.delete(user_id) + else: + return False + except gitlab.exceptions.GitlabError as e: + log.critical(e) + return False + else: + log.info("succeed to {} user:{} in project:{}".format(operate, username, project_name)) + return True + + +def add_project_user(username, project_name, access_level=20): + result = manipulate_project_user('add', username, project_name, access_level=access_level) + return result + + +def edit_project_user(username, project_name, access_level=20): + result = manipulate_project_user('edit', username, project_name, access_level=access_level) + return result + + +def remove_project_user(username, project_name): + result = manipulate_project_user('remove', username, project_name) + return result + + +def transfer_project(project_name, group_name): + group_id = get_group_id_from_name(group_name) + group = gl.groups.get(group_id) + project_id = get_project_id_from_name(project_name) + try: + group.transfer_project(project_id) + except gitlab.exceptions.GitlabError as e: + log.error("failed to transfer project:{} to group:{}".format(project_name, group_name)) + log.error(e) + return False + else: + log.info("succeed to transfer project:{} to group:{}".format(project_name, group_name)) + return True + + +# manipulate project branch +def get_project_branches(project_name): + project_id = get_project_id_from_name(project_name) + project = gl.projects.get(project_id) + try: + branches = project.branches.list(all=True, as_list=False) + except gitlab.exceptions.GitlabError as e: + log.error(e) + return False + else: + branches_list = [] + if branches: + for branch in branches: + # print(branch.attributes['name'], branch.attributes['commit']['id']) + branches_list.append(branch.attributes['name']) + return branches_list + + +def judge_branch_in_project(project_name, branch_name): + branches = get_project_branches(project_name) + if branches and branch_name in branches: + log.info("branch:{} exists project:{}".format(branch_name, project_name)) + return True + else: + return False + + +def manipulate_project_branch(operate, project_name, branch_name, ref='master'): + project_id = get_project_id_from_name(project_name) + project = gl.projects.get(project_id) + try: + if operate == 'create': + branch_info = {'branch': branch_name, 'ref': ref} + project.branches.create(branch_info) + elif operate == 'delete': + project.branches.delete(branch_name) + elif operate == 'protect': + branch = project.branches.get(branch_name) + branch.protect() + elif operate == 'unprotect': + branch = project.branches.get(branch_name) + branch.unprotect() + else: + return False + except gitlab.exceptions.GitlabError as e: + log.error(e) + return False + else: + log.info("succeed to {} branch:{}".format(operate, branch_name)) + return True + + +def create_project_branch(project_name, branch_name, ref='master'): + result = manipulate_project_branch('create', project_name, branch_name, ref=ref) + return result + + +def delete_project_branch(project_name, branch_name): + result = manipulate_project_branch('delete', project_name, branch_name) + return result + + +def set_branch_protect(project_name, branch_name): + result = manipulate_project_branch('protect', project_name, branch_name) + return result + + +def unset_branch_protect(project_name, branch_name): + result = manipulate_project_branch('unprotect', project_name, branch_name) + return result + + +create_project_with_import('repo-template-1', 'scm') + + diff --git a/gitlab_api/gitlab.cfg b/gitlab_api/gitlab.cfg new file mode 100644 index 0000000..a996d7a --- /dev/null +++ b/gitlab_api/gitlab.cfg @@ -0,0 +1,9 @@ +[global] +default = local +ssl_verify = false +timeout = 5 + +[local] +url = http://gitlab.example.com +private_token = X3YxrX5r-ddAdLtGqqos +api_version = 4 \ No newline at end of file diff --git a/gitlab_api/group_info.py b/gitlab_api/group_info.py deleted file mode 100644 index 25ece60..0000000 --- a/gitlab_api/group_info.py +++ /dev/null @@ -1,88 +0,0 @@ -import gitlab - -gitlab_url = "http://127.0.0.1" -user = "root" -private_token = "WZ3x9_W3wAqpzrB5Z4xs" -gl = gitlab.Gitlab(gitlab_url, private_token, api_version='4') - -# gitlab.GUEST_ACCESS = 10 -# gitlab.REPORTER_ACCESS = 20 -# gitlab.DEVELOPER_ACCESS = 30 -# gitlab.MASTER_ACCESS = 40 -# gitlab.OWNER_ACCESS = 50 - -# 遍历组的成员信息 username是登陆账号 -# groups = gl.groups.list() -# for g in groups: -# print(g.attributes["name"], g.attributes["id"], g.attributes["web_url"]) - -# group = gl.groups.get(5) -# print(type(group)) -# projects = group.projects.list() -# print(type(projects) -# -# projects_info = [] -# for project in projects: -# # print(project, project.__dict__) -# projects_info.append(project.attributes["id"]) -# -# print(projects_info) -# -# members_username = [] -# members = group.members.list() -# for m in members: -# print(m.attributes["id"], m.attributes["username"]) - - -def grant_privileges(username: str, groupname: str, glu: gitlab.Gitlab): - def _get_groups(): - groups_info = {} - for g in gl.groups.list(): - groups_info[g.attributes["name"]] = g.get_id() - return groups_info - - def _get_members(group_id: int): - group = gl.groups.get(group_id) - members_info = {} - for m in group.members.list(): - members_info[m.attributes["username"]] = m.get_id() - return members_info - - # def _get_projects(group_id: int): - # group = gl.groups.get(group_id) - # projects_info = {} - # for p in group.projects.list(visibility='private'): - # projects_info[p.attributes["name"]] = p.get_id() - # return projects_info - - def _get_projects(): - projects_info = {} - for p in gl.projects.list(): - projects_info[p.attributes["namespace"]["name"]] = p.get_id() - return projects_info - - groups = _get_groups() - group_id = groups[groupname] - members_info = _get_members(group_id) - projects_info = _get_projects() - project_id = projects_info[groupname] - - # 判断用户是否属于这个组 - if username in members_info.keys(): - raise("Error, {} already exists in {}".format(username, groupname)) - - -# grant_privileges("devon123", "admin", gl) -# print(gl.projects.list()[0].attributes["namespace"]["name"]) -# for p in gl.projects.list(): -# print(p) - -project = gl.projects.get(5) -branch = project.branches.get("master") -branch.protect() -print(branch) - - - - - diff --git a/gitlab_api/set_branch.py b/gitlab_api/set_branch.py deleted file mode 100644 index a48c623..0000000 --- a/gitlab_api/set_branch.py +++ /dev/null @@ -1,62 +0,0 @@ -import gitlab -import logging - -gitlab_url = "http://127.0.0.1" -user = "root" -private_token = "WZ3x9_W3wAqpzrB5Z4xs" -gl = gitlab.Gitlab(gitlab_url, private_token) - -log = logging.basicConfig(level=logging.INFO) -# def create_branch(project_id: int, branch_name, gl): -# project = gl.projects.get(project_id) -# -branch_name_master = "master-i18n" -branch_name_develop = "develop-i18n" -# project = gl.projects.get(5) -master_i18n_info = {'branch': branch_name_master, 'ref': 'master'} -develop_i18n_info = {'branch': branch_name_develop, 'ref': branch_name_master} - - -def set_protected_branch(project, branch_name): - try: - project.branches.get(branch_name) - except gitlab.exceptions.GitlabGetError: - logging.error("{} not exists!".format(branch_name)) - else: - try: - project.protectedbranches.get(branch_name) - except gitlab.exceptions.GitlabGetError: - logging.info("{} will be set protected".format(branch_name)) - project.protectedbranches.create({ - 'name': 'master-i18n', - 'merge_access_level': gitlab.MASTER_ACCESS, - 'push_access_level': gitlab.MASTER_ACCESS - }) - else: - logging.info("{} already is a protected branch".format(branch_name)) - - -def create_branch(project, branch_name_master, branch_name_develop): - try: - project.branches.get(branch_name_master) - except gitlab.exceptions.GitlabGetError: - # logging.error("Branch: {} not found".format(branch_name_master)) - logging.info("###Project: {} Branch: {} and {} will be created!".format(project.attributes["name"], branch_name_master, branch_name_develop)) - project.branches.create(master_i18n_info) - set_protected_branch(project, branch_name_master) - project.branches.create(develop_i18n_info) - else: - logging.info("----Project: {} already have branch: {}".format(project.attributes["name"], branch_name_master)) - set_protected_branch(project, branch_name_master) - try: - project.branches.get(branch_name_develop) - except gitlab.exceptions.GitlabGetError: - logging.info("###Project: {} Branch: {} will be created!".format(project.attributes["name"], branch_name_develop)) - project.branches.create(develop_i18n_info) - else: - logging.info("****Project: {} already have branches: {} and {}".format(project.attributes["name"], branch_name_master, branch_name_develop)) - - -project_name = "360/p361" -project = gl.projects.get(project_name) -create_branch(project, branch_name_master, branch_name_develop) diff --git a/gitlab_api/test.py b/gitlab_api/test.py deleted file mode 100644 index cfa9d0d..0000000 --- a/gitlab_api/test.py +++ /dev/null @@ -1,23 +0,0 @@ -import gitlab -import requests - - -gitlab_url = "http://127.0.0.1" -user = "root" -private_token = "WZ3x9_W3wAqpzrB5Z4xs" -gl = gitlab.Gitlab(gitlab_url, private_token, api_version='4') - -# print(len(gl.projects.list(all=True))) -# -project_name = "360/p361" -# p = gl.projects.get(project_name) -# print(p) -# print(p.protectedbranches.list()) -# print(p.protectedbranches.get('master')) - -payload = {'private_token': private_token} -uri = '/api/v3/projects/5/repository/branches/master' -url = gitlab_url + uri -r = requests.get(url, params=payload) -print(r.text) - diff --git a/mysite/polls/templates/polls/detail.html b/mysite/polls/templates/polls/detail.html new file mode 100644 index 0000000..566549b --- /dev/null +++ b/mysite/polls/templates/polls/detail.html @@ -0,0 +1,10 @@ + + + + + Title + + + + + \ No newline at end of file diff --git a/mysite/polls/templates/polls/index.html b/mysite/polls/templates/polls/index.html new file mode 100644 index 0000000..566549b --- /dev/null +++ b/mysite/polls/templates/polls/index.html @@ -0,0 +1,10 @@ + + + + + Title + + + + + \ No newline at end of file diff --git a/mysite/polls/urls.py b/mysite/polls/urls.py new file mode 100644 index 0000000..e69de29 diff --git a/mysql/mysql-crud.py b/mysql/mysql-crud.py new file mode 100644 index 0000000..32ed422 --- /dev/null +++ b/mysql/mysql-crud.py @@ -0,0 +1,79 @@ +""" +CRUD +""" +import sqlalchemy +from sqlalchemy.ext.declarative import declarative_base +from sqlalchemy import Column, Integer, String +from sqlalchemy.orm import sessionmaker + + +# 实体基类 +Base = declarative_base() + + +# 实体类 +class Student(Base): + __tablename__ = 'student' + + id = Column(Integer, primary_key=True, nullable=True, autoincrement=True) + name = Column(String(64), nullable=True) + age = Column(Integer) + + def __repr__(self): + return "<{} id:{} name:{} age:{}>".format(self.__class__.__name__, self.id, self.name, self.age) + + __str__ = __repr__ + + +# 引擎,管理连接池 +host = '127.0.0.1' +port = 32769 +user = 'root' +password = 'devon123' +database = 'test' + +conn_str = "mysql+pymysql://{}:{}@{}:{}/{}".format(user, password, host, port, database) +engine = sqlalchemy.create_engine(conn_str, echo=True) + +Base.metadata.create_all(engine) +# Base.metadata.drop_all(engine) + +Session = sessionmaker() +session = Session(bind=engine) + +try: +# insert + # student = Student() + # student.name = 'tom' + # student.age = 20 + # + # session.add(student) + # student1 = Student() + # session.add_all([student1, student2]) + + # lst = [] + # for i in range(5): + # student = Student() + # student.name = 'tom' + str(i) + # student.age = 20 + i + # lst.append(student) + # + # session.add_all(lst) + # session.commit() # pending + + # select + + + +except Exception as e: + print(e) + session.rollback() +finally: + pass + + + + + + + diff --git a/web/web2.py b/web/web2.py new file mode 100644 index 0000000..e69de29 From 2b320c19ad9d2640637eff90fe5c4893e23c7228 Mon Sep 17 00:00:00 2001 From: devon6686 Date: Wed, 17 Jul 2019 18:50:18 +0800 Subject: [PATCH 10/11] gitlab gerrit api --- cmdb/cmdb.py | 0 exercise/.DS_Store | Bin 6148 -> 6148 bytes exercise/inspect.py | 2 +- flask/app.py | 135 + flask/demo/__init__.py | 0 flask/demo/__pycache__/demo.cpython-36.pyc | Bin 0 -> 1545 bytes flask/demo/config.py | 2 + flask/demo/demo.py | 39 + flask/templates/hello.html | 14 + flask/templates/page_not_found.html | 10 + flask/venv/bin/activate | 76 + flask/venv/bin/activate.csh | 37 + flask/venv/bin/activate.fish | 75 + flask/venv/bin/easy_install | 11 + flask/venv/bin/easy_install-3.6 | 11 + flask/venv/bin/flask | 11 + flask/venv/bin/pip | 11 + flask/venv/bin/pip3 | 11 + flask/venv/bin/pip3.6 | 11 + flask/venv/bin/python | 1 + flask/venv/bin/python3 | 1 + .../Click-7.0.dist-info/INSTALLER | 1 + .../Click-7.0.dist-info/LICENSE.txt | 39 + .../Click-7.0.dist-info/METADATA | 121 + .../site-packages/Click-7.0.dist-info/RECORD | 40 + .../site-packages/Click-7.0.dist-info/WHEEL | 6 + .../Click-7.0.dist-info/top_level.txt | 1 + .../Flask-1.0.2.dist-info/INSTALLER | 1 + .../Flask-1.0.2.dist-info/LICENSE.txt | 31 + .../Flask-1.0.2.dist-info/METADATA | 130 + .../Flask-1.0.2.dist-info/RECORD | 48 + .../site-packages/Flask-1.0.2.dist-info/WHEEL | 6 + .../Flask-1.0.2.dist-info/entry_points.txt | 3 + .../Flask-1.0.2.dist-info/top_level.txt | 1 + .../Jinja2-2.10.dist-info/DESCRIPTION.rst | 37 + .../Jinja2-2.10.dist-info/INSTALLER | 1 + .../Jinja2-2.10.dist-info/LICENSE.txt | 31 + .../Jinja2-2.10.dist-info/METADATA | 68 + .../Jinja2-2.10.dist-info/RECORD | 63 + .../site-packages/Jinja2-2.10.dist-info/WHEEL | 6 + .../Jinja2-2.10.dist-info/entry_points.txt | 4 + .../Jinja2-2.10.dist-info/metadata.json | 1 + .../Jinja2-2.10.dist-info/top_level.txt | 1 + .../MarkupSafe-1.1.1.dist-info/INSTALLER | 1 + .../MarkupSafe-1.1.1.dist-info/LICENSE.rst | 28 + .../MarkupSafe-1.1.1.dist-info/METADATA | 103 + .../MarkupSafe-1.1.1.dist-info/RECORD | 16 + .../MarkupSafe-1.1.1.dist-info/WHEEL | 5 + .../MarkupSafe-1.1.1.dist-info/top_level.txt | 1 + .../Werkzeug-0.14.1.dist-info/DESCRIPTION.rst | 80 + .../Werkzeug-0.14.1.dist-info/INSTALLER | 1 + .../Werkzeug-0.14.1.dist-info/LICENSE.txt | 31 + .../Werkzeug-0.14.1.dist-info/METADATA | 116 + .../Werkzeug-0.14.1.dist-info/RECORD | 97 + .../Werkzeug-0.14.1.dist-info/WHEEL | 6 + .../Werkzeug-0.14.1.dist-info/metadata.json | 1 + .../Werkzeug-0.14.1.dist-info/top_level.txt | 1 + .../__pycache__/easy_install.cpython-36.pyc | Bin 0 -> 327 bytes .../python3.6/site-packages/click/__init__.py | 97 + .../click/__pycache__/__init__.cpython-36.pyc | Bin 0 -> 2670 bytes .../__pycache__/_bashcomplete.cpython-36.pyc | Bin 0 -> 9128 bytes .../click/__pycache__/_compat.cpython-36.pyc | Bin 0 -> 16801 bytes .../__pycache__/_termui_impl.cpython-36.pyc | Bin 0 -> 14036 bytes .../__pycache__/_textwrap.cpython-36.pyc | Bin 0 -> 1349 bytes .../__pycache__/_unicodefun.cpython-36.pyc | Bin 0 -> 3391 bytes .../__pycache__/_winconsole.cpython-36.pyc | Bin 0 -> 8793 bytes .../click/__pycache__/core.cpython-36.pyc | Bin 0 -> 59864 bytes .../__pycache__/decorators.cpython-36.pyc | Bin 0 -> 11622 bytes .../__pycache__/exceptions.cpython-36.pyc | Bin 0 -> 8624 bytes .../__pycache__/formatting.cpython-36.pyc | Bin 0 -> 8567 bytes .../click/__pycache__/globals.cpython-36.pyc | Bin 0 -> 1896 bytes .../click/__pycache__/parser.cpython-36.pyc | Bin 0 -> 11485 bytes .../click/__pycache__/termui.cpython-36.pyc | Bin 0 -> 20834 bytes .../click/__pycache__/testing.cpython-36.pyc | Bin 0 -> 11638 bytes .../click/__pycache__/types.cpython-36.pyc | Bin 0 -> 21881 bytes .../click/__pycache__/utils.cpython-36.pyc | Bin 0 -> 15262 bytes .../site-packages/click/_bashcomplete.py | 293 + .../python3.6/site-packages/click/_compat.py | 703 ++ .../site-packages/click/_termui_impl.py | 621 ++ .../site-packages/click/_textwrap.py | 38 + .../site-packages/click/_unicodefun.py | 125 + .../site-packages/click/_winconsole.py | 307 + .../lib/python3.6/site-packages/click/core.py | 1856 ++++ .../site-packages/click/decorators.py | 311 + .../site-packages/click/exceptions.py | 235 + .../site-packages/click/formatting.py | 256 + .../python3.6/site-packages/click/globals.py | 48 + .../python3.6/site-packages/click/parser.py | 427 + .../python3.6/site-packages/click/termui.py | 606 ++ .../python3.6/site-packages/click/testing.py | 374 + .../python3.6/site-packages/click/types.py | 668 ++ .../python3.6/site-packages/click/utils.py | 440 + .../python3.6/site-packages/easy_install.py | 5 + .../python3.6/site-packages/flask/__init__.py | 49 + .../python3.6/site-packages/flask/__main__.py | 14 + .../flask/__pycache__/__init__.cpython-36.pyc | Bin 0 -> 1844 bytes .../flask/__pycache__/__main__.cpython-36.pyc | Bin 0 -> 471 bytes .../flask/__pycache__/_compat.cpython-36.pyc | Bin 0 -> 3243 bytes .../flask/__pycache__/app.cpython-36.pyc | Bin 0 -> 70918 bytes .../__pycache__/blueprints.cpython-36.pyc | Bin 0 -> 20507 bytes .../flask/__pycache__/cli.cpython-36.pyc | Bin 0 -> 24884 bytes .../flask/__pycache__/config.cpython-36.pyc | Bin 0 -> 10010 bytes .../flask/__pycache__/ctx.cpython-36.pyc | Bin 0 -> 13980 bytes .../__pycache__/debughelpers.cpython-36.pyc | Bin 0 -> 6619 bytes .../flask/__pycache__/globals.cpython-36.pyc | Bin 0 -> 1771 bytes .../flask/__pycache__/helpers.cpython-36.pyc | Bin 0 -> 33079 bytes .../flask/__pycache__/logging.cpython-36.pyc | Bin 0 -> 2400 bytes .../flask/__pycache__/sessions.cpython-36.pyc | Bin 0 -> 12247 bytes .../flask/__pycache__/signals.cpython-36.pyc | Bin 0 -> 2432 bytes .../__pycache__/templating.cpython-36.pyc | Bin 0 -> 4981 bytes .../flask/__pycache__/testing.cpython-36.pyc | Bin 0 -> 7884 bytes .../flask/__pycache__/views.cpython-36.pyc | Bin 0 -> 4789 bytes .../flask/__pycache__/wrappers.cpython-36.pyc | Bin 0 -> 6790 bytes .../python3.6/site-packages/flask/_compat.py | 99 + .../lib/python3.6/site-packages/flask/app.py | 2315 +++++ .../site-packages/flask/blueprints.py | 448 + .../lib/python3.6/site-packages/flask/cli.py | 898 ++ .../python3.6/site-packages/flask/config.py | 265 + .../lib/python3.6/site-packages/flask/ctx.py | 457 + .../site-packages/flask/debughelpers.py | 168 + .../python3.6/site-packages/flask/globals.py | 61 + .../python3.6/site-packages/flask/helpers.py | 1044 +++ .../site-packages/flask/json/__init__.py | 327 + .../json/__pycache__/__init__.cpython-36.pyc | Bin 0 -> 10290 bytes .../flask/json/__pycache__/tag.cpython-36.pyc | Bin 0 -> 11092 bytes .../python3.6/site-packages/flask/json/tag.py | 300 + .../python3.6/site-packages/flask/logging.py | 78 + .../python3.6/site-packages/flask/sessions.py | 385 + .../python3.6/site-packages/flask/signals.py | 57 + .../site-packages/flask/templating.py | 150 + .../python3.6/site-packages/flask/testing.py | 250 + .../python3.6/site-packages/flask/views.py | 158 + .../python3.6/site-packages/flask/wrappers.py | 216 + .../itsdangerous-1.1.0.dist-info/INSTALLER | 1 + .../itsdangerous-1.1.0.dist-info/LICENSE.rst | 47 + .../itsdangerous-1.1.0.dist-info/METADATA | 98 + .../itsdangerous-1.1.0.dist-info/RECORD | 26 + .../itsdangerous-1.1.0.dist-info/WHEEL | 6 + .../top_level.txt | 1 + .../site-packages/itsdangerous/__init__.py | 22 + .../__pycache__/__init__.cpython-36.pyc | Bin 0 -> 1024 bytes .../__pycache__/_compat.cpython-36.pyc | Bin 0 -> 1186 bytes .../__pycache__/_json.cpython-36.pyc | Bin 0 -> 879 bytes .../__pycache__/encoding.cpython-36.pyc | Bin 0 -> 1651 bytes .../__pycache__/exc.cpython-36.pyc | Bin 0 -> 3240 bytes .../__pycache__/jws.cpython-36.pyc | Bin 0 -> 6699 bytes .../__pycache__/serializer.cpython-36.pyc | Bin 0 -> 8054 bytes .../__pycache__/signer.cpython-36.pyc | Bin 0 -> 5815 bytes .../__pycache__/timed.cpython-36.pyc | Bin 0 -> 4581 bytes .../__pycache__/url_safe.cpython-36.pyc | Bin 0 -> 2570 bytes .../site-packages/itsdangerous/_compat.py | 46 + .../site-packages/itsdangerous/_json.py | 18 + .../site-packages/itsdangerous/encoding.py | 49 + .../site-packages/itsdangerous/exc.py | 98 + .../site-packages/itsdangerous/jws.py | 218 + .../site-packages/itsdangerous/serializer.py | 233 + .../site-packages/itsdangerous/signer.py | 179 + .../site-packages/itsdangerous/timed.py | 147 + .../site-packages/itsdangerous/url_safe.py | 65 + .../site-packages/jinja2/__init__.py | 83 + .../__pycache__/__init__.cpython-36.pyc | Bin 0 -> 2548 bytes .../jinja2/__pycache__/_compat.cpython-36.pyc | Bin 0 -> 3358 bytes .../__pycache__/_identifier.cpython-36.pyc | Bin 0 -> 1861 bytes .../__pycache__/asyncfilters.cpython-36.pyc | Bin 0 -> 4829 bytes .../__pycache__/asyncsupport.cpython-36.pyc | Bin 0 -> 8178 bytes .../jinja2/__pycache__/bccache.cpython-36.pyc | Bin 0 -> 12734 bytes .../__pycache__/compiler.cpython-36.pyc | Bin 0 -> 46915 bytes .../__pycache__/constants.cpython-36.pyc | Bin 0 -> 1724 bytes .../jinja2/__pycache__/debug.cpython-36.pyc | Bin 0 -> 9357 bytes .../__pycache__/defaults.cpython-36.pyc | Bin 0 -> 1474 bytes .../__pycache__/environment.cpython-36.pyc | Bin 0 -> 43285 bytes .../__pycache__/exceptions.cpython-36.pyc | Bin 0 -> 5034 bytes .../jinja2/__pycache__/ext.cpython-36.pyc | Bin 0 -> 20125 bytes .../jinja2/__pycache__/filters.cpython-36.pyc | Bin 0 -> 34432 bytes .../__pycache__/idtracking.cpython-36.pyc | Bin 0 -> 9963 bytes .../jinja2/__pycache__/lexer.cpython-36.pyc | Bin 0 -> 18587 bytes .../jinja2/__pycache__/loaders.cpython-36.pyc | Bin 0 -> 16594 bytes .../jinja2/__pycache__/meta.cpython-36.pyc | Bin 0 -> 3685 bytes .../__pycache__/nativetypes.cpython-36.pyc | Bin 0 -> 5148 bytes .../jinja2/__pycache__/nodes.cpython-36.pyc | Bin 0 -> 36682 bytes .../__pycache__/optimizer.cpython-36.pyc | Bin 0 -> 2054 bytes .../jinja2/__pycache__/parser.cpython-36.pyc | Bin 0 -> 25359 bytes .../jinja2/__pycache__/runtime.cpython-36.pyc | Bin 0 -> 24624 bytes .../jinja2/__pycache__/sandbox.cpython-36.pyc | Bin 0 -> 14011 bytes .../jinja2/__pycache__/tests.cpython-36.pyc | Bin 0 -> 4430 bytes .../jinja2/__pycache__/utils.cpython-36.pyc | Bin 0 -> 20887 bytes .../jinja2/__pycache__/visitor.cpython-36.pyc | Bin 0 -> 3370 bytes .../python3.6/site-packages/jinja2/_compat.py | 99 + .../site-packages/jinja2/_identifier.py | 2 + .../site-packages/jinja2/asyncfilters.py | 146 + .../site-packages/jinja2/asyncsupport.py | 256 + .../python3.6/site-packages/jinja2/bccache.py | 362 + .../site-packages/jinja2/compiler.py | 1721 ++++ .../site-packages/jinja2/constants.py | 32 + .../python3.6/site-packages/jinja2/debug.py | 372 + .../site-packages/jinja2/defaults.py | 56 + .../site-packages/jinja2/environment.py | 1276 +++ .../site-packages/jinja2/exceptions.py | 146 + .../lib/python3.6/site-packages/jinja2/ext.py | 627 ++ .../python3.6/site-packages/jinja2/filters.py | 1190 +++ .../site-packages/jinja2/idtracking.py | 286 + .../python3.6/site-packages/jinja2/lexer.py | 739 ++ .../python3.6/site-packages/jinja2/loaders.py | 481 + .../python3.6/site-packages/jinja2/meta.py | 106 + .../site-packages/jinja2/nativetypes.py | 220 + .../python3.6/site-packages/jinja2/nodes.py | 999 ++ .../site-packages/jinja2/optimizer.py | 49 + .../python3.6/site-packages/jinja2/parser.py | 903 ++ .../python3.6/site-packages/jinja2/runtime.py | 813 ++ .../python3.6/site-packages/jinja2/sandbox.py | 475 + .../python3.6/site-packages/jinja2/tests.py | 175 + .../python3.6/site-packages/jinja2/utils.py | 647 ++ .../python3.6/site-packages/jinja2/visitor.py | 87 + .../site-packages/markupsafe/__init__.py | 327 + .../__pycache__/__init__.cpython-36.pyc | Bin 0 -> 10985 bytes .../__pycache__/_compat.cpython-36.pyc | Bin 0 -> 777 bytes .../__pycache__/_constants.cpython-36.pyc | Bin 0 -> 4277 bytes .../__pycache__/_native.cpython-36.pyc | Bin 0 -> 2129 bytes .../site-packages/markupsafe/_compat.py | 33 + .../site-packages/markupsafe/_constants.py | 264 + .../site-packages/markupsafe/_native.py | 69 + .../site-packages/markupsafe/_speedups.c | 423 + .../_speedups.cpython-36m-darwin.so | Bin 0 -> 35080 bytes .../pip-19.0.3.dist-info/INSTALLER | 1 + .../pip-19.0.3.dist-info/LICENSE.txt | 20 + .../pip-19.0.3.dist-info/METADATA | 75 + .../site-packages/pip-19.0.3.dist-info/RECORD | 620 ++ .../site-packages/pip-19.0.3.dist-info/WHEEL | 6 + .../pip-19.0.3.dist-info/entry_points.txt | 5 + .../pip-19.0.3.dist-info/top_level.txt | 1 + .../python3.6/site-packages/pip/__init__.py | 1 + .../python3.6/site-packages/pip/__main__.py | 19 + .../pip/__pycache__/__init__.cpython-36.pyc | Bin 0 -> 200 bytes .../pip/__pycache__/__main__.cpython-36.pyc | Bin 0 -> 452 bytes .../site-packages/pip/_internal/__init__.py | 78 + .../__pycache__/__init__.cpython-36.pyc | Bin 0 -> 1844 bytes .../__pycache__/build_env.cpython-36.pyc | Bin 0 -> 7506 bytes .../__pycache__/cache.cpython-36.pyc | Bin 0 -> 7052 bytes .../__pycache__/configuration.cpython-36.pyc | Bin 0 -> 9847 bytes .../__pycache__/download.cpython-36.pyc | Bin 0 -> 21208 bytes .../__pycache__/exceptions.cpython-36.pyc | Bin 0 -> 11744 bytes .../__pycache__/index.cpython-36.pyc | Bin 0 -> 25299 bytes .../__pycache__/locations.cpython-36.pyc | Bin 0 -> 4435 bytes .../__pycache__/pep425tags.cpython-36.pyc | Bin 0 -> 8336 bytes .../__pycache__/pyproject.cpython-36.pyc | Bin 0 -> 3186 bytes .../__pycache__/resolve.cpython-36.pyc | Bin 0 -> 9106 bytes .../__pycache__/wheel.cpython-36.pyc | Bin 0 -> 25974 bytes .../site-packages/pip/_internal/build_env.py | 215 + .../site-packages/pip/_internal/cache.py | 224 + .../pip/_internal/cli/__init__.py | 4 + .../cli/__pycache__/__init__.cpython-36.pyc | Bin 0 -> 275 bytes .../__pycache__/autocompletion.cpython-36.pyc | Bin 0 -> 5117 bytes .../__pycache__/base_command.cpython-36.pyc | Bin 0 -> 7825 bytes .../cli/__pycache__/cmdoptions.cpython-36.pyc | Bin 0 -> 16893 bytes .../__pycache__/main_parser.cpython-36.pyc | Bin 0 -> 2363 bytes .../cli/__pycache__/parser.cpython-36.pyc | Bin 0 -> 8959 bytes .../__pycache__/status_codes.cpython-36.pyc | Bin 0 -> 404 bytes .../pip/_internal/cli/autocompletion.py | 152 + .../pip/_internal/cli/base_command.py | 341 + .../pip/_internal/cli/cmdoptions.py | 809 ++ .../pip/_internal/cli/main_parser.py | 104 + .../site-packages/pip/_internal/cli/parser.py | 261 + .../pip/_internal/cli/status_codes.py | 8 + .../pip/_internal/commands/__init__.py | 79 + .../__pycache__/__init__.cpython-36.pyc | Bin 0 -> 2503 bytes .../commands/__pycache__/check.cpython-36.pyc | Bin 0 -> 1328 bytes .../__pycache__/completion.cpython-36.pyc | Bin 0 -> 3077 bytes .../__pycache__/configuration.cpython-36.pyc | Bin 0 -> 6447 bytes .../__pycache__/download.cpython-36.pyc | Bin 0 -> 4718 bytes .../__pycache__/freeze.cpython-36.pyc | Bin 0 -> 2865 bytes .../commands/__pycache__/hash.cpython-36.pyc | Bin 0 -> 2067 bytes .../commands/__pycache__/help.cpython-36.pyc | Bin 0 -> 1243 bytes .../__pycache__/install.cpython-36.pyc | Bin 0 -> 12472 bytes .../commands/__pycache__/list.cpython-36.pyc | Bin 0 -> 8719 bytes .../__pycache__/search.cpython-36.pyc | Bin 0 -> 4313 bytes .../commands/__pycache__/show.cpython-36.pyc | Bin 0 -> 5922 bytes .../__pycache__/uninstall.cpython-36.pyc | Bin 0 -> 2699 bytes .../commands/__pycache__/wheel.cpython-36.pyc | Bin 0 -> 5002 bytes .../pip/_internal/commands/check.py | 41 + .../pip/_internal/commands/completion.py | 94 + .../pip/_internal/commands/configuration.py | 227 + .../pip/_internal/commands/download.py | 176 + .../pip/_internal/commands/freeze.py | 96 + .../pip/_internal/commands/hash.py | 57 + .../pip/_internal/commands/help.py | 37 + .../pip/_internal/commands/install.py | 566 ++ .../pip/_internal/commands/list.py | 301 + .../pip/_internal/commands/search.py | 135 + .../pip/_internal/commands/show.py | 168 + .../pip/_internal/commands/uninstall.py | 78 + .../pip/_internal/commands/wheel.py | 186 + .../pip/_internal/configuration.py | 387 + .../site-packages/pip/_internal/download.py | 971 ++ .../site-packages/pip/_internal/exceptions.py | 274 + .../site-packages/pip/_internal/index.py | 990 ++ .../site-packages/pip/_internal/locations.py | 211 + .../pip/_internal/models/__init__.py | 2 + .../__pycache__/__init__.cpython-36.pyc | Bin 0 -> 263 bytes .../__pycache__/candidate.cpython-36.pyc | Bin 0 -> 1312 bytes .../__pycache__/format_control.cpython-36.pyc | Bin 0 -> 2266 bytes .../models/__pycache__/index.cpython-36.pyc | Bin 0 -> 1167 bytes .../models/__pycache__/link.cpython-36.pyc | Bin 0 -> 5001 bytes .../pip/_internal/models/candidate.py | 31 + .../pip/_internal/models/format_control.py | 73 + .../pip/_internal/models/index.py | 31 + .../pip/_internal/models/link.py | 163 + .../pip/_internal/operations/__init__.py | 0 .../__pycache__/__init__.cpython-36.pyc | Bin 0 -> 199 bytes .../__pycache__/check.cpython-36.pyc | Bin 0 -> 3624 bytes .../__pycache__/freeze.cpython-36.pyc | Bin 0 -> 5671 bytes .../__pycache__/prepare.cpython-36.pyc | Bin 0 -> 10281 bytes .../pip/_internal/operations/check.py | 155 + .../pip/_internal/operations/freeze.py | 247 + .../pip/_internal/operations/prepare.py | 413 + .../site-packages/pip/_internal/pep425tags.py | 381 + .../site-packages/pip/_internal/pyproject.py | 171 + .../pip/_internal/req/__init__.py | 77 + .../req/__pycache__/__init__.cpython-36.pyc | Bin 0 -> 1686 bytes .../__pycache__/constructors.cpython-36.pyc | Bin 0 -> 7608 bytes .../req/__pycache__/req_file.cpython-36.pyc | Bin 0 -> 9211 bytes .../__pycache__/req_install.cpython-36.pyc | Bin 0 -> 25061 bytes .../req/__pycache__/req_set.cpython-36.pyc | Bin 0 -> 6041 bytes .../__pycache__/req_tracker.cpython-36.pyc | Bin 0 -> 3145 bytes .../__pycache__/req_uninstall.cpython-36.pyc | Bin 0 -> 17015 bytes .../pip/_internal/req/constructors.py | 339 + .../pip/_internal/req/req_file.py | 382 + .../pip/_internal/req/req_install.py | 1021 ++ .../pip/_internal/req/req_set.py | 197 + .../pip/_internal/req/req_tracker.py | 88 + .../pip/_internal/req/req_uninstall.py | 596 ++ .../site-packages/pip/_internal/resolve.py | 393 + .../pip/_internal/utils/__init__.py | 0 .../utils/__pycache__/__init__.cpython-36.pyc | Bin 0 -> 194 bytes .../utils/__pycache__/appdirs.cpython-36.pyc | Bin 0 -> 8051 bytes .../utils/__pycache__/compat.cpython-36.pyc | Bin 0 -> 6171 bytes .../__pycache__/deprecation.cpython-36.pyc | Bin 0 -> 2568 bytes .../utils/__pycache__/encoding.cpython-36.pyc | Bin 0 -> 1271 bytes .../__pycache__/filesystem.cpython-36.pyc | Bin 0 -> 663 bytes .../utils/__pycache__/glibc.cpython-36.pyc | Bin 0 -> 1687 bytes .../utils/__pycache__/hashes.cpython-36.pyc | Bin 0 -> 3601 bytes .../utils/__pycache__/logging.cpython-36.pyc | Bin 0 -> 7840 bytes .../utils/__pycache__/misc.cpython-36.pyc | Bin 0 -> 25805 bytes .../utils/__pycache__/models.cpython-36.pyc | Bin 0 -> 1943 bytes .../utils/__pycache__/outdated.cpython-36.pyc | Bin 0 -> 4114 bytes .../__pycache__/packaging.cpython-36.pyc | Bin 0 -> 2613 bytes .../setuptools_build.cpython-36.pyc | Bin 0 -> 389 bytes .../utils/__pycache__/temp_dir.cpython-36.pyc | Bin 0 -> 4916 bytes .../utils/__pycache__/typing.cpython-36.pyc | Bin 0 -> 1338 bytes .../utils/__pycache__/ui.cpython-36.pyc | Bin 0 -> 12321 bytes .../pip/_internal/utils/appdirs.py | 270 + .../pip/_internal/utils/compat.py | 264 + .../pip/_internal/utils/deprecation.py | 90 + .../pip/_internal/utils/encoding.py | 39 + .../pip/_internal/utils/filesystem.py | 30 + .../pip/_internal/utils/glibc.py | 93 + .../pip/_internal/utils/hashes.py | 115 + .../pip/_internal/utils/logging.py | 318 + .../site-packages/pip/_internal/utils/misc.py | 1040 +++ .../pip/_internal/utils/models.py | 40 + .../pip/_internal/utils/outdated.py | 164 + .../pip/_internal/utils/packaging.py | 85 + .../pip/_internal/utils/setuptools_build.py | 8 + .../pip/_internal/utils/temp_dir.py | 155 + .../pip/_internal/utils/typing.py | 29 + .../site-packages/pip/_internal/utils/ui.py | 441 + .../pip/_internal/vcs/__init__.py | 534 ++ .../vcs/__pycache__/__init__.cpython-36.pyc | Bin 0 -> 15410 bytes .../vcs/__pycache__/bazaar.cpython-36.pyc | Bin 0 -> 3851 bytes .../vcs/__pycache__/git.cpython-36.pyc | Bin 0 -> 9484 bytes .../vcs/__pycache__/mercurial.cpython-36.pyc | Bin 0 -> 3795 bytes .../vcs/__pycache__/subversion.cpython-36.pyc | Bin 0 -> 6011 bytes .../site-packages/pip/_internal/vcs/bazaar.py | 114 + .../site-packages/pip/_internal/vcs/git.py | 369 + .../pip/_internal/vcs/mercurial.py | 103 + .../pip/_internal/vcs/subversion.py | 200 + .../site-packages/pip/_internal/wheel.py | 1095 +++ .../site-packages/pip/_vendor/__init__.py | 111 + .../__pycache__/__init__.cpython-36.pyc | Bin 0 -> 2882 bytes .../__pycache__/appdirs.cpython-36.pyc | Bin 0 -> 20661 bytes .../_vendor/__pycache__/distro.cpython-36.pyc | Bin 0 -> 36177 bytes .../__pycache__/ipaddress.cpython-36.pyc | Bin 0 -> 66569 bytes .../__pycache__/pyparsing.cpython-36.pyc | Bin 0 -> 221208 bytes .../__pycache__/retrying.cpython-36.pyc | Bin 0 -> 8094 bytes .../_vendor/__pycache__/six.cpython-36.pyc | Bin 0 -> 26512 bytes .../site-packages/pip/_vendor/appdirs.py | 604 ++ .../pip/_vendor/cachecontrol/__init__.py | 11 + .../__pycache__/__init__.cpython-36.pyc | Bin 0 -> 552 bytes .../__pycache__/_cmd.cpython-36.pyc | Bin 0 -> 1555 bytes .../__pycache__/adapter.cpython-36.pyc | Bin 0 -> 3043 bytes .../__pycache__/cache.cpython-36.pyc | Bin 0 -> 1768 bytes .../__pycache__/compat.cpython-36.pyc | Bin 0 -> 759 bytes .../__pycache__/controller.cpython-36.pyc | Bin 0 -> 7700 bytes .../__pycache__/filewrapper.cpython-36.pyc | Bin 0 -> 2156 bytes .../__pycache__/heuristics.cpython-36.pyc | Bin 0 -> 4686 bytes .../__pycache__/serialize.cpython-36.pyc | Bin 0 -> 4240 bytes .../__pycache__/wrapper.cpython-36.pyc | Bin 0 -> 660 bytes .../pip/_vendor/cachecontrol/_cmd.py | 57 + .../pip/_vendor/cachecontrol/adapter.py | 133 + .../pip/_vendor/cachecontrol/cache.py | 39 + .../_vendor/cachecontrol/caches/__init__.py | 2 + .../__pycache__/__init__.cpython-36.pyc | Bin 0 -> 296 bytes .../__pycache__/file_cache.cpython-36.pyc | Bin 0 -> 3230 bytes .../__pycache__/redis_cache.cpython-36.pyc | Bin 0 -> 1552 bytes .../_vendor/cachecontrol/caches/file_cache.py | 146 + .../cachecontrol/caches/redis_cache.py | 33 + .../pip/_vendor/cachecontrol/compat.py | 29 + .../pip/_vendor/cachecontrol/controller.py | 367 + .../pip/_vendor/cachecontrol/filewrapper.py | 80 + .../pip/_vendor/cachecontrol/heuristics.py | 135 + .../pip/_vendor/cachecontrol/serialize.py | 186 + .../pip/_vendor/cachecontrol/wrapper.py | 29 + .../pip/_vendor/certifi/__init__.py | 3 + .../pip/_vendor/certifi/__main__.py | 2 + .../__pycache__/__init__.cpython-36.pyc | Bin 0 -> 259 bytes .../__pycache__/__main__.cpython-36.pyc | Bin 0 -> 262 bytes .../certifi/__pycache__/core.cpython-36.pyc | Bin 0 -> 520 bytes .../pip/_vendor/certifi/cacert.pem | 4512 +++++++++ .../site-packages/pip/_vendor/certifi/core.py | 20 + .../pip/_vendor/chardet/__init__.py | 39 + .../__pycache__/__init__.cpython-36.pyc | Bin 0 -> 846 bytes .../__pycache__/big5freq.cpython-36.pyc | Bin 0 -> 54733 bytes .../__pycache__/big5prober.cpython-36.pyc | Bin 0 -> 1122 bytes .../chardistribution.cpython-36.pyc | Bin 0 -> 6318 bytes .../charsetgroupprober.cpython-36.pyc | Bin 0 -> 2229 bytes .../__pycache__/charsetprober.cpython-36.pyc | Bin 0 -> 3455 bytes .../codingstatemachine.cpython-36.pyc | Bin 0 -> 2886 bytes .../chardet/__pycache__/compat.cpython-36.pyc | Bin 0 -> 362 bytes .../__pycache__/cp949prober.cpython-36.pyc | Bin 0 -> 1129 bytes .../chardet/__pycache__/enums.cpython-36.pyc | Bin 0 -> 2620 bytes .../__pycache__/escprober.cpython-36.pyc | Bin 0 -> 2611 bytes .../chardet/__pycache__/escsm.cpython-36.pyc | Bin 0 -> 7368 bytes .../__pycache__/eucjpprober.cpython-36.pyc | Bin 0 -> 2415 bytes .../__pycache__/euckrfreq.cpython-36.pyc | Bin 0 -> 24119 bytes .../__pycache__/euckrprober.cpython-36.pyc | Bin 0 -> 1130 bytes .../__pycache__/euctwfreq.cpython-36.pyc | Bin 0 -> 54742 bytes .../__pycache__/euctwprober.cpython-36.pyc | Bin 0 -> 1130 bytes .../__pycache__/gb2312freq.cpython-36.pyc | Bin 0 -> 38384 bytes .../__pycache__/gb2312prober.cpython-36.pyc | Bin 0 -> 1138 bytes .../__pycache__/hebrewprober.cpython-36.pyc | Bin 0 -> 2972 bytes .../__pycache__/jisfreq.cpython-36.pyc | Bin 0 -> 44528 bytes .../chardet/__pycache__/jpcntx.cpython-36.pyc | Bin 0 -> 38667 bytes .../langbulgarianmodel.cpython-36.pyc | Bin 0 -> 24882 bytes .../langcyrillicmodel.cpython-36.pyc | Bin 0 -> 30433 bytes .../__pycache__/langgreekmodel.cpython-36.pyc | Bin 0 -> 24560 bytes .../langhebrewmodel.cpython-36.pyc | Bin 0 -> 23414 bytes .../langhungarianmodel.cpython-36.pyc | Bin 0 -> 24856 bytes .../__pycache__/langthaimodel.cpython-36.pyc | Bin 0 -> 23393 bytes .../langturkishmodel.cpython-36.pyc | Bin 0 -> 23411 bytes .../__pycache__/latin1prober.cpython-36.pyc | Bin 0 -> 2943 bytes .../mbcharsetprober.cpython-36.pyc | Bin 0 -> 2234 bytes .../mbcsgroupprober.cpython-36.pyc | Bin 0 -> 1125 bytes .../chardet/__pycache__/mbcssm.cpython-36.pyc | Bin 0 -> 17578 bytes .../sbcharsetprober.cpython-36.pyc | Bin 0 -> 2987 bytes .../sbcsgroupprober.cpython-36.pyc | Bin 0 -> 1615 bytes .../__pycache__/sjisprober.cpython-36.pyc | Bin 0 -> 2441 bytes .../universaldetector.cpython-36.pyc | Bin 0 -> 5836 bytes .../__pycache__/utf8prober.cpython-36.pyc | Bin 0 -> 1972 bytes .../__pycache__/version.cpython-36.pyc | Bin 0 -> 441 bytes .../pip/_vendor/chardet/big5freq.py | 386 + .../pip/_vendor/chardet/big5prober.py | 47 + .../pip/_vendor/chardet/chardistribution.py | 233 + .../pip/_vendor/chardet/charsetgroupprober.py | 106 + .../pip/_vendor/chardet/charsetprober.py | 145 + .../pip/_vendor/chardet/cli/__init__.py | 1 + .../cli/__pycache__/__init__.cpython-36.pyc | Bin 0 -> 198 bytes .../cli/__pycache__/chardetect.cpython-36.pyc | Bin 0 -> 2705 bytes .../pip/_vendor/chardet/cli/chardetect.py | 85 + .../pip/_vendor/chardet/codingstatemachine.py | 88 + .../pip/_vendor/chardet/compat.py | 34 + .../pip/_vendor/chardet/cp949prober.py | 49 + .../pip/_vendor/chardet/enums.py | 76 + .../pip/_vendor/chardet/escprober.py | 101 + .../pip/_vendor/chardet/escsm.py | 246 + .../pip/_vendor/chardet/eucjpprober.py | 92 + .../pip/_vendor/chardet/euckrfreq.py | 195 + .../pip/_vendor/chardet/euckrprober.py | 47 + .../pip/_vendor/chardet/euctwfreq.py | 387 + .../pip/_vendor/chardet/euctwprober.py | 46 + .../pip/_vendor/chardet/gb2312freq.py | 283 + .../pip/_vendor/chardet/gb2312prober.py | 46 + .../pip/_vendor/chardet/hebrewprober.py | 292 + .../pip/_vendor/chardet/jisfreq.py | 325 + .../pip/_vendor/chardet/jpcntx.py | 233 + .../pip/_vendor/chardet/langbulgarianmodel.py | 228 + .../pip/_vendor/chardet/langcyrillicmodel.py | 333 + .../pip/_vendor/chardet/langgreekmodel.py | 225 + .../pip/_vendor/chardet/langhebrewmodel.py | 200 + .../pip/_vendor/chardet/langhungarianmodel.py | 225 + .../pip/_vendor/chardet/langthaimodel.py | 199 + .../pip/_vendor/chardet/langturkishmodel.py | 193 + .../pip/_vendor/chardet/latin1prober.py | 145 + .../pip/_vendor/chardet/mbcharsetprober.py | 91 + .../pip/_vendor/chardet/mbcsgroupprober.py | 54 + .../pip/_vendor/chardet/mbcssm.py | 572 ++ .../pip/_vendor/chardet/sbcharsetprober.py | 132 + .../pip/_vendor/chardet/sbcsgroupprober.py | 73 + .../pip/_vendor/chardet/sjisprober.py | 92 + .../pip/_vendor/chardet/universaldetector.py | 286 + .../pip/_vendor/chardet/utf8prober.py | 82 + .../pip/_vendor/chardet/version.py | 9 + .../pip/_vendor/colorama/__init__.py | 6 + .../__pycache__/__init__.cpython-36.pyc | Bin 0 -> 446 bytes .../colorama/__pycache__/ansi.cpython-36.pyc | Bin 0 -> 3344 bytes .../__pycache__/ansitowin32.cpython-36.pyc | Bin 0 -> 7619 bytes .../__pycache__/initialise.cpython-36.pyc | Bin 0 -> 1667 bytes .../colorama/__pycache__/win32.cpython-36.pyc | Bin 0 -> 3869 bytes .../__pycache__/winterm.cpython-36.pyc | Bin 0 -> 4607 bytes .../pip/_vendor/colorama/ansi.py | 102 + .../pip/_vendor/colorama/ansitowin32.py | 257 + .../pip/_vendor/colorama/initialise.py | 80 + .../pip/_vendor/colorama/win32.py | 152 + .../pip/_vendor/colorama/winterm.py | 169 + .../pip/_vendor/distlib/__init__.py | 23 + .../__pycache__/__init__.cpython-36.pyc | Bin 0 -> 1044 bytes .../distlib/__pycache__/compat.cpython-36.pyc | Bin 0 -> 32080 bytes .../__pycache__/database.cpython-36.pyc | Bin 0 -> 42647 bytes .../distlib/__pycache__/index.cpython-36.pyc | Bin 0 -> 17375 bytes .../__pycache__/locators.cpython-36.pyc | Bin 0 -> 38855 bytes .../__pycache__/manifest.cpython-36.pyc | Bin 0 -> 10363 bytes .../__pycache__/markers.cpython-36.pyc | Bin 0 -> 4482 bytes .../__pycache__/metadata.cpython-36.pyc | Bin 0 -> 27722 bytes .../__pycache__/resources.cpython-36.pyc | Bin 0 -> 10911 bytes .../__pycache__/scripts.cpython-36.pyc | Bin 0 -> 11098 bytes .../distlib/__pycache__/util.cpython-36.pyc | Bin 0 -> 48081 bytes .../__pycache__/version.cpython-36.pyc | Bin 0 -> 20690 bytes .../distlib/__pycache__/wheel.cpython-36.pyc | Bin 0 -> 25454 bytes .../pip/_vendor/distlib/_backport/__init__.py | 6 + .../__pycache__/__init__.cpython-36.pyc | Bin 0 -> 486 bytes .../_backport/__pycache__/misc.cpython-36.pyc | Bin 0 -> 1092 bytes .../__pycache__/shutil.cpython-36.pyc | Bin 0 -> 21439 bytes .../__pycache__/sysconfig.cpython-36.pyc | Bin 0 -> 16040 bytes .../__pycache__/tarfile.cpython-36.pyc | Bin 0 -> 63050 bytes .../pip/_vendor/distlib/_backport/misc.py | 41 + .../pip/_vendor/distlib/_backport/shutil.py | 761 ++ .../_vendor/distlib/_backport/sysconfig.cfg | 84 + .../_vendor/distlib/_backport/sysconfig.py | 788 ++ .../pip/_vendor/distlib/_backport/tarfile.py | 2607 ++++++ .../pip/_vendor/distlib/compat.py | 1120 +++ .../pip/_vendor/distlib/database.py | 1339 +++ .../pip/_vendor/distlib/index.py | 516 ++ .../pip/_vendor/distlib/locators.py | 1295 +++ .../pip/_vendor/distlib/manifest.py | 393 + .../pip/_vendor/distlib/markers.py | 131 + .../pip/_vendor/distlib/metadata.py | 1094 +++ .../pip/_vendor/distlib/resources.py | 355 + .../pip/_vendor/distlib/scripts.py | 417 + .../site-packages/pip/_vendor/distlib/t32.exe | Bin 0 -> 92672 bytes .../site-packages/pip/_vendor/distlib/t64.exe | Bin 0 -> 102400 bytes .../site-packages/pip/_vendor/distlib/util.py | 1756 ++++ .../pip/_vendor/distlib/version.py | 736 ++ .../site-packages/pip/_vendor/distlib/w32.exe | Bin 0 -> 89088 bytes .../site-packages/pip/_vendor/distlib/w64.exe | Bin 0 -> 99328 bytes .../pip/_vendor/distlib/wheel.py | 988 ++ .../site-packages/pip/_vendor/distro.py | 1197 +++ .../pip/_vendor/html5lib/__init__.py | 35 + .../__pycache__/__init__.cpython-36.pyc | Bin 0 -> 1315 bytes .../__pycache__/_ihatexml.cpython-36.pyc | Bin 0 -> 13859 bytes .../__pycache__/_inputstream.cpython-36.pyc | Bin 0 -> 22727 bytes .../__pycache__/_tokenizer.cpython-36.pyc | Bin 0 -> 42163 bytes .../__pycache__/_utils.cpython-36.pyc | Bin 0 -> 3285 bytes .../__pycache__/constants.cpython-36.pyc | Bin 0 -> 66431 bytes .../__pycache__/html5parser.cpython-36.pyc | Bin 0 -> 99764 bytes .../__pycache__/serializer.cpython-36.pyc | Bin 0 -> 10933 bytes .../pip/_vendor/html5lib/_ihatexml.py | 288 + .../pip/_vendor/html5lib/_inputstream.py | 923 ++ .../pip/_vendor/html5lib/_tokenizer.py | 1721 ++++ .../pip/_vendor/html5lib/_trie/__init__.py | 14 + .../_trie/__pycache__/__init__.cpython-36.pyc | Bin 0 -> 428 bytes .../_trie/__pycache__/_base.cpython-36.pyc | Bin 0 -> 1511 bytes .../_trie/__pycache__/datrie.cpython-36.pyc | Bin 0 -> 2030 bytes .../_trie/__pycache__/py.cpython-36.pyc | Bin 0 -> 2235 bytes .../pip/_vendor/html5lib/_trie/_base.py | 37 + .../pip/_vendor/html5lib/_trie/datrie.py | 44 + .../pip/_vendor/html5lib/_trie/py.py | 67 + .../pip/_vendor/html5lib/_utils.py | 124 + .../pip/_vendor/html5lib/constants.py | 2947 ++++++ .../pip/_vendor/html5lib/filters/__init__.py | 0 .../__pycache__/__init__.cpython-36.pyc | Bin 0 -> 203 bytes .../alphabeticalattributes.cpython-36.pyc | Bin 0 -> 1329 bytes .../filters/__pycache__/base.cpython-36.pyc | Bin 0 -> 853 bytes .../inject_meta_charset.cpython-36.pyc | Bin 0 -> 1900 bytes .../filters/__pycache__/lint.cpython-36.pyc | Bin 0 -> 2646 bytes .../__pycache__/optionaltags.cpython-36.pyc | Bin 0 -> 3107 bytes .../__pycache__/sanitizer.cpython-36.pyc | Bin 0 -> 19165 bytes .../__pycache__/whitespace.cpython-36.pyc | Bin 0 -> 1361 bytes .../filters/alphabeticalattributes.py | 29 + .../pip/_vendor/html5lib/filters/base.py | 12 + .../html5lib/filters/inject_meta_charset.py | 73 + .../pip/_vendor/html5lib/filters/lint.py | 93 + .../_vendor/html5lib/filters/optionaltags.py | 207 + .../pip/_vendor/html5lib/filters/sanitizer.py | 896 ++ .../_vendor/html5lib/filters/whitespace.py | 38 + .../pip/_vendor/html5lib/html5parser.py | 2791 ++++++ .../pip/_vendor/html5lib/serializer.py | 409 + .../_vendor/html5lib/treeadapters/__init__.py | 30 + .../__pycache__/__init__.cpython-36.pyc | Bin 0 -> 942 bytes .../__pycache__/genshi.cpython-36.pyc | Bin 0 -> 1686 bytes .../__pycache__/sax.cpython-36.pyc | Bin 0 -> 1504 bytes .../_vendor/html5lib/treeadapters/genshi.py | 54 + .../pip/_vendor/html5lib/treeadapters/sax.py | 50 + .../_vendor/html5lib/treebuilders/__init__.py | 88 + .../__pycache__/__init__.cpython-36.pyc | Bin 0 -> 3323 bytes .../__pycache__/base.cpython-36.pyc | Bin 0 -> 11330 bytes .../__pycache__/dom.cpython-36.pyc | Bin 0 -> 9276 bytes .../__pycache__/etree.cpython-36.pyc | Bin 0 -> 11870 bytes .../__pycache__/etree_lxml.cpython-36.pyc | Bin 0 -> 11796 bytes .../pip/_vendor/html5lib/treebuilders/base.py | 417 + .../pip/_vendor/html5lib/treebuilders/dom.py | 236 + .../_vendor/html5lib/treebuilders/etree.py | 340 + .../html5lib/treebuilders/etree_lxml.py | 366 + .../_vendor/html5lib/treewalkers/__init__.py | 154 + .../__pycache__/__init__.cpython-36.pyc | Bin 0 -> 4010 bytes .../__pycache__/base.cpython-36.pyc | Bin 0 -> 6998 bytes .../__pycache__/dom.cpython-36.pyc | Bin 0 -> 1725 bytes .../__pycache__/etree.cpython-36.pyc | Bin 0 -> 3567 bytes .../__pycache__/etree_lxml.cpython-36.pyc | Bin 0 -> 6660 bytes .../__pycache__/genshi.cpython-36.pyc | Bin 0 -> 1899 bytes .../pip/_vendor/html5lib/treewalkers/base.py | 252 + .../pip/_vendor/html5lib/treewalkers/dom.py | 43 + .../pip/_vendor/html5lib/treewalkers/etree.py | 130 + .../html5lib/treewalkers/etree_lxml.py | 213 + .../_vendor/html5lib/treewalkers/genshi.py | 69 + .../pip/_vendor/idna/__init__.py | 2 + .../idna/__pycache__/__init__.cpython-36.pyc | Bin 0 -> 260 bytes .../idna/__pycache__/codec.cpython-36.pyc | Bin 0 -> 3107 bytes .../idna/__pycache__/compat.cpython-36.pyc | Bin 0 -> 620 bytes .../idna/__pycache__/core.cpython-36.pyc | Bin 0 -> 9160 bytes .../idna/__pycache__/idnadata.cpython-36.pyc | Bin 0 -> 29799 bytes .../idna/__pycache__/intranges.cpython-36.pyc | Bin 0 -> 1821 bytes .../__pycache__/package_data.cpython-36.pyc | Bin 0 -> 214 bytes .../idna/__pycache__/uts46data.cpython-36.pyc | Bin 0 -> 241809 bytes .../site-packages/pip/_vendor/idna/codec.py | 118 + .../site-packages/pip/_vendor/idna/compat.py | 12 + .../site-packages/pip/_vendor/idna/core.py | 396 + .../pip/_vendor/idna/idnadata.py | 1979 ++++ .../pip/_vendor/idna/intranges.py | 53 + .../pip/_vendor/idna/package_data.py | 2 + .../pip/_vendor/idna/uts46data.py | 8205 +++++++++++++++++ .../site-packages/pip/_vendor/ipaddress.py | 2419 +++++ .../pip/_vendor/lockfile/__init__.py | 347 + .../__pycache__/__init__.cpython-36.pyc | Bin 0 -> 9912 bytes .../__pycache__/linklockfile.cpython-36.pyc | Bin 0 -> 2291 bytes .../__pycache__/mkdirlockfile.cpython-36.pyc | Bin 0 -> 2653 bytes .../__pycache__/pidlockfile.cpython-36.pyc | Bin 0 -> 4853 bytes .../__pycache__/sqlitelockfile.cpython-36.pyc | Bin 0 -> 3752 bytes .../symlinklockfile.cpython-36.pyc | Bin 0 -> 2176 bytes .../pip/_vendor/lockfile/linklockfile.py | 73 + .../pip/_vendor/lockfile/mkdirlockfile.py | 84 + .../pip/_vendor/lockfile/pidlockfile.py | 190 + .../pip/_vendor/lockfile/sqlitelockfile.py | 156 + .../pip/_vendor/lockfile/symlinklockfile.py | 70 + .../pip/_vendor/msgpack/__init__.py | 66 + .../__pycache__/__init__.cpython-36.pyc | Bin 0 -> 2074 bytes .../__pycache__/_version.cpython-36.pyc | Bin 0 -> 236 bytes .../__pycache__/exceptions.cpython-36.pyc | Bin 0 -> 2177 bytes .../__pycache__/fallback.cpython-36.pyc | Bin 0 -> 24700 bytes .../pip/_vendor/msgpack/_version.py | 1 + .../pip/_vendor/msgpack/exceptions.py | 41 + .../pip/_vendor/msgpack/fallback.py | 977 ++ .../pip/_vendor/packaging/__about__.py | 27 + .../pip/_vendor/packaging/__init__.py | 26 + .../__pycache__/__about__.cpython-36.pyc | Bin 0 -> 734 bytes .../__pycache__/__init__.cpython-36.pyc | Bin 0 -> 572 bytes .../__pycache__/_compat.cpython-36.pyc | Bin 0 -> 1007 bytes .../__pycache__/_structures.cpython-36.pyc | Bin 0 -> 2864 bytes .../__pycache__/markers.cpython-36.pyc | Bin 0 -> 8882 bytes .../__pycache__/requirements.cpython-36.pyc | Bin 0 -> 3993 bytes .../__pycache__/specifiers.cpython-36.pyc | Bin 0 -> 19798 bytes .../__pycache__/utils.cpython-36.pyc | Bin 0 -> 1450 bytes .../__pycache__/version.cpython-36.pyc | Bin 0 -> 12003 bytes .../pip/_vendor/packaging/_compat.py | 31 + .../pip/_vendor/packaging/_structures.py | 68 + .../pip/_vendor/packaging/markers.py | 296 + .../pip/_vendor/packaging/requirements.py | 138 + .../pip/_vendor/packaging/specifiers.py | 749 ++ .../pip/_vendor/packaging/utils.py | 57 + .../pip/_vendor/packaging/version.py | 420 + .../pip/_vendor/pep517/__init__.py | 4 + .../__pycache__/__init__.cpython-36.pyc | Bin 0 -> 285 bytes .../__pycache__/_in_process.cpython-36.pyc | Bin 0 -> 5628 bytes .../pep517/__pycache__/build.cpython-36.pyc | Bin 0 -> 2767 bytes .../pep517/__pycache__/check.cpython-36.pyc | Bin 0 -> 4811 bytes .../__pycache__/colorlog.cpython-36.pyc | Bin 0 -> 2932 bytes .../pep517/__pycache__/compat.cpython-36.pyc | Bin 0 -> 1021 bytes .../__pycache__/envbuild.cpython-36.pyc | Bin 0 -> 4205 bytes .../__pycache__/wrappers.cpython-36.pyc | Bin 0 -> 5486 bytes .../pip/_vendor/pep517/_in_process.py | 207 + .../site-packages/pip/_vendor/pep517/build.py | 108 + .../site-packages/pip/_vendor/pep517/check.py | 202 + .../pip/_vendor/pep517/colorlog.py | 115 + .../pip/_vendor/pep517/compat.py | 23 + .../pip/_vendor/pep517/envbuild.py | 158 + .../pip/_vendor/pep517/wrappers.py | 163 + .../pip/_vendor/pkg_resources/__init__.py | 3171 +++++++ .../__pycache__/__init__.cpython-36.pyc | Bin 0 -> 96849 bytes .../__pycache__/py31compat.cpython-36.pyc | Bin 0 -> 662 bytes .../pip/_vendor/pkg_resources/py31compat.py | 23 + .../pip/_vendor/progress/__init__.py | 127 + .../__pycache__/__init__.cpython-36.pyc | Bin 0 -> 3913 bytes .../progress/__pycache__/bar.cpython-36.pyc | Bin 0 -> 2844 bytes .../__pycache__/counter.cpython-36.pyc | Bin 0 -> 1647 bytes .../__pycache__/helpers.cpython-36.pyc | Bin 0 -> 3019 bytes .../__pycache__/spinner.cpython-36.pyc | Bin 0 -> 1514 bytes .../site-packages/pip/_vendor/progress/bar.py | 94 + .../pip/_vendor/progress/counter.py | 48 + .../pip/_vendor/progress/helpers.py | 91 + .../pip/_vendor/progress/spinner.py | 44 + .../site-packages/pip/_vendor/pyparsing.py | 6452 +++++++++++++ .../pip/_vendor/pytoml/__init__.py | 4 + .../__pycache__/__init__.cpython-36.pyc | Bin 0 -> 379 bytes .../pytoml/__pycache__/core.cpython-36.pyc | Bin 0 -> 942 bytes .../pytoml/__pycache__/parser.cpython-36.pyc | Bin 0 -> 10084 bytes .../pytoml/__pycache__/test.cpython-36.pyc | Bin 0 -> 1242 bytes .../pytoml/__pycache__/utils.cpython-36.pyc | Bin 0 -> 2143 bytes .../pytoml/__pycache__/writer.cpython-36.pyc | Bin 0 -> 3571 bytes .../site-packages/pip/_vendor/pytoml/core.py | 13 + .../pip/_vendor/pytoml/parser.py | 341 + .../site-packages/pip/_vendor/pytoml/test.py | 30 + .../site-packages/pip/_vendor/pytoml/utils.py | 67 + .../pip/_vendor/pytoml/writer.py | 106 + .../pip/_vendor/requests/__init__.py | 133 + .../__pycache__/__init__.cpython-36.pyc | Bin 0 -> 3490 bytes .../__pycache__/__version__.cpython-36.pyc | Bin 0 -> 553 bytes .../_internal_utils.cpython-36.pyc | Bin 0 -> 1311 bytes .../__pycache__/adapters.cpython-36.pyc | Bin 0 -> 16902 bytes .../requests/__pycache__/api.cpython-36.pyc | Bin 0 -> 6494 bytes .../requests/__pycache__/auth.cpython-36.pyc | Bin 0 -> 8345 bytes .../requests/__pycache__/certs.cpython-36.pyc | Bin 0 -> 636 bytes .../__pycache__/compat.cpython-36.pyc | Bin 0 -> 1615 bytes .../__pycache__/cookies.cpython-36.pyc | Bin 0 -> 18790 bytes .../__pycache__/exceptions.cpython-36.pyc | Bin 0 -> 5510 bytes .../requests/__pycache__/help.cpython-36.pyc | Bin 0 -> 2689 bytes .../requests/__pycache__/hooks.cpython-36.pyc | Bin 0 -> 983 bytes .../__pycache__/models.cpython-36.pyc | Bin 0 -> 24165 bytes .../__pycache__/packages.cpython-36.pyc | Bin 0 -> 528 bytes .../__pycache__/sessions.cpython-36.pyc | Bin 0 -> 19429 bytes .../__pycache__/status_codes.cpython-36.pyc | Bin 0 -> 4781 bytes .../__pycache__/structures.cpython-36.pyc | Bin 0 -> 4382 bytes .../requests/__pycache__/utils.cpython-36.pyc | Bin 0 -> 22099 bytes .../pip/_vendor/requests/__version__.py | 14 + .../pip/_vendor/requests/_internal_utils.py | 42 + .../pip/_vendor/requests/adapters.py | 533 ++ .../site-packages/pip/_vendor/requests/api.py | 158 + .../pip/_vendor/requests/auth.py | 305 + .../pip/_vendor/requests/certs.py | 18 + .../pip/_vendor/requests/compat.py | 74 + .../pip/_vendor/requests/cookies.py | 549 ++ .../pip/_vendor/requests/exceptions.py | 126 + .../pip/_vendor/requests/help.py | 119 + .../pip/_vendor/requests/hooks.py | 34 + .../pip/_vendor/requests/models.py | 953 ++ .../pip/_vendor/requests/packages.py | 16 + .../pip/_vendor/requests/sessions.py | 770 ++ .../pip/_vendor/requests/status_codes.py | 120 + .../pip/_vendor/requests/structures.py | 103 + .../pip/_vendor/requests/utils.py | 977 ++ .../site-packages/pip/_vendor/retrying.py | 267 + .../site-packages/pip/_vendor/six.py | 952 ++ .../pip/_vendor/urllib3/__init__.py | 92 + .../__pycache__/__init__.cpython-36.pyc | Bin 0 -> 2204 bytes .../__pycache__/_collections.cpython-36.pyc | Bin 0 -> 10691 bytes .../__pycache__/connection.cpython-36.pyc | Bin 0 -> 10144 bytes .../__pycache__/connectionpool.cpython-36.pyc | Bin 0 -> 23666 bytes .../__pycache__/exceptions.cpython-36.pyc | Bin 0 -> 10403 bytes .../urllib3/__pycache__/fields.cpython-36.pyc | Bin 0 -> 5873 bytes .../__pycache__/filepost.cpython-36.pyc | Bin 0 -> 2763 bytes .../__pycache__/poolmanager.cpython-36.pyc | Bin 0 -> 12970 bytes .../__pycache__/request.cpython-36.pyc | Bin 0 -> 5585 bytes .../__pycache__/response.cpython-36.pyc | Bin 0 -> 18785 bytes .../pip/_vendor/urllib3/_collections.py | 329 + .../pip/_vendor/urllib3/connection.py | 391 + .../pip/_vendor/urllib3/connectionpool.py | 896 ++ .../pip/_vendor/urllib3/contrib/__init__.py | 0 .../__pycache__/__init__.cpython-36.pyc | Bin 0 -> 202 bytes .../_appengine_environ.cpython-36.pyc | Bin 0 -> 1098 bytes .../__pycache__/appengine.cpython-36.pyc | Bin 0 -> 8317 bytes .../__pycache__/ntlmpool.cpython-36.pyc | Bin 0 -> 3244 bytes .../__pycache__/pyopenssl.cpython-36.pyc | Bin 0 -> 14533 bytes .../securetransport.cpython-36.pyc | Bin 0 -> 17897 bytes .../contrib/__pycache__/socks.cpython-36.pyc | Bin 0 -> 4908 bytes .../urllib3/contrib/_appengine_environ.py | 30 + .../contrib/_securetransport/__init__.py | 0 .../__pycache__/__init__.cpython-36.pyc | Bin 0 -> 219 bytes .../__pycache__/bindings.cpython-36.pyc | Bin 0 -> 10434 bytes .../__pycache__/low_level.cpython-36.pyc | Bin 0 -> 7495 bytes .../contrib/_securetransport/bindings.py | 593 ++ .../contrib/_securetransport/low_level.py | 346 + .../pip/_vendor/urllib3/contrib/appengine.py | 289 + .../pip/_vendor/urllib3/contrib/ntlmpool.py | 111 + .../pip/_vendor/urllib3/contrib/pyopenssl.py | 466 + .../urllib3/contrib/securetransport.py | 804 ++ .../pip/_vendor/urllib3/contrib/socks.py | 192 + .../pip/_vendor/urllib3/exceptions.py | 246 + .../pip/_vendor/urllib3/fields.py | 178 + .../pip/_vendor/urllib3/filepost.py | 98 + .../pip/_vendor/urllib3/packages/__init__.py | 5 + .../__pycache__/__init__.cpython-36.pyc | Bin 0 -> 328 bytes .../packages/__pycache__/six.cpython-36.pyc | Bin 0 -> 24500 bytes .../urllib3/packages/backports/__init__.py | 0 .../__pycache__/__init__.cpython-36.pyc | Bin 0 -> 213 bytes .../__pycache__/makefile.cpython-36.pyc | Bin 0 -> 1307 bytes .../urllib3/packages/backports/makefile.py | 53 + .../pip/_vendor/urllib3/packages/six.py | 868 ++ .../packages/ssl_match_hostname/__init__.py | 19 + .../__pycache__/__init__.cpython-36.pyc | Bin 0 -> 589 bytes .../_implementation.cpython-36.pyc | Bin 0 -> 3316 bytes .../ssl_match_hostname/_implementation.py | 156 + .../pip/_vendor/urllib3/poolmanager.py | 450 + .../pip/_vendor/urllib3/request.py | 150 + .../pip/_vendor/urllib3/response.py | 705 ++ .../pip/_vendor/urllib3/util/__init__.py | 54 + .../util/__pycache__/__init__.cpython-36.pyc | Bin 0 -> 1132 bytes .../__pycache__/connection.cpython-36.pyc | Bin 0 -> 3169 bytes .../util/__pycache__/queue.cpython-36.pyc | Bin 0 -> 1043 bytes .../util/__pycache__/request.cpython-36.pyc | Bin 0 -> 3224 bytes .../util/__pycache__/response.cpython-36.pyc | Bin 0 -> 1972 bytes .../util/__pycache__/retry.cpython-36.pyc | Bin 0 -> 12658 bytes .../util/__pycache__/ssl_.cpython-36.pyc | Bin 0 -> 9562 bytes .../util/__pycache__/timeout.cpython-36.pyc | Bin 0 -> 8773 bytes .../util/__pycache__/url.cpython-36.pyc | Bin 0 -> 5192 bytes .../util/__pycache__/wait.cpython-36.pyc | Bin 0 -> 3153 bytes .../pip/_vendor/urllib3/util/connection.py | 134 + .../pip/_vendor/urllib3/util/queue.py | 21 + .../pip/_vendor/urllib3/util/request.py | 118 + .../pip/_vendor/urllib3/util/response.py | 87 + .../pip/_vendor/urllib3/util/retry.py | 411 + .../pip/_vendor/urllib3/util/ssl_.py | 381 + .../pip/_vendor/urllib3/util/timeout.py | 242 + .../pip/_vendor/urllib3/util/url.py | 230 + .../pip/_vendor/urllib3/util/wait.py | 150 + .../pip/_vendor/webencodings/__init__.py | 342 + .../__pycache__/__init__.cpython-36.pyc | Bin 0 -> 9680 bytes .../__pycache__/labels.cpython-36.pyc | Bin 0 -> 4092 bytes .../__pycache__/mklabels.cpython-36.pyc | Bin 0 -> 1914 bytes .../__pycache__/tests.cpython-36.pyc | Bin 0 -> 5070 bytes .../__pycache__/x_user_defined.cpython-36.pyc | Bin 0 -> 2667 bytes .../pip/_vendor/webencodings/labels.py | 231 + .../pip/_vendor/webencodings/mklabels.py | 59 + .../pip/_vendor/webencodings/tests.py | 153 + .../_vendor/webencodings/x_user_defined.py | 325 + .../site-packages/pkg_resources/__init__.py | 3051 ++++++ .../__pycache__/__init__.cpython-36.pyc | Bin 0 -> 95359 bytes .../pkg_resources/_vendor/__init__.py | 0 .../__pycache__/__init__.cpython-36.pyc | Bin 0 -> 203 bytes .../__pycache__/appdirs.cpython-36.pyc | Bin 0 -> 18629 bytes .../__pycache__/pyparsing.cpython-36.pyc | Bin 0 -> 201125 bytes .../_vendor/__pycache__/six.cpython-36.pyc | Bin 0 -> 24500 bytes .../pkg_resources/_vendor/appdirs.py | 552 ++ .../_vendor/packaging/__about__.py | 21 + .../_vendor/packaging/__init__.py | 14 + .../__pycache__/__about__.cpython-36.pyc | Bin 0 -> 739 bytes .../__pycache__/__init__.cpython-36.pyc | Bin 0 -> 577 bytes .../__pycache__/_compat.cpython-36.pyc | Bin 0 -> 1024 bytes .../__pycache__/_structures.cpython-36.pyc | Bin 0 -> 2881 bytes .../__pycache__/markers.cpython-36.pyc | Bin 0 -> 8043 bytes .../__pycache__/requirements.cpython-36.pyc | Bin 0 -> 3900 bytes .../__pycache__/specifiers.cpython-36.pyc | Bin 0 -> 19843 bytes .../__pycache__/utils.cpython-36.pyc | Bin 0 -> 508 bytes .../__pycache__/version.cpython-36.pyc | Bin 0 -> 10618 bytes .../_vendor/packaging/_compat.py | 30 + .../_vendor/packaging/_structures.py | 68 + .../_vendor/packaging/markers.py | 287 + .../_vendor/packaging/requirements.py | 127 + .../_vendor/packaging/specifiers.py | 774 ++ .../pkg_resources/_vendor/packaging/utils.py | 14 + .../_vendor/packaging/version.py | 393 + .../pkg_resources/_vendor/pyparsing.py | 5696 ++++++++++++ .../pkg_resources/_vendor/six.py | 868 ++ .../pkg_resources/extern/__init__.py | 73 + .../__pycache__/__init__.cpython-36.pyc | Bin 0 -> 2434 bytes .../DESCRIPTION.rst | 243 + .../setuptools-28.8.0.dist-info/INSTALLER | 1 + .../setuptools-28.8.0.dist-info/METADATA | 272 + .../setuptools-28.8.0.dist-info/RECORD | 143 + .../setuptools-28.8.0.dist-info/WHEEL | 6 + .../dependency_links.txt | 2 + .../entry_points.txt | 63 + .../setuptools-28.8.0.dist-info/metadata.json | 1 + .../setuptools-28.8.0.dist-info/top_level.txt | 3 + .../setuptools-28.8.0.dist-info/zip-safe | 1 + .../site-packages/setuptools/__init__.py | 160 + .../__pycache__/__init__.cpython-36.pyc | Bin 0 -> 5705 bytes .../__pycache__/archive_util.cpython-36.pyc | Bin 0 -> 5168 bytes .../__pycache__/depends.cpython-36.pyc | Bin 0 -> 5838 bytes .../__pycache__/dist.cpython-36.pyc | Bin 0 -> 32178 bytes .../__pycache__/extension.cpython-36.pyc | Bin 0 -> 1985 bytes .../__pycache__/glob.cpython-36.pyc | Bin 0 -> 3853 bytes .../__pycache__/launch.cpython-36.pyc | Bin 0 -> 864 bytes .../__pycache__/lib2to3_ex.cpython-36.pyc | Bin 0 -> 2443 bytes .../__pycache__/monkey.cpython-36.pyc | Bin 0 -> 4533 bytes .../__pycache__/msvc.cpython-36.pyc | Bin 0 -> 31286 bytes .../__pycache__/namespaces.cpython-36.pyc | Bin 0 -> 3201 bytes .../__pycache__/package_index.cpython-36.pyc | Bin 0 -> 32500 bytes .../__pycache__/py26compat.cpython-36.pyc | Bin 0 -> 1073 bytes .../__pycache__/py27compat.cpython-36.pyc | Bin 0 -> 622 bytes .../__pycache__/py31compat.cpython-36.pyc | Bin 0 -> 1903 bytes .../__pycache__/sandbox.cpython-36.pyc | Bin 0 -> 15543 bytes .../__pycache__/site-patch.cpython-36.pyc | Bin 0 -> 1516 bytes .../__pycache__/ssl_support.cpython-36.pyc | Bin 0 -> 6369 bytes .../__pycache__/unicode_utils.cpython-36.pyc | Bin 0 -> 1179 bytes .../__pycache__/version.cpython-36.pyc | Bin 0 -> 333 bytes .../windows_support.cpython-36.pyc | Bin 0 -> 1021 bytes .../site-packages/setuptools/archive_util.py | 173 + .../site-packages/setuptools/cli-32.exe | Bin 0 -> 65536 bytes .../site-packages/setuptools/cli-64.exe | Bin 0 -> 74752 bytes .../site-packages/setuptools/cli.exe | Bin 0 -> 65536 bytes .../setuptools/command/__init__.py | 17 + .../__pycache__/__init__.cpython-36.pyc | Bin 0 -> 722 bytes .../command/__pycache__/alias.cpython-36.pyc | Bin 0 -> 2444 bytes .../__pycache__/bdist_egg.cpython-36.pyc | Bin 0 -> 13674 bytes .../__pycache__/bdist_rpm.cpython-36.pyc | Bin 0 -> 1787 bytes .../__pycache__/bdist_wininst.cpython-36.pyc | Bin 0 -> 988 bytes .../__pycache__/build_ext.cpython-36.pyc | Bin 0 -> 10014 bytes .../__pycache__/build_py.cpython-36.pyc | Bin 0 -> 8583 bytes .../__pycache__/develop.cpython-36.pyc | Bin 0 -> 5900 bytes .../__pycache__/easy_install.cpython-36.pyc | Bin 0 -> 63994 bytes .../__pycache__/egg_info.cpython-36.pyc | Bin 0 -> 21067 bytes .../__pycache__/install.cpython-36.pyc | Bin 0 -> 3984 bytes .../install_egg_info.cpython-36.pyc | Bin 0 -> 2449 bytes .../__pycache__/install_lib.cpython-36.pyc | Bin 0 -> 4094 bytes .../install_scripts.cpython-36.pyc | Bin 0 -> 2289 bytes .../__pycache__/py36compat.cpython-36.pyc | Bin 0 -> 4634 bytes .../__pycache__/register.cpython-36.pyc | Bin 0 -> 604 bytes .../command/__pycache__/rotate.cpython-36.pyc | Bin 0 -> 2590 bytes .../__pycache__/saveopts.cpython-36.pyc | Bin 0 -> 935 bytes .../command/__pycache__/sdist.cpython-36.pyc | Bin 0 -> 6119 bytes .../command/__pycache__/setopt.cpython-36.pyc | Bin 0 -> 4613 bytes .../command/__pycache__/test.cpython-36.pyc | Bin 0 -> 7462 bytes .../command/__pycache__/upload.cpython-36.pyc | Bin 0 -> 1363 bytes .../__pycache__/upload_docs.cpython-36.pyc | Bin 0 -> 6032 bytes .../site-packages/setuptools/command/alias.py | 80 + .../setuptools/command/bdist_egg.py | 472 + .../setuptools/command/bdist_rpm.py | 43 + .../setuptools/command/bdist_wininst.py | 21 + .../setuptools/command/build_ext.py | 328 + .../setuptools/command/build_py.py | 270 + .../setuptools/command/develop.py | 197 + .../setuptools/command/easy_install.py | 2287 +++++ .../setuptools/command/egg_info.py | 697 ++ .../setuptools/command/install.py | 125 + .../setuptools/command/install_egg_info.py | 62 + .../setuptools/command/install_lib.py | 121 + .../setuptools/command/install_scripts.py | 65 + .../setuptools/command/launcher manifest.xml | 15 + .../setuptools/command/py36compat.py | 136 + .../setuptools/command/register.py | 10 + .../setuptools/command/rotate.py | 66 + .../setuptools/command/saveopts.py | 22 + .../site-packages/setuptools/command/sdist.py | 202 + .../setuptools/command/setopt.py | 149 + .../site-packages/setuptools/command/test.py | 247 + .../setuptools/command/upload.py | 38 + .../setuptools/command/upload_docs.py | 206 + .../site-packages/setuptools/depends.py | 217 + .../site-packages/setuptools/dist.py | 914 ++ .../site-packages/setuptools/extension.py | 57 + .../setuptools/extern/__init__.py | 4 + .../__pycache__/__init__.cpython-36.pyc | Bin 0 -> 343 bytes .../site-packages/setuptools/glob.py | 176 + .../site-packages/setuptools/gui-32.exe | Bin 0 -> 65536 bytes .../site-packages/setuptools/gui-64.exe | Bin 0 -> 75264 bytes .../site-packages/setuptools/gui.exe | Bin 0 -> 65536 bytes .../site-packages/setuptools/launch.py | 35 + .../site-packages/setuptools/lib2to3_ex.py | 62 + .../site-packages/setuptools/monkey.py | 186 + .../site-packages/setuptools/msvc.py | 1193 +++ .../site-packages/setuptools/namespaces.py | 93 + .../site-packages/setuptools/package_index.py | 1115 +++ .../site-packages/setuptools/py26compat.py | 31 + .../site-packages/setuptools/py27compat.py | 18 + .../site-packages/setuptools/py31compat.py | 56 + .../site-packages/setuptools/sandbox.py | 492 + .../setuptools/script (dev).tmpl | 5 + .../site-packages/setuptools/script.tmpl | 3 + .../site-packages/setuptools/site-patch.py | 74 + .../site-packages/setuptools/ssl_support.py | 250 + .../site-packages/setuptools/unicode_utils.py | 44 + .../site-packages/setuptools/version.py | 6 + .../setuptools/windows_support.py | 29 + .../site-packages/werkzeug/__init__.py | 151 + .../__pycache__/__init__.cpython-36.pyc | Bin 0 -> 4748 bytes .../__pycache__/_compat.cpython-36.pyc | Bin 0 -> 7151 bytes .../__pycache__/_internal.cpython-36.pyc | Bin 0 -> 12637 bytes .../__pycache__/_reloader.cpython-36.pyc | Bin 0 -> 8901 bytes .../__pycache__/datastructures.cpython-36.pyc | Bin 0 -> 100088 bytes .../__pycache__/exceptions.cpython-36.pyc | Bin 0 -> 22982 bytes .../__pycache__/filesystem.cpython-36.pyc | Bin 0 -> 2259 bytes .../__pycache__/formparser.cpython-36.pyc | Bin 0 -> 16205 bytes .../werkzeug/__pycache__/http.cpython-36.pyc | Bin 0 -> 33511 bytes .../werkzeug/__pycache__/local.cpython-36.pyc | Bin 0 -> 18728 bytes .../__pycache__/posixemulation.cpython-36.pyc | Bin 0 -> 2820 bytes .../__pycache__/routing.cpython-36.pyc | Bin 0 -> 60202 bytes .../__pycache__/script.cpython-36.pyc | Bin 0 -> 10118 bytes .../__pycache__/security.cpython-36.pyc | Bin 0 -> 8570 bytes .../__pycache__/serving.cpython-36.pyc | Bin 0 -> 26554 bytes .../werkzeug/__pycache__/test.cpython-36.pyc | Bin 0 -> 31088 bytes .../__pycache__/testapp.cpython-36.pyc | Bin 0 -> 9477 bytes .../werkzeug/__pycache__/urls.cpython-36.pyc | Bin 0 -> 33362 bytes .../__pycache__/useragents.cpython-36.pyc | Bin 0 -> 6094 bytes .../werkzeug/__pycache__/utils.cpython-36.pyc | Bin 0 -> 21215 bytes .../__pycache__/websocket.cpython-36.pyc | Bin 0 -> 8257 bytes .../__pycache__/wrappers.cpython-36.pyc | Bin 0 -> 76462 bytes .../werkzeug/__pycache__/wsgi.cpython-36.pyc | Bin 0 -> 44717 bytes .../site-packages/werkzeug/_compat.py | 206 + .../site-packages/werkzeug/_internal.py | 419 + .../site-packages/werkzeug/_reloader.py | 277 + .../werkzeug/contrib/__init__.py | 16 + .../__pycache__/__init__.cpython-36.pyc | Bin 0 -> 803 bytes .../contrib/__pycache__/atom.cpython-36.pyc | Bin 0 -> 14115 bytes .../contrib/__pycache__/cache.cpython-36.pyc | Bin 0 -> 32428 bytes .../contrib/__pycache__/fixers.cpython-36.pyc | Bin 0 -> 10120 bytes .../contrib/__pycache__/iterio.cpython-36.pyc | Bin 0 -> 11002 bytes .../__pycache__/jsrouting.cpython-36.pyc | Bin 0 -> 8311 bytes .../__pycache__/limiter.cpython-36.pyc | Bin 0 -> 1774 bytes .../contrib/__pycache__/lint.cpython-36.pyc | Bin 0 -> 11938 bytes .../__pycache__/profiler.cpython-36.pyc | Bin 0 -> 5300 bytes .../__pycache__/securecookie.cpython-36.pyc | Bin 0 -> 10352 bytes .../__pycache__/sessions.cpython-36.pyc | Bin 0 -> 12940 bytes .../__pycache__/testtools.cpython-36.pyc | Bin 0 -> 2686 bytes .../__pycache__/wrappers.cpython-36.pyc | Bin 0 -> 10431 bytes .../site-packages/werkzeug/contrib/atom.py | 355 + .../site-packages/werkzeug/contrib/cache.py | 913 ++ .../site-packages/werkzeug/contrib/fixers.py | 254 + .../site-packages/werkzeug/contrib/iterio.py | 352 + .../werkzeug/contrib/jsrouting.py | 264 + .../site-packages/werkzeug/contrib/limiter.py | 41 + .../site-packages/werkzeug/contrib/lint.py | 343 + .../werkzeug/contrib/profiler.py | 147 + .../werkzeug/contrib/securecookie.py | 323 + .../werkzeug/contrib/sessions.py | 352 + .../werkzeug/contrib/testtools.py | 73 + .../werkzeug/contrib/wrappers.py | 284 + .../site-packages/werkzeug/datastructures.py | 2762 ++++++ .../site-packages/werkzeug/debug/__init__.py | 470 + .../debug/__pycache__/__init__.cpython-36.pyc | Bin 0 -> 12763 bytes .../debug/__pycache__/console.cpython-36.pyc | Bin 0 -> 7377 bytes .../debug/__pycache__/repr.cpython-36.pyc | Bin 0 -> 8681 bytes .../debug/__pycache__/tbtools.cpython-36.pyc | Bin 0 -> 15699 bytes .../site-packages/werkzeug/debug/console.py | 215 + .../site-packages/werkzeug/debug/repr.py | 280 + .../werkzeug/debug/shared/FONT_LICENSE | 96 + .../werkzeug/debug/shared/console.png | Bin 0 -> 507 bytes .../werkzeug/debug/shared/debugger.js | 205 + .../werkzeug/debug/shared/jquery.js | 5 + .../werkzeug/debug/shared/less.png | Bin 0 -> 191 bytes .../werkzeug/debug/shared/more.png | Bin 0 -> 200 bytes .../werkzeug/debug/shared/source.png | Bin 0 -> 818 bytes .../werkzeug/debug/shared/style.css | 143 + .../werkzeug/debug/shared/ubuntu.ttf | Bin 0 -> 70220 bytes .../site-packages/werkzeug/debug/tbtools.py | 556 ++ .../site-packages/werkzeug/exceptions.py | 719 ++ .../site-packages/werkzeug/filesystem.py | 66 + .../site-packages/werkzeug/formparser.py | 534 ++ .../python3.6/site-packages/werkzeug/http.py | 1158 +++ .../python3.6/site-packages/werkzeug/local.py | 420 + .../site-packages/werkzeug/posixemulation.py | 106 + .../site-packages/werkzeug/routing.py | 1792 ++++ .../site-packages/werkzeug/script.py | 318 + .../site-packages/werkzeug/security.py | 270 + .../site-packages/werkzeug/serving.py | 862 ++ .../python3.6/site-packages/werkzeug/test.py | 948 ++ .../site-packages/werkzeug/testapp.py | 230 + .../python3.6/site-packages/werkzeug/urls.py | 1007 ++ .../site-packages/werkzeug/useragents.py | 212 + .../python3.6/site-packages/werkzeug/utils.py | 628 ++ .../site-packages/werkzeug/websocket.py | 337 + .../site-packages/werkzeug/wrappers.py | 2028 ++++ .../python3.6/site-packages/werkzeug/wsgi.py | 1364 +++ flask/venv/pip-selfcheck.json | 1 + flask/venv/pyvenv.cfg | 3 + gerrit/gerrit.py | 279 + gitlab/git.py | 672 ++ gitlab_api/gitlab.cfg => gitlab/gl.cfg | 0 gitlab_api/git.py | 368 - mysite/manage.py | 15 + mysite/mysite/__init__.py | 0 .../__pycache__/__init__.cpython-36.pyc | Bin 0 -> 145 bytes .../__pycache__/settings.cpython-36.pyc | Bin 0 -> 2341 bytes mysite/mysite/__pycache__/urls.cpython-36.pyc | Bin 0 -> 971 bytes mysite/mysite/__pycache__/wsgi.cpython-36.pyc | Bin 0 -> 546 bytes mysite/mysite/settings.py | 129 + mysite/mysite/urls.py | 22 + mysite/mysite/wsgi.py | 16 + mysite/polls/__init__.py | 0 .../polls/__pycache__/__init__.cpython-36.pyc | Bin 0 -> 144 bytes mysite/polls/__pycache__/admin.cpython-36.pyc | Bin 0 -> 273 bytes mysite/polls/__pycache__/apps.cpython-36.pyc | Bin 0 -> 358 bytes .../polls/__pycache__/models.cpython-36.pyc | Bin 0 -> 1270 bytes mysite/polls/__pycache__/urls.cpython-36.pyc | Bin 0 -> 345 bytes mysite/polls/__pycache__/views.cpython-36.pyc | Bin 0 -> 1327 bytes mysite/polls/admin.py | 8 + mysite/polls/apps.py | 5 + mysite/polls/models.py | 26 + mysite/polls/templates/polls/detail.html | 20 +- mysite/polls/templates/polls/index.html | 19 +- mysite/polls/urls.py | 11 + mysite/polls/views.py | 46 + mysql/mysql-crud.py | 33 +- nexus3/download_asset_from_url.py | 46 + nexus3/get_components_from_repo.py | 66 + nexus3/get_rs_gav_from_url.py | 39 + nexus3/get_ss_url_from_release_gav.py | 63 + shell/etcd/etcd.conf | 17 + shell/etcd/etcd.service | 29 + shell/etcd/generate_ca.sh | 129 + shell/etcd/install_cfssl.sh | 19 + shell/etcd/install_etcd.sh | 15 + shell/etcd/start_etcd_service.sh | 57 + shell/nexus/upload-aar.sh | 37 + shell/nexus/upload-jar.sh | 40 + web/web1.py | 60 +- web/web2.py | 101 + 1112 files changed, 186368 insertions(+), 407 deletions(-) create mode 100644 cmdb/cmdb.py create mode 100644 flask/app.py create mode 100644 flask/demo/__init__.py create mode 100644 flask/demo/__pycache__/demo.cpython-36.pyc create mode 100644 flask/demo/config.py create mode 100644 flask/demo/demo.py create mode 100644 flask/templates/hello.html create mode 100644 flask/templates/page_not_found.html create mode 100644 flask/venv/bin/activate create mode 100644 flask/venv/bin/activate.csh create mode 100644 flask/venv/bin/activate.fish create mode 100755 flask/venv/bin/easy_install create mode 100755 flask/venv/bin/easy_install-3.6 create mode 100755 flask/venv/bin/flask create mode 100755 flask/venv/bin/pip create mode 100755 flask/venv/bin/pip3 create mode 100755 flask/venv/bin/pip3.6 create mode 120000 flask/venv/bin/python create mode 120000 flask/venv/bin/python3 create mode 100644 flask/venv/lib/python3.6/site-packages/Click-7.0.dist-info/INSTALLER create mode 100644 flask/venv/lib/python3.6/site-packages/Click-7.0.dist-info/LICENSE.txt create mode 100644 flask/venv/lib/python3.6/site-packages/Click-7.0.dist-info/METADATA create mode 100644 flask/venv/lib/python3.6/site-packages/Click-7.0.dist-info/RECORD create mode 100644 flask/venv/lib/python3.6/site-packages/Click-7.0.dist-info/WHEEL create mode 100644 flask/venv/lib/python3.6/site-packages/Click-7.0.dist-info/top_level.txt create mode 100644 flask/venv/lib/python3.6/site-packages/Flask-1.0.2.dist-info/INSTALLER create mode 100644 flask/venv/lib/python3.6/site-packages/Flask-1.0.2.dist-info/LICENSE.txt create mode 100644 flask/venv/lib/python3.6/site-packages/Flask-1.0.2.dist-info/METADATA create mode 100644 flask/venv/lib/python3.6/site-packages/Flask-1.0.2.dist-info/RECORD create mode 100644 flask/venv/lib/python3.6/site-packages/Flask-1.0.2.dist-info/WHEEL create mode 100644 flask/venv/lib/python3.6/site-packages/Flask-1.0.2.dist-info/entry_points.txt create mode 100644 flask/venv/lib/python3.6/site-packages/Flask-1.0.2.dist-info/top_level.txt create mode 100644 flask/venv/lib/python3.6/site-packages/Jinja2-2.10.dist-info/DESCRIPTION.rst create mode 100644 flask/venv/lib/python3.6/site-packages/Jinja2-2.10.dist-info/INSTALLER create mode 100644 flask/venv/lib/python3.6/site-packages/Jinja2-2.10.dist-info/LICENSE.txt create mode 100644 flask/venv/lib/python3.6/site-packages/Jinja2-2.10.dist-info/METADATA create mode 100644 flask/venv/lib/python3.6/site-packages/Jinja2-2.10.dist-info/RECORD create mode 100644 flask/venv/lib/python3.6/site-packages/Jinja2-2.10.dist-info/WHEEL create mode 100644 flask/venv/lib/python3.6/site-packages/Jinja2-2.10.dist-info/entry_points.txt create mode 100644 flask/venv/lib/python3.6/site-packages/Jinja2-2.10.dist-info/metadata.json create mode 100644 flask/venv/lib/python3.6/site-packages/Jinja2-2.10.dist-info/top_level.txt create mode 100644 flask/venv/lib/python3.6/site-packages/MarkupSafe-1.1.1.dist-info/INSTALLER create mode 100644 flask/venv/lib/python3.6/site-packages/MarkupSafe-1.1.1.dist-info/LICENSE.rst create mode 100644 flask/venv/lib/python3.6/site-packages/MarkupSafe-1.1.1.dist-info/METADATA create mode 100644 flask/venv/lib/python3.6/site-packages/MarkupSafe-1.1.1.dist-info/RECORD create mode 100644 flask/venv/lib/python3.6/site-packages/MarkupSafe-1.1.1.dist-info/WHEEL create mode 100644 flask/venv/lib/python3.6/site-packages/MarkupSafe-1.1.1.dist-info/top_level.txt create mode 100644 flask/venv/lib/python3.6/site-packages/Werkzeug-0.14.1.dist-info/DESCRIPTION.rst create mode 100644 flask/venv/lib/python3.6/site-packages/Werkzeug-0.14.1.dist-info/INSTALLER create mode 100644 flask/venv/lib/python3.6/site-packages/Werkzeug-0.14.1.dist-info/LICENSE.txt create mode 100644 flask/venv/lib/python3.6/site-packages/Werkzeug-0.14.1.dist-info/METADATA create mode 100644 flask/venv/lib/python3.6/site-packages/Werkzeug-0.14.1.dist-info/RECORD create mode 100644 flask/venv/lib/python3.6/site-packages/Werkzeug-0.14.1.dist-info/WHEEL create mode 100644 flask/venv/lib/python3.6/site-packages/Werkzeug-0.14.1.dist-info/metadata.json create mode 100644 flask/venv/lib/python3.6/site-packages/Werkzeug-0.14.1.dist-info/top_level.txt create mode 100644 flask/venv/lib/python3.6/site-packages/__pycache__/easy_install.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/click/__init__.py create mode 100644 flask/venv/lib/python3.6/site-packages/click/__pycache__/__init__.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/click/__pycache__/_bashcomplete.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/click/__pycache__/_compat.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/click/__pycache__/_termui_impl.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/click/__pycache__/_textwrap.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/click/__pycache__/_unicodefun.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/click/__pycache__/_winconsole.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/click/__pycache__/core.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/click/__pycache__/decorators.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/click/__pycache__/exceptions.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/click/__pycache__/formatting.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/click/__pycache__/globals.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/click/__pycache__/parser.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/click/__pycache__/termui.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/click/__pycache__/testing.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/click/__pycache__/types.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/click/__pycache__/utils.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/click/_bashcomplete.py create mode 100644 flask/venv/lib/python3.6/site-packages/click/_compat.py create mode 100644 flask/venv/lib/python3.6/site-packages/click/_termui_impl.py create mode 100644 flask/venv/lib/python3.6/site-packages/click/_textwrap.py create mode 100644 flask/venv/lib/python3.6/site-packages/click/_unicodefun.py create mode 100644 flask/venv/lib/python3.6/site-packages/click/_winconsole.py create mode 100644 flask/venv/lib/python3.6/site-packages/click/core.py create mode 100644 flask/venv/lib/python3.6/site-packages/click/decorators.py create mode 100644 flask/venv/lib/python3.6/site-packages/click/exceptions.py create mode 100644 flask/venv/lib/python3.6/site-packages/click/formatting.py create mode 100644 flask/venv/lib/python3.6/site-packages/click/globals.py create mode 100644 flask/venv/lib/python3.6/site-packages/click/parser.py create mode 100644 flask/venv/lib/python3.6/site-packages/click/termui.py create mode 100644 flask/venv/lib/python3.6/site-packages/click/testing.py create mode 100644 flask/venv/lib/python3.6/site-packages/click/types.py create mode 100644 flask/venv/lib/python3.6/site-packages/click/utils.py create mode 100644 flask/venv/lib/python3.6/site-packages/easy_install.py create mode 100644 flask/venv/lib/python3.6/site-packages/flask/__init__.py create mode 100644 flask/venv/lib/python3.6/site-packages/flask/__main__.py create mode 100644 flask/venv/lib/python3.6/site-packages/flask/__pycache__/__init__.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/flask/__pycache__/__main__.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/flask/__pycache__/_compat.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/flask/__pycache__/app.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/flask/__pycache__/blueprints.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/flask/__pycache__/cli.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/flask/__pycache__/config.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/flask/__pycache__/ctx.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/flask/__pycache__/debughelpers.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/flask/__pycache__/globals.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/flask/__pycache__/helpers.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/flask/__pycache__/logging.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/flask/__pycache__/sessions.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/flask/__pycache__/signals.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/flask/__pycache__/templating.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/flask/__pycache__/testing.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/flask/__pycache__/views.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/flask/__pycache__/wrappers.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/flask/_compat.py create mode 100644 flask/venv/lib/python3.6/site-packages/flask/app.py create mode 100644 flask/venv/lib/python3.6/site-packages/flask/blueprints.py create mode 100644 flask/venv/lib/python3.6/site-packages/flask/cli.py create mode 100644 flask/venv/lib/python3.6/site-packages/flask/config.py create mode 100644 flask/venv/lib/python3.6/site-packages/flask/ctx.py create mode 100644 flask/venv/lib/python3.6/site-packages/flask/debughelpers.py create mode 100644 flask/venv/lib/python3.6/site-packages/flask/globals.py create mode 100644 flask/venv/lib/python3.6/site-packages/flask/helpers.py create mode 100644 flask/venv/lib/python3.6/site-packages/flask/json/__init__.py create mode 100644 flask/venv/lib/python3.6/site-packages/flask/json/__pycache__/__init__.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/flask/json/__pycache__/tag.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/flask/json/tag.py create mode 100644 flask/venv/lib/python3.6/site-packages/flask/logging.py create mode 100644 flask/venv/lib/python3.6/site-packages/flask/sessions.py create mode 100644 flask/venv/lib/python3.6/site-packages/flask/signals.py create mode 100644 flask/venv/lib/python3.6/site-packages/flask/templating.py create mode 100644 flask/venv/lib/python3.6/site-packages/flask/testing.py create mode 100644 flask/venv/lib/python3.6/site-packages/flask/views.py create mode 100644 flask/venv/lib/python3.6/site-packages/flask/wrappers.py create mode 100644 flask/venv/lib/python3.6/site-packages/itsdangerous-1.1.0.dist-info/INSTALLER create mode 100644 flask/venv/lib/python3.6/site-packages/itsdangerous-1.1.0.dist-info/LICENSE.rst create mode 100644 flask/venv/lib/python3.6/site-packages/itsdangerous-1.1.0.dist-info/METADATA create mode 100644 flask/venv/lib/python3.6/site-packages/itsdangerous-1.1.0.dist-info/RECORD create mode 100644 flask/venv/lib/python3.6/site-packages/itsdangerous-1.1.0.dist-info/WHEEL create mode 100644 flask/venv/lib/python3.6/site-packages/itsdangerous-1.1.0.dist-info/top_level.txt create mode 100644 flask/venv/lib/python3.6/site-packages/itsdangerous/__init__.py create mode 100644 flask/venv/lib/python3.6/site-packages/itsdangerous/__pycache__/__init__.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/itsdangerous/__pycache__/_compat.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/itsdangerous/__pycache__/_json.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/itsdangerous/__pycache__/encoding.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/itsdangerous/__pycache__/exc.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/itsdangerous/__pycache__/jws.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/itsdangerous/__pycache__/serializer.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/itsdangerous/__pycache__/signer.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/itsdangerous/__pycache__/timed.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/itsdangerous/__pycache__/url_safe.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/itsdangerous/_compat.py create mode 100644 flask/venv/lib/python3.6/site-packages/itsdangerous/_json.py create mode 100644 flask/venv/lib/python3.6/site-packages/itsdangerous/encoding.py create mode 100644 flask/venv/lib/python3.6/site-packages/itsdangerous/exc.py create mode 100644 flask/venv/lib/python3.6/site-packages/itsdangerous/jws.py create mode 100644 flask/venv/lib/python3.6/site-packages/itsdangerous/serializer.py create mode 100644 flask/venv/lib/python3.6/site-packages/itsdangerous/signer.py create mode 100644 flask/venv/lib/python3.6/site-packages/itsdangerous/timed.py create mode 100644 flask/venv/lib/python3.6/site-packages/itsdangerous/url_safe.py create mode 100644 flask/venv/lib/python3.6/site-packages/jinja2/__init__.py create mode 100644 flask/venv/lib/python3.6/site-packages/jinja2/__pycache__/__init__.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/jinja2/__pycache__/_compat.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/jinja2/__pycache__/_identifier.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/jinja2/__pycache__/asyncfilters.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/jinja2/__pycache__/asyncsupport.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/jinja2/__pycache__/bccache.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/jinja2/__pycache__/compiler.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/jinja2/__pycache__/constants.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/jinja2/__pycache__/debug.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/jinja2/__pycache__/defaults.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/jinja2/__pycache__/environment.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/jinja2/__pycache__/exceptions.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/jinja2/__pycache__/ext.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/jinja2/__pycache__/filters.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/jinja2/__pycache__/idtracking.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/jinja2/__pycache__/lexer.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/jinja2/__pycache__/loaders.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/jinja2/__pycache__/meta.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/jinja2/__pycache__/nativetypes.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/jinja2/__pycache__/nodes.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/jinja2/__pycache__/optimizer.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/jinja2/__pycache__/parser.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/jinja2/__pycache__/runtime.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/jinja2/__pycache__/sandbox.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/jinja2/__pycache__/tests.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/jinja2/__pycache__/utils.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/jinja2/__pycache__/visitor.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/jinja2/_compat.py create mode 100644 flask/venv/lib/python3.6/site-packages/jinja2/_identifier.py create mode 100644 flask/venv/lib/python3.6/site-packages/jinja2/asyncfilters.py create mode 100644 flask/venv/lib/python3.6/site-packages/jinja2/asyncsupport.py create mode 100644 flask/venv/lib/python3.6/site-packages/jinja2/bccache.py create mode 100644 flask/venv/lib/python3.6/site-packages/jinja2/compiler.py create mode 100644 flask/venv/lib/python3.6/site-packages/jinja2/constants.py create mode 100644 flask/venv/lib/python3.6/site-packages/jinja2/debug.py create mode 100644 flask/venv/lib/python3.6/site-packages/jinja2/defaults.py create mode 100644 flask/venv/lib/python3.6/site-packages/jinja2/environment.py create mode 100644 flask/venv/lib/python3.6/site-packages/jinja2/exceptions.py create mode 100644 flask/venv/lib/python3.6/site-packages/jinja2/ext.py create mode 100644 flask/venv/lib/python3.6/site-packages/jinja2/filters.py create mode 100644 flask/venv/lib/python3.6/site-packages/jinja2/idtracking.py create mode 100644 flask/venv/lib/python3.6/site-packages/jinja2/lexer.py create mode 100644 flask/venv/lib/python3.6/site-packages/jinja2/loaders.py create mode 100644 flask/venv/lib/python3.6/site-packages/jinja2/meta.py create mode 100644 flask/venv/lib/python3.6/site-packages/jinja2/nativetypes.py create mode 100644 flask/venv/lib/python3.6/site-packages/jinja2/nodes.py create mode 100644 flask/venv/lib/python3.6/site-packages/jinja2/optimizer.py create mode 100644 flask/venv/lib/python3.6/site-packages/jinja2/parser.py create mode 100644 flask/venv/lib/python3.6/site-packages/jinja2/runtime.py create mode 100644 flask/venv/lib/python3.6/site-packages/jinja2/sandbox.py create mode 100644 flask/venv/lib/python3.6/site-packages/jinja2/tests.py create mode 100644 flask/venv/lib/python3.6/site-packages/jinja2/utils.py create mode 100644 flask/venv/lib/python3.6/site-packages/jinja2/visitor.py create mode 100644 flask/venv/lib/python3.6/site-packages/markupsafe/__init__.py create mode 100644 flask/venv/lib/python3.6/site-packages/markupsafe/__pycache__/__init__.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/markupsafe/__pycache__/_compat.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/markupsafe/__pycache__/_constants.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/markupsafe/__pycache__/_native.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/markupsafe/_compat.py create mode 100644 flask/venv/lib/python3.6/site-packages/markupsafe/_constants.py create mode 100644 flask/venv/lib/python3.6/site-packages/markupsafe/_native.py create mode 100644 flask/venv/lib/python3.6/site-packages/markupsafe/_speedups.c create mode 100644 flask/venv/lib/python3.6/site-packages/markupsafe/_speedups.cpython-36m-darwin.so create mode 100644 flask/venv/lib/python3.6/site-packages/pip-19.0.3.dist-info/INSTALLER create mode 100644 flask/venv/lib/python3.6/site-packages/pip-19.0.3.dist-info/LICENSE.txt create mode 100644 flask/venv/lib/python3.6/site-packages/pip-19.0.3.dist-info/METADATA create mode 100644 flask/venv/lib/python3.6/site-packages/pip-19.0.3.dist-info/RECORD create mode 100644 flask/venv/lib/python3.6/site-packages/pip-19.0.3.dist-info/WHEEL create mode 100644 flask/venv/lib/python3.6/site-packages/pip-19.0.3.dist-info/entry_points.txt create mode 100644 flask/venv/lib/python3.6/site-packages/pip-19.0.3.dist-info/top_level.txt create mode 100644 flask/venv/lib/python3.6/site-packages/pip/__init__.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/__main__.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/__pycache__/__init__.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/__pycache__/__main__.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_internal/__init__.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_internal/__pycache__/__init__.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_internal/__pycache__/build_env.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_internal/__pycache__/cache.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_internal/__pycache__/configuration.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_internal/__pycache__/download.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_internal/__pycache__/exceptions.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_internal/__pycache__/index.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_internal/__pycache__/locations.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_internal/__pycache__/pep425tags.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_internal/__pycache__/pyproject.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_internal/__pycache__/resolve.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_internal/__pycache__/wheel.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_internal/build_env.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_internal/cache.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_internal/cli/__init__.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_internal/cli/__pycache__/__init__.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_internal/cli/__pycache__/autocompletion.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_internal/cli/__pycache__/base_command.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_internal/cli/__pycache__/cmdoptions.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_internal/cli/__pycache__/main_parser.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_internal/cli/__pycache__/parser.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_internal/cli/__pycache__/status_codes.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_internal/cli/autocompletion.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_internal/cli/base_command.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_internal/cli/cmdoptions.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_internal/cli/main_parser.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_internal/cli/parser.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_internal/cli/status_codes.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_internal/commands/__init__.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_internal/commands/__pycache__/__init__.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_internal/commands/__pycache__/check.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_internal/commands/__pycache__/completion.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_internal/commands/__pycache__/configuration.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_internal/commands/__pycache__/download.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_internal/commands/__pycache__/freeze.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_internal/commands/__pycache__/hash.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_internal/commands/__pycache__/help.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_internal/commands/__pycache__/install.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_internal/commands/__pycache__/list.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_internal/commands/__pycache__/search.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_internal/commands/__pycache__/show.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_internal/commands/__pycache__/uninstall.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_internal/commands/__pycache__/wheel.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_internal/commands/check.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_internal/commands/completion.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_internal/commands/configuration.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_internal/commands/download.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_internal/commands/freeze.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_internal/commands/hash.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_internal/commands/help.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_internal/commands/install.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_internal/commands/list.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_internal/commands/search.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_internal/commands/show.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_internal/commands/uninstall.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_internal/commands/wheel.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_internal/configuration.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_internal/download.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_internal/exceptions.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_internal/index.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_internal/locations.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_internal/models/__init__.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_internal/models/__pycache__/__init__.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_internal/models/__pycache__/candidate.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_internal/models/__pycache__/format_control.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_internal/models/__pycache__/index.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_internal/models/__pycache__/link.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_internal/models/candidate.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_internal/models/format_control.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_internal/models/index.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_internal/models/link.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_internal/operations/__init__.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_internal/operations/__pycache__/__init__.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_internal/operations/__pycache__/check.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_internal/operations/__pycache__/freeze.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_internal/operations/__pycache__/prepare.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_internal/operations/check.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_internal/operations/freeze.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_internal/operations/prepare.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_internal/pep425tags.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_internal/pyproject.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_internal/req/__init__.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_internal/req/__pycache__/__init__.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_internal/req/__pycache__/constructors.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_internal/req/__pycache__/req_file.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_internal/req/__pycache__/req_install.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_internal/req/__pycache__/req_set.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_internal/req/__pycache__/req_tracker.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_internal/req/__pycache__/req_uninstall.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_internal/req/constructors.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_internal/req/req_file.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_internal/req/req_install.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_internal/req/req_set.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_internal/req/req_tracker.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_internal/req/req_uninstall.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_internal/resolve.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_internal/utils/__init__.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_internal/utils/__pycache__/__init__.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_internal/utils/__pycache__/appdirs.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_internal/utils/__pycache__/compat.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_internal/utils/__pycache__/deprecation.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_internal/utils/__pycache__/encoding.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_internal/utils/__pycache__/filesystem.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_internal/utils/__pycache__/glibc.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_internal/utils/__pycache__/hashes.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_internal/utils/__pycache__/logging.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_internal/utils/__pycache__/misc.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_internal/utils/__pycache__/models.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_internal/utils/__pycache__/outdated.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_internal/utils/__pycache__/packaging.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_internal/utils/__pycache__/setuptools_build.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_internal/utils/__pycache__/temp_dir.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_internal/utils/__pycache__/typing.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_internal/utils/__pycache__/ui.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_internal/utils/appdirs.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_internal/utils/compat.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_internal/utils/deprecation.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_internal/utils/encoding.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_internal/utils/filesystem.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_internal/utils/glibc.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_internal/utils/hashes.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_internal/utils/logging.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_internal/utils/misc.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_internal/utils/models.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_internal/utils/outdated.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_internal/utils/packaging.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_internal/utils/setuptools_build.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_internal/utils/temp_dir.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_internal/utils/typing.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_internal/utils/ui.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_internal/vcs/__init__.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_internal/vcs/__pycache__/__init__.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_internal/vcs/__pycache__/bazaar.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_internal/vcs/__pycache__/git.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_internal/vcs/__pycache__/mercurial.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_internal/vcs/__pycache__/subversion.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_internal/vcs/bazaar.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_internal/vcs/git.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_internal/vcs/mercurial.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_internal/vcs/subversion.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_internal/wheel.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/__init__.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/__pycache__/__init__.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/__pycache__/appdirs.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/__pycache__/distro.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/__pycache__/ipaddress.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/__pycache__/pyparsing.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/__pycache__/retrying.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/__pycache__/six.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/appdirs.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/cachecontrol/__init__.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/cachecontrol/__pycache__/__init__.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/cachecontrol/__pycache__/_cmd.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/cachecontrol/__pycache__/adapter.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/cachecontrol/__pycache__/cache.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/cachecontrol/__pycache__/compat.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/cachecontrol/__pycache__/controller.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/cachecontrol/__pycache__/filewrapper.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/cachecontrol/__pycache__/heuristics.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/cachecontrol/__pycache__/serialize.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/cachecontrol/__pycache__/wrapper.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/cachecontrol/_cmd.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/cachecontrol/adapter.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/cachecontrol/cache.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/cachecontrol/caches/__init__.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/cachecontrol/caches/__pycache__/__init__.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/cachecontrol/caches/__pycache__/file_cache.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/cachecontrol/caches/__pycache__/redis_cache.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/cachecontrol/caches/file_cache.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/cachecontrol/caches/redis_cache.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/cachecontrol/compat.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/cachecontrol/controller.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/cachecontrol/filewrapper.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/cachecontrol/heuristics.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/cachecontrol/serialize.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/cachecontrol/wrapper.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/certifi/__init__.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/certifi/__main__.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/certifi/__pycache__/__init__.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/certifi/__pycache__/__main__.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/certifi/__pycache__/core.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/certifi/cacert.pem create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/certifi/core.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/chardet/__init__.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/chardet/__pycache__/__init__.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/chardet/__pycache__/big5freq.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/chardet/__pycache__/big5prober.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/chardet/__pycache__/chardistribution.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/chardet/__pycache__/charsetgroupprober.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/chardet/__pycache__/charsetprober.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/chardet/__pycache__/codingstatemachine.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/chardet/__pycache__/compat.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/chardet/__pycache__/cp949prober.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/chardet/__pycache__/enums.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/chardet/__pycache__/escprober.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/chardet/__pycache__/escsm.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/chardet/__pycache__/eucjpprober.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/chardet/__pycache__/euckrfreq.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/chardet/__pycache__/euckrprober.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/chardet/__pycache__/euctwfreq.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/chardet/__pycache__/euctwprober.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/chardet/__pycache__/gb2312freq.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/chardet/__pycache__/gb2312prober.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/chardet/__pycache__/hebrewprober.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/chardet/__pycache__/jisfreq.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/chardet/__pycache__/jpcntx.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/chardet/__pycache__/langbulgarianmodel.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/chardet/__pycache__/langcyrillicmodel.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/chardet/__pycache__/langgreekmodel.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/chardet/__pycache__/langhebrewmodel.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/chardet/__pycache__/langhungarianmodel.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/chardet/__pycache__/langthaimodel.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/chardet/__pycache__/langturkishmodel.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/chardet/__pycache__/latin1prober.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/chardet/__pycache__/mbcharsetprober.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/chardet/__pycache__/mbcsgroupprober.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/chardet/__pycache__/mbcssm.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/chardet/__pycache__/sbcharsetprober.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/chardet/__pycache__/sbcsgroupprober.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/chardet/__pycache__/sjisprober.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/chardet/__pycache__/universaldetector.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/chardet/__pycache__/utf8prober.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/chardet/__pycache__/version.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/chardet/big5freq.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/chardet/big5prober.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/chardet/chardistribution.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/chardet/charsetgroupprober.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/chardet/charsetprober.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/chardet/cli/__init__.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/chardet/cli/__pycache__/__init__.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/chardet/cli/__pycache__/chardetect.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/chardet/cli/chardetect.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/chardet/codingstatemachine.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/chardet/compat.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/chardet/cp949prober.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/chardet/enums.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/chardet/escprober.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/chardet/escsm.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/chardet/eucjpprober.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/chardet/euckrfreq.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/chardet/euckrprober.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/chardet/euctwfreq.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/chardet/euctwprober.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/chardet/gb2312freq.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/chardet/gb2312prober.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/chardet/hebrewprober.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/chardet/jisfreq.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/chardet/jpcntx.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/chardet/langbulgarianmodel.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/chardet/langcyrillicmodel.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/chardet/langgreekmodel.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/chardet/langhebrewmodel.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/chardet/langhungarianmodel.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/chardet/langthaimodel.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/chardet/langturkishmodel.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/chardet/latin1prober.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/chardet/mbcharsetprober.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/chardet/mbcsgroupprober.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/chardet/mbcssm.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/chardet/sbcharsetprober.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/chardet/sbcsgroupprober.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/chardet/sjisprober.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/chardet/universaldetector.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/chardet/utf8prober.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/chardet/version.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/colorama/__init__.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/colorama/__pycache__/__init__.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/colorama/__pycache__/ansi.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/colorama/__pycache__/ansitowin32.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/colorama/__pycache__/initialise.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/colorama/__pycache__/win32.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/colorama/__pycache__/winterm.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/colorama/ansi.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/colorama/ansitowin32.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/colorama/initialise.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/colorama/win32.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/colorama/winterm.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/distlib/__init__.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/distlib/__pycache__/__init__.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/distlib/__pycache__/compat.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/distlib/__pycache__/database.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/distlib/__pycache__/index.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/distlib/__pycache__/locators.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/distlib/__pycache__/manifest.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/distlib/__pycache__/markers.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/distlib/__pycache__/metadata.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/distlib/__pycache__/resources.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/distlib/__pycache__/scripts.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/distlib/__pycache__/util.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/distlib/__pycache__/version.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/distlib/__pycache__/wheel.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/distlib/_backport/__init__.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/distlib/_backport/__pycache__/__init__.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/distlib/_backport/__pycache__/misc.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/distlib/_backport/__pycache__/shutil.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/distlib/_backport/__pycache__/sysconfig.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/distlib/_backport/__pycache__/tarfile.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/distlib/_backport/misc.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/distlib/_backport/shutil.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/distlib/_backport/sysconfig.cfg create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/distlib/_backport/sysconfig.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/distlib/_backport/tarfile.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/distlib/compat.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/distlib/database.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/distlib/index.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/distlib/locators.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/distlib/manifest.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/distlib/markers.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/distlib/metadata.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/distlib/resources.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/distlib/scripts.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/distlib/t32.exe create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/distlib/t64.exe create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/distlib/util.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/distlib/version.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/distlib/w32.exe create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/distlib/w64.exe create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/distlib/wheel.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/distro.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/html5lib/__init__.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/html5lib/__pycache__/__init__.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/html5lib/__pycache__/_ihatexml.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/html5lib/__pycache__/_inputstream.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/html5lib/__pycache__/_tokenizer.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/html5lib/__pycache__/_utils.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/html5lib/__pycache__/constants.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/html5lib/__pycache__/html5parser.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/html5lib/__pycache__/serializer.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/html5lib/_ihatexml.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/html5lib/_inputstream.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/html5lib/_tokenizer.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/html5lib/_trie/__init__.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/html5lib/_trie/__pycache__/__init__.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/html5lib/_trie/__pycache__/_base.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/html5lib/_trie/__pycache__/datrie.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/html5lib/_trie/__pycache__/py.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/html5lib/_trie/_base.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/html5lib/_trie/datrie.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/html5lib/_trie/py.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/html5lib/_utils.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/html5lib/constants.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/html5lib/filters/__init__.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/html5lib/filters/__pycache__/__init__.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/html5lib/filters/__pycache__/alphabeticalattributes.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/html5lib/filters/__pycache__/base.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/html5lib/filters/__pycache__/inject_meta_charset.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/html5lib/filters/__pycache__/lint.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/html5lib/filters/__pycache__/optionaltags.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/html5lib/filters/__pycache__/sanitizer.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/html5lib/filters/__pycache__/whitespace.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/html5lib/filters/alphabeticalattributes.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/html5lib/filters/base.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/html5lib/filters/inject_meta_charset.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/html5lib/filters/lint.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/html5lib/filters/optionaltags.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/html5lib/filters/sanitizer.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/html5lib/filters/whitespace.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/html5lib/html5parser.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/html5lib/serializer.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/html5lib/treeadapters/__init__.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/html5lib/treeadapters/__pycache__/__init__.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/html5lib/treeadapters/__pycache__/genshi.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/html5lib/treeadapters/__pycache__/sax.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/html5lib/treeadapters/genshi.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/html5lib/treeadapters/sax.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/html5lib/treebuilders/__init__.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/html5lib/treebuilders/__pycache__/__init__.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/html5lib/treebuilders/__pycache__/base.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/html5lib/treebuilders/__pycache__/dom.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/html5lib/treebuilders/__pycache__/etree.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/html5lib/treebuilders/__pycache__/etree_lxml.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/html5lib/treebuilders/base.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/html5lib/treebuilders/dom.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/html5lib/treebuilders/etree.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/html5lib/treebuilders/etree_lxml.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/html5lib/treewalkers/__init__.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/html5lib/treewalkers/__pycache__/__init__.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/html5lib/treewalkers/__pycache__/base.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/html5lib/treewalkers/__pycache__/dom.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/html5lib/treewalkers/__pycache__/etree.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/html5lib/treewalkers/__pycache__/etree_lxml.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/html5lib/treewalkers/__pycache__/genshi.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/html5lib/treewalkers/base.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/html5lib/treewalkers/dom.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/html5lib/treewalkers/etree.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/html5lib/treewalkers/etree_lxml.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/html5lib/treewalkers/genshi.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/idna/__init__.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/idna/__pycache__/__init__.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/idna/__pycache__/codec.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/idna/__pycache__/compat.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/idna/__pycache__/core.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/idna/__pycache__/idnadata.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/idna/__pycache__/intranges.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/idna/__pycache__/package_data.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/idna/__pycache__/uts46data.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/idna/codec.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/idna/compat.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/idna/core.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/idna/idnadata.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/idna/intranges.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/idna/package_data.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/idna/uts46data.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/ipaddress.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/lockfile/__init__.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/lockfile/__pycache__/__init__.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/lockfile/__pycache__/linklockfile.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/lockfile/__pycache__/mkdirlockfile.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/lockfile/__pycache__/pidlockfile.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/lockfile/__pycache__/sqlitelockfile.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/lockfile/__pycache__/symlinklockfile.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/lockfile/linklockfile.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/lockfile/mkdirlockfile.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/lockfile/pidlockfile.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/lockfile/sqlitelockfile.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/lockfile/symlinklockfile.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/msgpack/__init__.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/msgpack/__pycache__/__init__.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/msgpack/__pycache__/_version.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/msgpack/__pycache__/exceptions.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/msgpack/__pycache__/fallback.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/msgpack/_version.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/msgpack/exceptions.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/msgpack/fallback.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/packaging/__about__.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/packaging/__init__.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/packaging/__pycache__/__about__.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/packaging/__pycache__/__init__.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/packaging/__pycache__/_compat.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/packaging/__pycache__/_structures.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/packaging/__pycache__/markers.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/packaging/__pycache__/requirements.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/packaging/__pycache__/specifiers.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/packaging/__pycache__/utils.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/packaging/__pycache__/version.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/packaging/_compat.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/packaging/_structures.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/packaging/markers.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/packaging/requirements.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/packaging/specifiers.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/packaging/utils.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/packaging/version.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/pep517/__init__.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/pep517/__pycache__/__init__.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/pep517/__pycache__/_in_process.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/pep517/__pycache__/build.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/pep517/__pycache__/check.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/pep517/__pycache__/colorlog.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/pep517/__pycache__/compat.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/pep517/__pycache__/envbuild.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/pep517/__pycache__/wrappers.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/pep517/_in_process.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/pep517/build.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/pep517/check.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/pep517/colorlog.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/pep517/compat.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/pep517/envbuild.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/pep517/wrappers.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/pkg_resources/__init__.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/pkg_resources/__pycache__/__init__.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/pkg_resources/__pycache__/py31compat.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/pkg_resources/py31compat.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/progress/__init__.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/progress/__pycache__/__init__.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/progress/__pycache__/bar.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/progress/__pycache__/counter.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/progress/__pycache__/helpers.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/progress/__pycache__/spinner.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/progress/bar.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/progress/counter.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/progress/helpers.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/progress/spinner.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/pyparsing.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/pytoml/__init__.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/pytoml/__pycache__/__init__.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/pytoml/__pycache__/core.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/pytoml/__pycache__/parser.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/pytoml/__pycache__/test.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/pytoml/__pycache__/utils.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/pytoml/__pycache__/writer.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/pytoml/core.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/pytoml/parser.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/pytoml/test.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/pytoml/utils.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/pytoml/writer.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/requests/__init__.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/requests/__pycache__/__init__.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/requests/__pycache__/__version__.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/requests/__pycache__/_internal_utils.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/requests/__pycache__/adapters.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/requests/__pycache__/api.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/requests/__pycache__/auth.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/requests/__pycache__/certs.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/requests/__pycache__/compat.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/requests/__pycache__/cookies.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/requests/__pycache__/exceptions.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/requests/__pycache__/help.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/requests/__pycache__/hooks.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/requests/__pycache__/models.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/requests/__pycache__/packages.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/requests/__pycache__/sessions.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/requests/__pycache__/status_codes.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/requests/__pycache__/structures.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/requests/__pycache__/utils.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/requests/__version__.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/requests/_internal_utils.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/requests/adapters.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/requests/api.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/requests/auth.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/requests/certs.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/requests/compat.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/requests/cookies.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/requests/exceptions.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/requests/help.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/requests/hooks.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/requests/models.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/requests/packages.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/requests/sessions.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/requests/status_codes.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/requests/structures.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/requests/utils.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/retrying.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/six.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/urllib3/__init__.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/urllib3/__pycache__/__init__.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/urllib3/__pycache__/_collections.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/urllib3/__pycache__/connection.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/urllib3/__pycache__/connectionpool.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/urllib3/__pycache__/exceptions.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/urllib3/__pycache__/fields.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/urllib3/__pycache__/filepost.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/urllib3/__pycache__/poolmanager.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/urllib3/__pycache__/request.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/urllib3/__pycache__/response.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/urllib3/_collections.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/urllib3/connection.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/urllib3/connectionpool.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/urllib3/contrib/__init__.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/urllib3/contrib/__pycache__/__init__.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/urllib3/contrib/__pycache__/_appengine_environ.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/urllib3/contrib/__pycache__/appengine.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/urllib3/contrib/__pycache__/ntlmpool.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/urllib3/contrib/__pycache__/pyopenssl.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/urllib3/contrib/__pycache__/securetransport.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/urllib3/contrib/__pycache__/socks.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/urllib3/contrib/_appengine_environ.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/urllib3/contrib/_securetransport/__init__.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/urllib3/contrib/_securetransport/__pycache__/__init__.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/urllib3/contrib/_securetransport/__pycache__/bindings.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/urllib3/contrib/_securetransport/__pycache__/low_level.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/urllib3/contrib/_securetransport/bindings.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/urllib3/contrib/_securetransport/low_level.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/urllib3/contrib/appengine.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/urllib3/contrib/ntlmpool.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/urllib3/contrib/pyopenssl.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/urllib3/contrib/securetransport.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/urllib3/contrib/socks.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/urllib3/exceptions.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/urllib3/fields.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/urllib3/filepost.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/urllib3/packages/__init__.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/urllib3/packages/__pycache__/__init__.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/urllib3/packages/__pycache__/six.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/urllib3/packages/backports/__init__.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/urllib3/packages/backports/__pycache__/__init__.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/urllib3/packages/backports/__pycache__/makefile.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/urllib3/packages/backports/makefile.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/urllib3/packages/six.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/urllib3/packages/ssl_match_hostname/__init__.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/urllib3/packages/ssl_match_hostname/__pycache__/__init__.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/urllib3/packages/ssl_match_hostname/__pycache__/_implementation.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/urllib3/packages/ssl_match_hostname/_implementation.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/urllib3/poolmanager.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/urllib3/request.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/urllib3/response.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/urllib3/util/__init__.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/urllib3/util/__pycache__/__init__.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/urllib3/util/__pycache__/connection.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/urllib3/util/__pycache__/queue.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/urllib3/util/__pycache__/request.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/urllib3/util/__pycache__/response.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/urllib3/util/__pycache__/retry.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/urllib3/util/__pycache__/ssl_.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/urllib3/util/__pycache__/timeout.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/urllib3/util/__pycache__/url.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/urllib3/util/__pycache__/wait.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/urllib3/util/connection.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/urllib3/util/queue.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/urllib3/util/request.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/urllib3/util/response.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/urllib3/util/retry.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/urllib3/util/ssl_.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/urllib3/util/timeout.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/urllib3/util/url.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/urllib3/util/wait.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/webencodings/__init__.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/webencodings/__pycache__/__init__.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/webencodings/__pycache__/labels.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/webencodings/__pycache__/mklabels.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/webencodings/__pycache__/tests.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/webencodings/__pycache__/x_user_defined.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/webencodings/labels.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/webencodings/mklabels.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/webencodings/tests.py create mode 100644 flask/venv/lib/python3.6/site-packages/pip/_vendor/webencodings/x_user_defined.py create mode 100644 flask/venv/lib/python3.6/site-packages/pkg_resources/__init__.py create mode 100644 flask/venv/lib/python3.6/site-packages/pkg_resources/__pycache__/__init__.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pkg_resources/_vendor/__init__.py create mode 100644 flask/venv/lib/python3.6/site-packages/pkg_resources/_vendor/__pycache__/__init__.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pkg_resources/_vendor/__pycache__/appdirs.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pkg_resources/_vendor/__pycache__/pyparsing.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pkg_resources/_vendor/__pycache__/six.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pkg_resources/_vendor/appdirs.py create mode 100644 flask/venv/lib/python3.6/site-packages/pkg_resources/_vendor/packaging/__about__.py create mode 100644 flask/venv/lib/python3.6/site-packages/pkg_resources/_vendor/packaging/__init__.py create mode 100644 flask/venv/lib/python3.6/site-packages/pkg_resources/_vendor/packaging/__pycache__/__about__.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pkg_resources/_vendor/packaging/__pycache__/__init__.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pkg_resources/_vendor/packaging/__pycache__/_compat.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pkg_resources/_vendor/packaging/__pycache__/_structures.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pkg_resources/_vendor/packaging/__pycache__/markers.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pkg_resources/_vendor/packaging/__pycache__/requirements.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pkg_resources/_vendor/packaging/__pycache__/specifiers.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pkg_resources/_vendor/packaging/__pycache__/utils.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pkg_resources/_vendor/packaging/__pycache__/version.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/pkg_resources/_vendor/packaging/_compat.py create mode 100644 flask/venv/lib/python3.6/site-packages/pkg_resources/_vendor/packaging/_structures.py create mode 100644 flask/venv/lib/python3.6/site-packages/pkg_resources/_vendor/packaging/markers.py create mode 100644 flask/venv/lib/python3.6/site-packages/pkg_resources/_vendor/packaging/requirements.py create mode 100644 flask/venv/lib/python3.6/site-packages/pkg_resources/_vendor/packaging/specifiers.py create mode 100644 flask/venv/lib/python3.6/site-packages/pkg_resources/_vendor/packaging/utils.py create mode 100644 flask/venv/lib/python3.6/site-packages/pkg_resources/_vendor/packaging/version.py create mode 100644 flask/venv/lib/python3.6/site-packages/pkg_resources/_vendor/pyparsing.py create mode 100644 flask/venv/lib/python3.6/site-packages/pkg_resources/_vendor/six.py create mode 100644 flask/venv/lib/python3.6/site-packages/pkg_resources/extern/__init__.py create mode 100644 flask/venv/lib/python3.6/site-packages/pkg_resources/extern/__pycache__/__init__.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/setuptools-28.8.0.dist-info/DESCRIPTION.rst create mode 100644 flask/venv/lib/python3.6/site-packages/setuptools-28.8.0.dist-info/INSTALLER create mode 100644 flask/venv/lib/python3.6/site-packages/setuptools-28.8.0.dist-info/METADATA create mode 100644 flask/venv/lib/python3.6/site-packages/setuptools-28.8.0.dist-info/RECORD create mode 100644 flask/venv/lib/python3.6/site-packages/setuptools-28.8.0.dist-info/WHEEL create mode 100644 flask/venv/lib/python3.6/site-packages/setuptools-28.8.0.dist-info/dependency_links.txt create mode 100644 flask/venv/lib/python3.6/site-packages/setuptools-28.8.0.dist-info/entry_points.txt create mode 100644 flask/venv/lib/python3.6/site-packages/setuptools-28.8.0.dist-info/metadata.json create mode 100644 flask/venv/lib/python3.6/site-packages/setuptools-28.8.0.dist-info/top_level.txt create mode 100644 flask/venv/lib/python3.6/site-packages/setuptools-28.8.0.dist-info/zip-safe create mode 100644 flask/venv/lib/python3.6/site-packages/setuptools/__init__.py create mode 100644 flask/venv/lib/python3.6/site-packages/setuptools/__pycache__/__init__.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/setuptools/__pycache__/archive_util.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/setuptools/__pycache__/depends.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/setuptools/__pycache__/dist.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/setuptools/__pycache__/extension.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/setuptools/__pycache__/glob.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/setuptools/__pycache__/launch.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/setuptools/__pycache__/lib2to3_ex.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/setuptools/__pycache__/monkey.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/setuptools/__pycache__/msvc.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/setuptools/__pycache__/namespaces.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/setuptools/__pycache__/package_index.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/setuptools/__pycache__/py26compat.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/setuptools/__pycache__/py27compat.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/setuptools/__pycache__/py31compat.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/setuptools/__pycache__/sandbox.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/setuptools/__pycache__/site-patch.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/setuptools/__pycache__/ssl_support.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/setuptools/__pycache__/unicode_utils.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/setuptools/__pycache__/version.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/setuptools/__pycache__/windows_support.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/setuptools/archive_util.py create mode 100644 flask/venv/lib/python3.6/site-packages/setuptools/cli-32.exe create mode 100644 flask/venv/lib/python3.6/site-packages/setuptools/cli-64.exe create mode 100644 flask/venv/lib/python3.6/site-packages/setuptools/cli.exe create mode 100644 flask/venv/lib/python3.6/site-packages/setuptools/command/__init__.py create mode 100644 flask/venv/lib/python3.6/site-packages/setuptools/command/__pycache__/__init__.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/setuptools/command/__pycache__/alias.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/setuptools/command/__pycache__/bdist_egg.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/setuptools/command/__pycache__/bdist_rpm.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/setuptools/command/__pycache__/bdist_wininst.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/setuptools/command/__pycache__/build_ext.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/setuptools/command/__pycache__/build_py.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/setuptools/command/__pycache__/develop.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/setuptools/command/__pycache__/easy_install.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/setuptools/command/__pycache__/egg_info.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/setuptools/command/__pycache__/install.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/setuptools/command/__pycache__/install_egg_info.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/setuptools/command/__pycache__/install_lib.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/setuptools/command/__pycache__/install_scripts.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/setuptools/command/__pycache__/py36compat.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/setuptools/command/__pycache__/register.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/setuptools/command/__pycache__/rotate.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/setuptools/command/__pycache__/saveopts.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/setuptools/command/__pycache__/sdist.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/setuptools/command/__pycache__/setopt.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/setuptools/command/__pycache__/test.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/setuptools/command/__pycache__/upload.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/setuptools/command/__pycache__/upload_docs.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/setuptools/command/alias.py create mode 100644 flask/venv/lib/python3.6/site-packages/setuptools/command/bdist_egg.py create mode 100644 flask/venv/lib/python3.6/site-packages/setuptools/command/bdist_rpm.py create mode 100644 flask/venv/lib/python3.6/site-packages/setuptools/command/bdist_wininst.py create mode 100644 flask/venv/lib/python3.6/site-packages/setuptools/command/build_ext.py create mode 100644 flask/venv/lib/python3.6/site-packages/setuptools/command/build_py.py create mode 100644 flask/venv/lib/python3.6/site-packages/setuptools/command/develop.py create mode 100644 flask/venv/lib/python3.6/site-packages/setuptools/command/easy_install.py create mode 100644 flask/venv/lib/python3.6/site-packages/setuptools/command/egg_info.py create mode 100644 flask/venv/lib/python3.6/site-packages/setuptools/command/install.py create mode 100644 flask/venv/lib/python3.6/site-packages/setuptools/command/install_egg_info.py create mode 100644 flask/venv/lib/python3.6/site-packages/setuptools/command/install_lib.py create mode 100644 flask/venv/lib/python3.6/site-packages/setuptools/command/install_scripts.py create mode 100644 flask/venv/lib/python3.6/site-packages/setuptools/command/launcher manifest.xml create mode 100644 flask/venv/lib/python3.6/site-packages/setuptools/command/py36compat.py create mode 100644 flask/venv/lib/python3.6/site-packages/setuptools/command/register.py create mode 100644 flask/venv/lib/python3.6/site-packages/setuptools/command/rotate.py create mode 100644 flask/venv/lib/python3.6/site-packages/setuptools/command/saveopts.py create mode 100644 flask/venv/lib/python3.6/site-packages/setuptools/command/sdist.py create mode 100644 flask/venv/lib/python3.6/site-packages/setuptools/command/setopt.py create mode 100644 flask/venv/lib/python3.6/site-packages/setuptools/command/test.py create mode 100644 flask/venv/lib/python3.6/site-packages/setuptools/command/upload.py create mode 100644 flask/venv/lib/python3.6/site-packages/setuptools/command/upload_docs.py create mode 100644 flask/venv/lib/python3.6/site-packages/setuptools/depends.py create mode 100644 flask/venv/lib/python3.6/site-packages/setuptools/dist.py create mode 100644 flask/venv/lib/python3.6/site-packages/setuptools/extension.py create mode 100644 flask/venv/lib/python3.6/site-packages/setuptools/extern/__init__.py create mode 100644 flask/venv/lib/python3.6/site-packages/setuptools/extern/__pycache__/__init__.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/setuptools/glob.py create mode 100644 flask/venv/lib/python3.6/site-packages/setuptools/gui-32.exe create mode 100644 flask/venv/lib/python3.6/site-packages/setuptools/gui-64.exe create mode 100644 flask/venv/lib/python3.6/site-packages/setuptools/gui.exe create mode 100644 flask/venv/lib/python3.6/site-packages/setuptools/launch.py create mode 100644 flask/venv/lib/python3.6/site-packages/setuptools/lib2to3_ex.py create mode 100644 flask/venv/lib/python3.6/site-packages/setuptools/monkey.py create mode 100644 flask/venv/lib/python3.6/site-packages/setuptools/msvc.py create mode 100644 flask/venv/lib/python3.6/site-packages/setuptools/namespaces.py create mode 100644 flask/venv/lib/python3.6/site-packages/setuptools/package_index.py create mode 100644 flask/venv/lib/python3.6/site-packages/setuptools/py26compat.py create mode 100644 flask/venv/lib/python3.6/site-packages/setuptools/py27compat.py create mode 100644 flask/venv/lib/python3.6/site-packages/setuptools/py31compat.py create mode 100644 flask/venv/lib/python3.6/site-packages/setuptools/sandbox.py create mode 100644 flask/venv/lib/python3.6/site-packages/setuptools/script (dev).tmpl create mode 100644 flask/venv/lib/python3.6/site-packages/setuptools/script.tmpl create mode 100644 flask/venv/lib/python3.6/site-packages/setuptools/site-patch.py create mode 100644 flask/venv/lib/python3.6/site-packages/setuptools/ssl_support.py create mode 100644 flask/venv/lib/python3.6/site-packages/setuptools/unicode_utils.py create mode 100644 flask/venv/lib/python3.6/site-packages/setuptools/version.py create mode 100644 flask/venv/lib/python3.6/site-packages/setuptools/windows_support.py create mode 100644 flask/venv/lib/python3.6/site-packages/werkzeug/__init__.py create mode 100644 flask/venv/lib/python3.6/site-packages/werkzeug/__pycache__/__init__.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/werkzeug/__pycache__/_compat.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/werkzeug/__pycache__/_internal.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/werkzeug/__pycache__/_reloader.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/werkzeug/__pycache__/datastructures.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/werkzeug/__pycache__/exceptions.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/werkzeug/__pycache__/filesystem.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/werkzeug/__pycache__/formparser.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/werkzeug/__pycache__/http.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/werkzeug/__pycache__/local.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/werkzeug/__pycache__/posixemulation.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/werkzeug/__pycache__/routing.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/werkzeug/__pycache__/script.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/werkzeug/__pycache__/security.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/werkzeug/__pycache__/serving.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/werkzeug/__pycache__/test.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/werkzeug/__pycache__/testapp.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/werkzeug/__pycache__/urls.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/werkzeug/__pycache__/useragents.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/werkzeug/__pycache__/utils.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/werkzeug/__pycache__/websocket.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/werkzeug/__pycache__/wrappers.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/werkzeug/__pycache__/wsgi.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/werkzeug/_compat.py create mode 100644 flask/venv/lib/python3.6/site-packages/werkzeug/_internal.py create mode 100644 flask/venv/lib/python3.6/site-packages/werkzeug/_reloader.py create mode 100644 flask/venv/lib/python3.6/site-packages/werkzeug/contrib/__init__.py create mode 100644 flask/venv/lib/python3.6/site-packages/werkzeug/contrib/__pycache__/__init__.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/werkzeug/contrib/__pycache__/atom.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/werkzeug/contrib/__pycache__/cache.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/werkzeug/contrib/__pycache__/fixers.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/werkzeug/contrib/__pycache__/iterio.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/werkzeug/contrib/__pycache__/jsrouting.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/werkzeug/contrib/__pycache__/limiter.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/werkzeug/contrib/__pycache__/lint.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/werkzeug/contrib/__pycache__/profiler.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/werkzeug/contrib/__pycache__/securecookie.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/werkzeug/contrib/__pycache__/sessions.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/werkzeug/contrib/__pycache__/testtools.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/werkzeug/contrib/__pycache__/wrappers.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/werkzeug/contrib/atom.py create mode 100644 flask/venv/lib/python3.6/site-packages/werkzeug/contrib/cache.py create mode 100644 flask/venv/lib/python3.6/site-packages/werkzeug/contrib/fixers.py create mode 100644 flask/venv/lib/python3.6/site-packages/werkzeug/contrib/iterio.py create mode 100644 flask/venv/lib/python3.6/site-packages/werkzeug/contrib/jsrouting.py create mode 100644 flask/venv/lib/python3.6/site-packages/werkzeug/contrib/limiter.py create mode 100644 flask/venv/lib/python3.6/site-packages/werkzeug/contrib/lint.py create mode 100644 flask/venv/lib/python3.6/site-packages/werkzeug/contrib/profiler.py create mode 100644 flask/venv/lib/python3.6/site-packages/werkzeug/contrib/securecookie.py create mode 100644 flask/venv/lib/python3.6/site-packages/werkzeug/contrib/sessions.py create mode 100644 flask/venv/lib/python3.6/site-packages/werkzeug/contrib/testtools.py create mode 100644 flask/venv/lib/python3.6/site-packages/werkzeug/contrib/wrappers.py create mode 100644 flask/venv/lib/python3.6/site-packages/werkzeug/datastructures.py create mode 100644 flask/venv/lib/python3.6/site-packages/werkzeug/debug/__init__.py create mode 100644 flask/venv/lib/python3.6/site-packages/werkzeug/debug/__pycache__/__init__.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/werkzeug/debug/__pycache__/console.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/werkzeug/debug/__pycache__/repr.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/werkzeug/debug/__pycache__/tbtools.cpython-36.pyc create mode 100644 flask/venv/lib/python3.6/site-packages/werkzeug/debug/console.py create mode 100644 flask/venv/lib/python3.6/site-packages/werkzeug/debug/repr.py create mode 100644 flask/venv/lib/python3.6/site-packages/werkzeug/debug/shared/FONT_LICENSE create mode 100644 flask/venv/lib/python3.6/site-packages/werkzeug/debug/shared/console.png create mode 100644 flask/venv/lib/python3.6/site-packages/werkzeug/debug/shared/debugger.js create mode 100644 flask/venv/lib/python3.6/site-packages/werkzeug/debug/shared/jquery.js create mode 100644 flask/venv/lib/python3.6/site-packages/werkzeug/debug/shared/less.png create mode 100644 flask/venv/lib/python3.6/site-packages/werkzeug/debug/shared/more.png create mode 100644 flask/venv/lib/python3.6/site-packages/werkzeug/debug/shared/source.png create mode 100644 flask/venv/lib/python3.6/site-packages/werkzeug/debug/shared/style.css create mode 100644 flask/venv/lib/python3.6/site-packages/werkzeug/debug/shared/ubuntu.ttf create mode 100644 flask/venv/lib/python3.6/site-packages/werkzeug/debug/tbtools.py create mode 100644 flask/venv/lib/python3.6/site-packages/werkzeug/exceptions.py create mode 100644 flask/venv/lib/python3.6/site-packages/werkzeug/filesystem.py create mode 100644 flask/venv/lib/python3.6/site-packages/werkzeug/formparser.py create mode 100644 flask/venv/lib/python3.6/site-packages/werkzeug/http.py create mode 100644 flask/venv/lib/python3.6/site-packages/werkzeug/local.py create mode 100644 flask/venv/lib/python3.6/site-packages/werkzeug/posixemulation.py create mode 100644 flask/venv/lib/python3.6/site-packages/werkzeug/routing.py create mode 100644 flask/venv/lib/python3.6/site-packages/werkzeug/script.py create mode 100644 flask/venv/lib/python3.6/site-packages/werkzeug/security.py create mode 100644 flask/venv/lib/python3.6/site-packages/werkzeug/serving.py create mode 100644 flask/venv/lib/python3.6/site-packages/werkzeug/test.py create mode 100644 flask/venv/lib/python3.6/site-packages/werkzeug/testapp.py create mode 100644 flask/venv/lib/python3.6/site-packages/werkzeug/urls.py create mode 100644 flask/venv/lib/python3.6/site-packages/werkzeug/useragents.py create mode 100644 flask/venv/lib/python3.6/site-packages/werkzeug/utils.py create mode 100644 flask/venv/lib/python3.6/site-packages/werkzeug/websocket.py create mode 100644 flask/venv/lib/python3.6/site-packages/werkzeug/wrappers.py create mode 100644 flask/venv/lib/python3.6/site-packages/werkzeug/wsgi.py create mode 100644 flask/venv/pip-selfcheck.json create mode 100644 flask/venv/pyvenv.cfg create mode 100644 gerrit/gerrit.py create mode 100644 gitlab/git.py rename gitlab_api/gitlab.cfg => gitlab/gl.cfg (100%) delete mode 100644 gitlab_api/git.py create mode 100755 mysite/manage.py create mode 100644 mysite/mysite/__init__.py create mode 100644 mysite/mysite/__pycache__/__init__.cpython-36.pyc create mode 100644 mysite/mysite/__pycache__/settings.cpython-36.pyc create mode 100644 mysite/mysite/__pycache__/urls.cpython-36.pyc create mode 100644 mysite/mysite/__pycache__/wsgi.cpython-36.pyc create mode 100644 mysite/mysite/settings.py create mode 100644 mysite/mysite/urls.py create mode 100644 mysite/mysite/wsgi.py create mode 100644 mysite/polls/__init__.py create mode 100644 mysite/polls/__pycache__/__init__.cpython-36.pyc create mode 100644 mysite/polls/__pycache__/admin.cpython-36.pyc create mode 100644 mysite/polls/__pycache__/apps.cpython-36.pyc create mode 100644 mysite/polls/__pycache__/models.cpython-36.pyc create mode 100644 mysite/polls/__pycache__/urls.cpython-36.pyc create mode 100644 mysite/polls/__pycache__/views.cpython-36.pyc create mode 100644 mysite/polls/admin.py create mode 100644 mysite/polls/apps.py create mode 100644 mysite/polls/models.py create mode 100644 mysite/polls/views.py create mode 100644 nexus3/download_asset_from_url.py create mode 100644 nexus3/get_components_from_repo.py create mode 100644 nexus3/get_rs_gav_from_url.py create mode 100644 nexus3/get_ss_url_from_release_gav.py create mode 100644 shell/etcd/etcd.conf create mode 100644 shell/etcd/etcd.service create mode 100755 shell/etcd/generate_ca.sh create mode 100755 shell/etcd/install_cfssl.sh create mode 100755 shell/etcd/install_etcd.sh create mode 100755 shell/etcd/start_etcd_service.sh create mode 100644 shell/nexus/upload-aar.sh create mode 100644 shell/nexus/upload-jar.sh diff --git a/cmdb/cmdb.py b/cmdb/cmdb.py new file mode 100644 index 0000000..e69de29 diff --git a/exercise/.DS_Store b/exercise/.DS_Store index 5008ddfcf53c02e82d7eee2e57c38e5672ef89f6..7099792dd170ffa4ad09fc633d6f43ab8f863adf 100644 GIT binary patch delta 76 zcmZoMXfc?eJ=s8n#e|iim?489l_7^AC#5(!Cn-NahmipYm_P&&fH*)bzwhy LNb_cHj-UJhcAya4 delta 51 vcmZoMXfc?e&B4IH0LBvwMFg0D92j6^U=Y|?IE{T`gVbaL5thx|96$L1%DD*$ diff --git a/exercise/inspect.py b/exercise/inspect.py index 901be39..eb3b6f3 100644 --- a/exercise/inspect.py +++ b/exercise/inspect.py @@ -6,7 +6,7 @@ from inspect import signature -def add1(x:int, y:int, *args, **kwargs) -> int : +def add1(x: int, y: int, *args, **kwargs) -> int: return x + y diff --git a/flask/app.py b/flask/app.py new file mode 100644 index 0000000..cdf7d1b --- /dev/null +++ b/flask/app.py @@ -0,0 +1,135 @@ +""" +flask exercise +""" +from flask import Flask, url_for, request +from flask import render_template +import logging +FORMAT = '%(asctime)-15s %(levelname)s %(message)s' +logging.basicConfig(level=logging.INFO) +logger = logging.getLogger('flask') +handler = logging.FileHandler('flask.log') +fmt = logging.Formatter(FORMAT) +handler.setFormatter(fmt) +logger.addHandler(handler) + +# from logging.config import dictConfig +# +# dictConfig({ +# 'version': 1, +# 'formatters': {'default': { +# 'format': '[%(asctime)s] %(levelname)s in %(module)s: %(message)s', +# }}, +# 'handlers': {'wsgi': { +# 'class': 'logging.StreamHandler', +# 'stream': 'ext://flask.logging.wsgi_errors_stream', +# 'formatter': 'default' +# }}, +# 'root': { +# 'level': 'INFO', +# 'handlers': ['wsgi'] +# } +# }) + +app = Flask(__name__) + + +# 路由 +# @app.route('/') +# def index(): +# return 'index' + + +# @app.route('/hello') +# def hello(): +# return 'hello world!' + + +@app.route('/post/') +def show_post(post_id): + return 'Post {}'.format(post_id) + + +@app.route('/path/') +def show_subpath(subpath): + return 'Subpath: {}'.format(subpath) + + +""" +转换器类型: + string:缺省值,接受任何不包含斜杠的文本 + int: + float: + path:类似string,可以接受斜杠 + uuid:接受UUID字符串 +""" + + +@app.route('/projects/') +def projects(): + return 'The project page' + + +@app.route('/about') +def about(): + return 'The about page' + + +""" +/ 重定向行为: + projects的URL,会自动补齐尾部'/'; + about的url,如果访问时尾部带了'/',会报错; +""" + + +@app.route('/') +def index(): + return 'index' + + +@app.route('/login') +def login(): + return 'login' + + +@app.route('/user/') +def profile(username): + # app.logger.info('user: {}'.format(username)) + logger.info('user: {}'.format(username)) + return 'User %s' % username + + +""" +url_for()函数用于构建指定函数的URL。它把函数名称作为第一个参数,可以接受任意个关键字参数,每个关键字参数对应URL中的变量。 +未知变量讲添加到URL中作为查询参数。 +""" +with app.test_request_context(): + print(url_for('index')) + print(url_for('login')) + print(url_for('login', next='/')) + print(url_for('profile', username='John Doe')) + + +@app.route('/method', methods=['GET', 'POST']) +def method(): + if request.method == 'POST': + return 'do post' + else: + return 'do show' + + +# 如果支持GET方法,flask会自动添加HEAD方法支持; +# url_for('static', filename='style.css') + + +# flask使用Jinja2模板引擎,render_template方法可以渲染模板 +# flask会在templates文件夹内寻找模板 +@app.route('/hello/') +@app.route('/hello/') +def hello(name=None): + return render_template('hello.html', name=name) + + +# error page +@app.errorhandler(404) +def page_not_found(error): + return render_template('page_not_found.html'), 404 diff --git a/flask/demo/__init__.py b/flask/demo/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/flask/demo/__pycache__/demo.cpython-36.pyc b/flask/demo/__pycache__/demo.cpython-36.pyc new file mode 100644 index 0000000000000000000000000000000000000000..513d3ef2727ba010c2f6fd539c1d491b3a504127 GIT binary patch literal 1545 zcmZ`(OK;mo5Z+xrL{X2p&dYs5ZPA0!!isI6MhzjbD$A{qSV1l25Td|>(XJfIe8@{G zs0<$pBt80v^e^qTC;x?>IZQu`k-P7KP zKkL1^{61Oa7x6)>rLwFzfM}NP?Cu@z?Cx(rfqUm*Z+HL4pIQ@KD|n16J@5Y7J9)*A zI-}0doneo^JnfHyuht@?(@yspKY4M~Kkj!sqyCG*aEzR8FBgnM82J%^Bmos9V1fpg zw5JXXS1@70ZC~3#Y31_-RKfUNQ38Kic%uBC1itWL&lPQ-X0Z$$1(+X?nwIv`c^rqY zW2q}M6(yls@N>D)wQyc!Q94#Kk!f+$00x>gErp!4J5QsFxzzPss<%>cAt&KHF2)ps zc;S=5=)%Z-070+FlsqCpfekLpZ6wk7PCbR9+i93ceC9Hq{7uw7nEvm6>m@9mw@jH^ zM>0PzvRP}UvZ)*wt=Xb@lcjshTEmQX-~EdMkeyK`OCY`WbZ9Z({ z$Dqw08b+j%Fgj(1gf8K^;gNv-8fG8zG2KU=cfwl{SxR!ytgB6ks{05J5FR2tLU@d@ zh43lDX9x`hv+r-w`Uc^n0{a}IxLl6JKwxZ>Zh^=)nP)4Eq3j*=cT(7jV8hrP{%PUz zm#45chM=~>*-X3RES*GWhF;*DWJ1P9uV%HiPM8`j+tFSgrKfoQO@*tp$~@}h%{*(f F{2#_QQgZ+R literal 0 HcmV?d00001 diff --git a/flask/demo/config.py b/flask/demo/config.py new file mode 100644 index 0000000..15729fb --- /dev/null +++ b/flask/demo/config.py @@ -0,0 +1,2 @@ +SQLALCHEMY_DATABASE_URI = "mysql://root:devon123@127.0.0.1:32769/flask" +SQLALCHEMY_TRACK_MODIFICATIONS = True diff --git a/flask/demo/demo.py b/flask/demo/demo.py new file mode 100644 index 0000000..f104f1f --- /dev/null +++ b/flask/demo/demo.py @@ -0,0 +1,39 @@ +from flask import Flask +from flask_sqlalchemy import SQLAlchemy + +app = Flask(__name__) +app.config['SECRET_KEY'] = 'dev' +app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql://root:devon123@127.0.0.1:32769/flask' +app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = True + +db = SQLAlchemy(app) + + +class Role(db.Model): + __tablename__ = 'roles' + id = db.Column(db.Integer, nullable=False, primary_key=True, autoincrement=True) + name = db.Column(db.String(32), nullable=False, unique=True, server_default='') + + def __repr__(self): + return '' % self.name + + +class User(db.Model): + __tablename__ = 'users' + + id = db.Column(db.Integer, primary_key=True, autoincrement=True) + username = db.Column(db.String(64), nullable=False, unique=True, index=True) + email = db.Column(db.String(128), unique=True) + role_id = db.Column(db.Integer, nullable=False) + + def __init__(self, username, email): + self.username = username + self.email = email + + def __repr__(self): + return '' %(self.username, self.role_id) + + + + + diff --git a/flask/templates/hello.html b/flask/templates/hello.html new file mode 100644 index 0000000..2c05803 --- /dev/null +++ b/flask/templates/hello.html @@ -0,0 +1,14 @@ + + + + + Hello from Flask + + +{% if name %} +

Hello {{ name }}!

+{% else %} +

Hello, World!

+{% endif %} + + \ No newline at end of file diff --git a/flask/templates/page_not_found.html b/flask/templates/page_not_found.html new file mode 100644 index 0000000..e7272bb --- /dev/null +++ b/flask/templates/page_not_found.html @@ -0,0 +1,10 @@ + + + + + Page not Found + + +

Sorry for lost!

+ + \ No newline at end of file diff --git a/flask/venv/bin/activate b/flask/venv/bin/activate new file mode 100644 index 0000000..d5f8b39 --- /dev/null +++ b/flask/venv/bin/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="/Users/devon/Desktop/project/python3/flask/venv" +export VIRTUAL_ENV + +_OLD_VIRTUAL_PATH="$PATH" +PATH="$VIRTUAL_ENV/bin:$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/flask/venv/bin/activate.csh b/flask/venv/bin/activate.csh new file mode 100644 index 0000000..e52ab1f --- /dev/null +++ b/flask/venv/bin/activate.csh @@ -0,0 +1,37 @@ +# This file must be used with "source bin/activate.csh" *from csh*. +# You cannot run it directly. +# Created by Davide Di Blasi . +# Ported to Python 3.3 venv by Andrew Svetlov + +alias deactivate 'test $?_OLD_VIRTUAL_PATH != 0 && setenv PATH "$_OLD_VIRTUAL_PATH" && unset _OLD_VIRTUAL_PATH; rehash; test $?_OLD_VIRTUAL_PROMPT != 0 && set prompt="$_OLD_VIRTUAL_PROMPT" && unset _OLD_VIRTUAL_PROMPT; unsetenv VIRTUAL_ENV; test "\!:*" != "nondestructive" && unalias deactivate' + +# Unset irrelevant variables. +deactivate nondestructive + +setenv VIRTUAL_ENV "/Users/devon/Desktop/project/python3/flask/venv" + +set _OLD_VIRTUAL_PATH="$PATH" +setenv PATH "$VIRTUAL_ENV/bin:$PATH" + + +set _OLD_VIRTUAL_PROMPT="$prompt" + +if (! "$?VIRTUAL_ENV_DISABLE_PROMPT") then + if ("venv" != "") then + set env_name = "venv" + else + if (`basename "VIRTUAL_ENV"` == "__") then + # special case for Aspen magic directories + # see http://www.zetadev.com/software/aspen/ + set env_name = `basename \`dirname "$VIRTUAL_ENV"\`` + else + set env_name = `basename "$VIRTUAL_ENV"` + endif + endif + set prompt = "[$env_name] $prompt" + unset env_name +endif + +alias pydoc python -m pydoc + +rehash diff --git a/flask/venv/bin/activate.fish b/flask/venv/bin/activate.fish new file mode 100644 index 0000000..ffcc991 --- /dev/null +++ b/flask/venv/bin/activate.fish @@ -0,0 +1,75 @@ +# This file must be used with ". bin/activate.fish" *from fish* (http://fishshell.org) +# you cannot run it directly + +function deactivate -d "Exit virtualenv and return to normal shell environment" + # reset old environment variables + if test -n "$_OLD_VIRTUAL_PATH" + set -gx PATH $_OLD_VIRTUAL_PATH + set -e _OLD_VIRTUAL_PATH + end + if test -n "$_OLD_VIRTUAL_PYTHONHOME" + set -gx PYTHONHOME $_OLD_VIRTUAL_PYTHONHOME + set -e _OLD_VIRTUAL_PYTHONHOME + end + + if test -n "$_OLD_FISH_PROMPT_OVERRIDE" + functions -e fish_prompt + set -e _OLD_FISH_PROMPT_OVERRIDE + functions -c _old_fish_prompt fish_prompt + functions -e _old_fish_prompt + end + + set -e VIRTUAL_ENV + if test "$argv[1]" != "nondestructive" + # Self destruct! + functions -e deactivate + end +end + +# unset irrelevant variables +deactivate nondestructive + +set -gx VIRTUAL_ENV "/Users/devon/Desktop/project/python3/flask/venv" + +set -gx _OLD_VIRTUAL_PATH $PATH +set -gx PATH "$VIRTUAL_ENV/bin" $PATH + +# unset PYTHONHOME if set +if set -q PYTHONHOME + set -gx _OLD_VIRTUAL_PYTHONHOME $PYTHONHOME + set -e PYTHONHOME +end + +if test -z "$VIRTUAL_ENV_DISABLE_PROMPT" + # fish uses a function instead of an env var to generate the prompt. + + # save the current fish_prompt function as the function _old_fish_prompt + functions -c fish_prompt _old_fish_prompt + + # with the original prompt function renamed, we can override with our own. + function fish_prompt + # Save the return status of the last command + set -l old_status $status + + # Prompt override? + if test -n "(venv) " + printf "%s%s" "(venv) " (set_color normal) + else + # ...Otherwise, prepend env + set -l _checkbase (basename "$VIRTUAL_ENV") + if test $_checkbase = "__" + # special case for Aspen magic directories + # see http://www.zetadev.com/software/aspen/ + printf "%s[%s]%s " (set_color -b blue white) (basename (dirname "$VIRTUAL_ENV")) (set_color normal) + else + printf "%s(%s)%s" (set_color -b blue white) (basename "$VIRTUAL_ENV") (set_color normal) + end + end + + # Restore the return status of the previous command. + echo "exit $old_status" | . + _old_fish_prompt + end + + set -gx _OLD_FISH_PROMPT_OVERRIDE "$VIRTUAL_ENV" +end diff --git a/flask/venv/bin/easy_install b/flask/venv/bin/easy_install new file mode 100755 index 0000000..fab47f6 --- /dev/null +++ b/flask/venv/bin/easy_install @@ -0,0 +1,11 @@ +#!/Users/devon/Desktop/project/python3/flask/venv/bin/python3 + +# -*- coding: utf-8 -*- +import re +import sys + +from setuptools.command.easy_install import main + +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0]) + sys.exit(main()) diff --git a/flask/venv/bin/easy_install-3.6 b/flask/venv/bin/easy_install-3.6 new file mode 100755 index 0000000..fab47f6 --- /dev/null +++ b/flask/venv/bin/easy_install-3.6 @@ -0,0 +1,11 @@ +#!/Users/devon/Desktop/project/python3/flask/venv/bin/python3 + +# -*- coding: utf-8 -*- +import re +import sys + +from setuptools.command.easy_install import main + +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0]) + sys.exit(main()) diff --git a/flask/venv/bin/flask b/flask/venv/bin/flask new file mode 100755 index 0000000..75a764b --- /dev/null +++ b/flask/venv/bin/flask @@ -0,0 +1,11 @@ +#!/Users/devon/Desktop/project/python3/flask/venv/bin/python3 + +# -*- coding: utf-8 -*- +import re +import sys + +from flask.cli import main + +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0]) + sys.exit(main()) diff --git a/flask/venv/bin/pip b/flask/venv/bin/pip new file mode 100755 index 0000000..6db6ac9 --- /dev/null +++ b/flask/venv/bin/pip @@ -0,0 +1,11 @@ +#!/Users/devon/Desktop/project/python3/flask/venv/bin/python3 + +# -*- coding: utf-8 -*- +import re +import sys + +from pip._internal import main + +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0]) + sys.exit(main()) diff --git a/flask/venv/bin/pip3 b/flask/venv/bin/pip3 new file mode 100755 index 0000000..6db6ac9 --- /dev/null +++ b/flask/venv/bin/pip3 @@ -0,0 +1,11 @@ +#!/Users/devon/Desktop/project/python3/flask/venv/bin/python3 + +# -*- coding: utf-8 -*- +import re +import sys + +from pip._internal import main + +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0]) + sys.exit(main()) diff --git a/flask/venv/bin/pip3.6 b/flask/venv/bin/pip3.6 new file mode 100755 index 0000000..6db6ac9 --- /dev/null +++ b/flask/venv/bin/pip3.6 @@ -0,0 +1,11 @@ +#!/Users/devon/Desktop/project/python3/flask/venv/bin/python3 + +# -*- coding: utf-8 -*- +import re +import sys + +from pip._internal import main + +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0]) + sys.exit(main()) diff --git a/flask/venv/bin/python b/flask/venv/bin/python new file mode 120000 index 0000000..b8a0adb --- /dev/null +++ b/flask/venv/bin/python @@ -0,0 +1 @@ +python3 \ No newline at end of file diff --git a/flask/venv/bin/python3 b/flask/venv/bin/python3 new file mode 120000 index 0000000..6b2efc8 --- /dev/null +++ b/flask/venv/bin/python3 @@ -0,0 +1 @@ +/Library/Frameworks/Python.framework/Versions/3.6/bin/python3 \ No newline at end of file diff --git a/flask/venv/lib/python3.6/site-packages/Click-7.0.dist-info/INSTALLER b/flask/venv/lib/python3.6/site-packages/Click-7.0.dist-info/INSTALLER new file mode 100644 index 0000000..a1b589e --- /dev/null +++ b/flask/venv/lib/python3.6/site-packages/Click-7.0.dist-info/INSTALLER @@ -0,0 +1 @@ +pip diff --git a/flask/venv/lib/python3.6/site-packages/Click-7.0.dist-info/LICENSE.txt b/flask/venv/lib/python3.6/site-packages/Click-7.0.dist-info/LICENSE.txt new file mode 100644 index 0000000..87ce152 --- /dev/null +++ b/flask/venv/lib/python3.6/site-packages/Click-7.0.dist-info/LICENSE.txt @@ -0,0 +1,39 @@ +Copyright © 2014 by the Pallets team. + +Some rights reserved. + +Redistribution and use in source and binary forms of the software as +well as documentation, 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 holder nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE AND DOCUMENTATION 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 AND DOCUMENTATION, EVEN IF ADVISED OF THE POSSIBILITY OF +SUCH DAMAGE. + +---- + +Click uses parts of optparse written by Gregory P. Ward and maintained +by the Python Software Foundation. This is limited to code in parser.py. + +Copyright © 2001-2006 Gregory P. Ward. All rights reserved. +Copyright © 2002-2006 Python Software Foundation. All rights reserved. diff --git a/flask/venv/lib/python3.6/site-packages/Click-7.0.dist-info/METADATA b/flask/venv/lib/python3.6/site-packages/Click-7.0.dist-info/METADATA new file mode 100644 index 0000000..625bdad --- /dev/null +++ b/flask/venv/lib/python3.6/site-packages/Click-7.0.dist-info/METADATA @@ -0,0 +1,121 @@ +Metadata-Version: 2.1 +Name: Click +Version: 7.0 +Summary: Composable command line interface toolkit +Home-page: https://palletsprojects.com/p/click/ +Author: Armin Ronacher +Author-email: armin.ronacher@active-4.com +Maintainer: Pallets Team +Maintainer-email: contact@palletsprojects.com +License: BSD +Project-URL: Documentation, https://click.palletsprojects.com/ +Project-URL: Code, https://github.com/pallets/click +Project-URL: Issue tracker, https://github.com/pallets/click/issues +Platform: UNKNOWN +Classifier: Development Status :: 5 - Production/Stable +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 :: 3.7 +Requires-Python: >=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.* + +\$ click\_ +========== + +Click is a Python package for creating beautiful command line interfaces +in a composable way with as little code as necessary. It's the "Command +Line Interface Creation Kit". It's highly configurable but comes with +sensible defaults out of the box. + +It aims to make the process of writing command line tools quick and fun +while also preventing any frustration caused by the inability to +implement an intended CLI API. + +Click in three points: + +- Arbitrary nesting of commands +- Automatic help page generation +- Supports lazy loading of subcommands at runtime + + +Installing +---------- + +Install and update using `pip`_: + +.. code-block:: text + + $ pip install click + +Click supports Python 3.4 and newer, Python 2.7, and PyPy. + +.. _pip: https://pip.pypa.io/en/stable/quickstart/ + + +A Simple Example +---------------- + +What does it look like? Here is an example of a simple Click program: + +.. code-block:: python + + import click + + @click.command() + @click.option("--count", default=1, help="Number of greetings.") + @click.option("--name", prompt="Your name", + help="The person to greet.") + def hello(count, name): + """Simple program that greets NAME for a total of COUNT times.""" + for _ in range(count): + click.echo("Hello, %s!" % name) + + if __name__ == '__main__': + hello() + +And what it looks like when run: + +.. code-block:: text + + $ python hello.py --count=3 + Your name: Click + Hello, Click! + Hello, Click! + Hello, Click! + + +Donate +------ + +The Pallets organization develops and supports Click and other popular +packages. In order to grow the community of contributors and users, and +allow the maintainers to devote more time to the projects, `please +donate today`_. + +.. _please donate today: https://palletsprojects.com/donate + + +Links +----- + +* Website: https://palletsprojects.com/p/click/ +* Documentation: https://click.palletsprojects.com/ +* License: `BSD `_ +* Releases: https://pypi.org/project/click/ +* Code: https://github.com/pallets/click +* Issue tracker: https://github.com/pallets/click/issues +* Test status: + + * Linux, Mac: https://travis-ci.org/pallets/click + * Windows: https://ci.appveyor.com/project/pallets/click + +* Test coverage: https://codecov.io/gh/pallets/click + + diff --git a/flask/venv/lib/python3.6/site-packages/Click-7.0.dist-info/RECORD b/flask/venv/lib/python3.6/site-packages/Click-7.0.dist-info/RECORD new file mode 100644 index 0000000..d4ecfef --- /dev/null +++ b/flask/venv/lib/python3.6/site-packages/Click-7.0.dist-info/RECORD @@ -0,0 +1,40 @@ +Click-7.0.dist-info/LICENSE.txt,sha256=4hIxn676T0Wcisk3_chVcECjyrivKTZsoqSNI5AlIlw,1876 +Click-7.0.dist-info/METADATA,sha256=-r8jeke3Zer4diRvT1MjFZuiJ6yTT_qFP39svLqdaLI,3516 +Click-7.0.dist-info/RECORD,, +Click-7.0.dist-info/WHEEL,sha256=gduuPyBvFJQSQ0zdyxF7k0zynDXbIbvg5ZBHoXum5uk,110 +Click-7.0.dist-info/top_level.txt,sha256=J1ZQogalYS4pphY_lPECoNMfw0HzTSrZglC4Yfwo4xA,6 +click/__init__.py,sha256=HjGThQ7tef9kkwCV371TBnrf0SAi6fKfU_jtEnbYTvQ,2789 +click/_bashcomplete.py,sha256=iaNUmtxag0YPfxba3TDYCNietiTMQIrvhRLj-H8okFU,11014 +click/_compat.py,sha256=vYmvoj4opPxo-c-2GMQQjYT_r_QkOKybkfGoeVrt0dA,23399 +click/_termui_impl.py,sha256=xHmLtOJhKUCVD6168yucJ9fknUJPAMs0eUTPgVUO-GQ,19611 +click/_textwrap.py,sha256=gwS4m7bdQiJnzaDG8osFcRb-5vn4t4l2qSCy-5csCEc,1198 +click/_unicodefun.py,sha256=QHy2_5jYlX-36O-JVrTHNnHOqg8tquUR0HmQFev7Ics,4364 +click/_winconsole.py,sha256=PPWVak8Iikm_gAPsxMrzwsVFCvHgaW3jPaDWZ1JBl3U,8965 +click/core.py,sha256=q8FLcDZsagBGSRe5Y9Hi_FGvAeZvusNfoO5EkhkSQ8Y,75305 +click/decorators.py,sha256=idKt6duLUUfAFftrHoREi8MJSd39XW36pUVHthdglwk,11226 +click/exceptions.py,sha256=CNpAjBAE7qjaV4WChxQeak95e5yUOau8AsvT-8m6wss,7663 +click/formatting.py,sha256=eh-cypTUAhpI3HD-K4ZpR3vCiURIO62xXvKkR3tNUTM,8889 +click/globals.py,sha256=oQkou3ZQ5DgrbVM6BwIBirwiqozbjfirzsLGAlLRRdg,1514 +click/parser.py,sha256=m-nGZz4VwprM42_qtFlWFGo7yRJQxkBlRcZodoH593Y,15510 +click/termui.py,sha256=o_ZXB2jyvL2Rce7P_bFGq452iyBq9ykJyRApIPMCZO0,23207 +click/testing.py,sha256=aYGqY_iWLu2p4k7lkuJ6t3fqpf6aPGqTsyLzNY_ngKg,13062 +click/types.py,sha256=2Q929p-aBP_ZYuMFJqJR-Ipucofv3fmDc5JzBDPmzJU,23287 +click/utils.py,sha256=6-D0WkAxvv9FkgHXSHwDIv0l9Gdx9Mm6Z5vuKNLIfZI,15763 +Click-7.0.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +click/__pycache__/parser.cpython-36.pyc,, +click/__pycache__/exceptions.cpython-36.pyc,, +click/__pycache__/formatting.cpython-36.pyc,, +click/__pycache__/testing.cpython-36.pyc,, +click/__pycache__/types.cpython-36.pyc,, +click/__pycache__/_bashcomplete.cpython-36.pyc,, +click/__pycache__/_compat.cpython-36.pyc,, +click/__pycache__/_winconsole.cpython-36.pyc,, +click/__pycache__/_unicodefun.cpython-36.pyc,, +click/__pycache__/utils.cpython-36.pyc,, +click/__pycache__/_textwrap.cpython-36.pyc,, +click/__pycache__/core.cpython-36.pyc,, +click/__pycache__/termui.cpython-36.pyc,, +click/__pycache__/__init__.cpython-36.pyc,, +click/__pycache__/globals.cpython-36.pyc,, +click/__pycache__/decorators.cpython-36.pyc,, +click/__pycache__/_termui_impl.cpython-36.pyc,, diff --git a/flask/venv/lib/python3.6/site-packages/Click-7.0.dist-info/WHEEL b/flask/venv/lib/python3.6/site-packages/Click-7.0.dist-info/WHEEL new file mode 100644 index 0000000..1316c41 --- /dev/null +++ b/flask/venv/lib/python3.6/site-packages/Click-7.0.dist-info/WHEEL @@ -0,0 +1,6 @@ +Wheel-Version: 1.0 +Generator: bdist_wheel (0.31.1) +Root-Is-Purelib: true +Tag: py2-none-any +Tag: py3-none-any + diff --git a/flask/venv/lib/python3.6/site-packages/Click-7.0.dist-info/top_level.txt b/flask/venv/lib/python3.6/site-packages/Click-7.0.dist-info/top_level.txt new file mode 100644 index 0000000..dca9a90 --- /dev/null +++ b/flask/venv/lib/python3.6/site-packages/Click-7.0.dist-info/top_level.txt @@ -0,0 +1 @@ +click diff --git a/flask/venv/lib/python3.6/site-packages/Flask-1.0.2.dist-info/INSTALLER b/flask/venv/lib/python3.6/site-packages/Flask-1.0.2.dist-info/INSTALLER new file mode 100644 index 0000000..a1b589e --- /dev/null +++ b/flask/venv/lib/python3.6/site-packages/Flask-1.0.2.dist-info/INSTALLER @@ -0,0 +1 @@ +pip diff --git a/flask/venv/lib/python3.6/site-packages/Flask-1.0.2.dist-info/LICENSE.txt b/flask/venv/lib/python3.6/site-packages/Flask-1.0.2.dist-info/LICENSE.txt new file mode 100644 index 0000000..8f9252f --- /dev/null +++ b/flask/venv/lib/python3.6/site-packages/Flask-1.0.2.dist-info/LICENSE.txt @@ -0,0 +1,31 @@ +Copyright © 2010 by the Pallets team. + +Some rights reserved. + +Redistribution and use in source and binary forms of the software as +well as documentation, 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 holder nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE AND DOCUMENTATION 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 AND DOCUMENTATION, EVEN IF ADVISED OF THE POSSIBILITY OF +SUCH DAMAGE. diff --git a/flask/venv/lib/python3.6/site-packages/Flask-1.0.2.dist-info/METADATA b/flask/venv/lib/python3.6/site-packages/Flask-1.0.2.dist-info/METADATA new file mode 100644 index 0000000..c600e73 --- /dev/null +++ b/flask/venv/lib/python3.6/site-packages/Flask-1.0.2.dist-info/METADATA @@ -0,0 +1,130 @@ +Metadata-Version: 2.1 +Name: Flask +Version: 1.0.2 +Summary: A simple framework for building complex web applications. +Home-page: https://www.palletsprojects.com/p/flask/ +Author: Armin Ronacher +Author-email: armin.ronacher@active-4.com +Maintainer: Pallets team +Maintainer-email: contact@palletsprojects.com +License: BSD +Project-URL: Documentation, http://flask.pocoo.org/docs/ +Project-URL: Code, https://github.com/pallets/flask +Project-URL: Issue tracker, https://github.com/pallets/flask/issues +Platform: any +Classifier: Development Status :: 5 - Production/Stable +Classifier: Environment :: Web Environment +Classifier: Framework :: Flask +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: Topic :: Internet :: WWW/HTTP :: Dynamic Content +Classifier: Topic :: Internet :: WWW/HTTP :: WSGI :: Application +Classifier: Topic :: Software Development :: Libraries :: Application Frameworks +Classifier: Topic :: Software Development :: Libraries :: Python Modules +Provides-Extra: dev +Provides-Extra: docs +Provides-Extra: dotenv +Requires-Dist: Werkzeug (>=0.14) +Requires-Dist: Jinja2 (>=2.10) +Requires-Dist: itsdangerous (>=0.24) +Requires-Dist: click (>=5.1) +Provides-Extra: dev +Requires-Dist: pytest (>=3); extra == 'dev' +Requires-Dist: coverage; extra == 'dev' +Requires-Dist: tox; extra == 'dev' +Requires-Dist: sphinx; extra == 'dev' +Requires-Dist: pallets-sphinx-themes; extra == 'dev' +Requires-Dist: sphinxcontrib-log-cabinet; extra == 'dev' +Provides-Extra: docs +Requires-Dist: sphinx; extra == 'docs' +Requires-Dist: pallets-sphinx-themes; extra == 'docs' +Requires-Dist: sphinxcontrib-log-cabinet; extra == 'docs' +Provides-Extra: dotenv +Requires-Dist: python-dotenv; extra == 'dotenv' + +Flask +===== + +Flask is a lightweight `WSGI`_ web application framework. It is designed +to make getting started quick and easy, with the ability to scale up to +complex applications. It began as a simple wrapper around `Werkzeug`_ +and `Jinja`_ and has become one of the most popular Python web +application frameworks. + +Flask offers suggestions, but doesn't enforce any dependencies or +project layout. It is up to the developer to choose the tools and +libraries they want to use. There are many extensions provided by the +community that make adding new functionality easy. + + +Installing +---------- + +Install and update using `pip`_: + +.. code-block:: text + + pip install -U Flask + + +A Simple Example +---------------- + +.. code-block:: python + + from flask import Flask + + app = Flask(__name__) + + @app.route('/') + def hello(): + return 'Hello, World!' + +.. code-block:: text + + $ FLASK_APP=hello.py flask run + * Serving Flask app "hello" + * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit) + + +Donate +------ + +The Pallets organization develops and supports Flask and the libraries +it uses. In order to grow the community of contributors and users, and +allow the maintainers to devote more time to the projects, `please +donate today`_. + +.. _please donate today: https://psfmember.org/civicrm/contribute/transact?reset=1&id=20 + + +Links +----- + +* Website: https://www.palletsprojects.com/p/flask/ +* Documentation: http://flask.pocoo.org/docs/ +* License: `BSD `_ +* Releases: https://pypi.org/project/Flask/ +* Code: https://github.com/pallets/flask +* Issue tracker: https://github.com/pallets/flask/issues +* Test status: + + * Linux, Mac: https://travis-ci.org/pallets/flask + * Windows: https://ci.appveyor.com/project/pallets/flask + +* Test coverage: https://codecov.io/gh/pallets/flask + +.. _WSGI: https://wsgi.readthedocs.io +.. _Werkzeug: https://www.palletsprojects.com/p/werkzeug/ +.. _Jinja: https://www.palletsprojects.com/p/jinja/ +.. _pip: https://pip.pypa.io/en/stable/quickstart/ + + diff --git a/flask/venv/lib/python3.6/site-packages/Flask-1.0.2.dist-info/RECORD b/flask/venv/lib/python3.6/site-packages/Flask-1.0.2.dist-info/RECORD new file mode 100644 index 0000000..b3b3a98 --- /dev/null +++ b/flask/venv/lib/python3.6/site-packages/Flask-1.0.2.dist-info/RECORD @@ -0,0 +1,48 @@ +Flask-1.0.2.dist-info/LICENSE.txt,sha256=ziEXA3AIuaiUn1qe4cd1XxCESWTYrk4TjN7Qb06J3l8,1575 +Flask-1.0.2.dist-info/METADATA,sha256=iA5tiNWzTtgCVe80aTZGNWsckj853fJyfvHs9U-WZRk,4182 +Flask-1.0.2.dist-info/RECORD,, +Flask-1.0.2.dist-info/WHEEL,sha256=J3CsTk7Mf2JNUyhImI-mjX-fmI4oDjyiXgWT4qgZiCE,110 +Flask-1.0.2.dist-info/entry_points.txt,sha256=gBLA1aKg0OYR8AhbAfg8lnburHtKcgJLDU52BBctN0k,42 +Flask-1.0.2.dist-info/top_level.txt,sha256=dvi65F6AeGWVU0TBpYiC04yM60-FX1gJFkK31IKQr5c,6 +flask/__init__.py,sha256=qq8lK6QQbxJALf1igz7qsvUwOTAoKvFGfdLm7jPNsso,1673 +flask/__main__.py,sha256=pgIXrHhxM5MAMvgzAqWpw_t6AXZ1zG38us4JRgJKtxk,291 +flask/_compat.py,sha256=UDFGhosh6mOdNB-4evKPuneHum1OpcAlwTNJCRm0irQ,2892 +flask/app.py,sha256=ahpe3T8w98rQd_Er5d7uDxK57S1nnqGQx3V3hirBovU,94147 +flask/blueprints.py,sha256=Cyhl_x99tgwqEZPtNDJUFneAfVJxWfEU4bQA7zWS6VU,18331 +flask/cli.py,sha256=30QYAO10Do9LbZYCLgfI_xhKjASdLopL8wKKVUGS2oA,29442 +flask/config.py,sha256=kznUhj4DLYxsTF_4kfDG8GEHto1oZG_kqblyrLFtpqQ,9951 +flask/ctx.py,sha256=leFzS9fzmo0uaLCdxpHc5_iiJZ1H0X_Ig4yPCOvT--g,16224 +flask/debughelpers.py,sha256=1ceC-UyqZTd4KsJkf0OObHPsVt5R3T6vnmYhiWBjV-w,6479 +flask/globals.py,sha256=pGg72QW_-4xUfsI33I5L_y76c21AeqfSqXDcbd8wvXU,1649 +flask/helpers.py,sha256=YCl8D1plTO1evEYP4KIgaY3H8Izww5j4EdgRJ89oHTw,40106 +flask/logging.py,sha256=qV9h0vt7NIRkKM9OHDWndzO61E5CeBMlqPJyTt-W2Wc,2231 +flask/sessions.py,sha256=2XHV4ASREhSEZ8bsPQW6pNVNuFtbR-04BzfKg0AfvHo,14452 +flask/signals.py,sha256=BGQbVyCYXnzKK2DVCzppKFyWN1qmrtW1QMAYUs-1Nr8,2211 +flask/templating.py,sha256=FDfWMbpgpC3qObW8GGXRAVrkHFF8K4CHOJymB1wvULI,4914 +flask/testing.py,sha256=XD3gWNvLUV8dqVHwKd9tZzsj81fSHtjOphQ1wTNtlMs,9379 +flask/views.py,sha256=Wy-_WkUVtCfE2zCXYeJehNgHuEtviE4v3HYfJ--MpbY,5733 +flask/wrappers.py,sha256=1Z9hF5-hXQajn_58XITQFRY8efv3Vy3uZ0avBfZu6XI,7511 +flask/json/__init__.py,sha256=Ns1Hj805XIxuBMh2z0dYnMVfb_KUgLzDmP3WoUYaPhw,10729 +flask/json/tag.py,sha256=9ehzrmt5k7hxf7ZEK0NOs3swvQyU9fWNe-pnYe69N60,8223 +../../../bin/flask,sha256=I9qLww0uCR0wcAgxnwmu248g2tkjS2Jwml3mnV5vTZw,255 +Flask-1.0.2.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +flask/__pycache__/blueprints.cpython-36.pyc,, +flask/__pycache__/logging.cpython-36.pyc,, +flask/__pycache__/sessions.cpython-36.pyc,, +flask/__pycache__/templating.cpython-36.pyc,, +flask/__pycache__/cli.cpython-36.pyc,, +flask/__pycache__/config.cpython-36.pyc,, +flask/__pycache__/signals.cpython-36.pyc,, +flask/__pycache__/testing.cpython-36.pyc,, +flask/__pycache__/views.cpython-36.pyc,, +flask/__pycache__/ctx.cpython-36.pyc,, +flask/__pycache__/app.cpython-36.pyc,, +flask/__pycache__/__main__.cpython-36.pyc,, +flask/__pycache__/_compat.cpython-36.pyc,, +flask/__pycache__/helpers.cpython-36.pyc,, +flask/__pycache__/wrappers.cpython-36.pyc,, +flask/__pycache__/__init__.cpython-36.pyc,, +flask/__pycache__/debughelpers.cpython-36.pyc,, +flask/__pycache__/globals.cpython-36.pyc,, +flask/json/__pycache__/tag.cpython-36.pyc,, +flask/json/__pycache__/__init__.cpython-36.pyc,, diff --git a/flask/venv/lib/python3.6/site-packages/Flask-1.0.2.dist-info/WHEEL b/flask/venv/lib/python3.6/site-packages/Flask-1.0.2.dist-info/WHEEL new file mode 100644 index 0000000..f21b51c --- /dev/null +++ b/flask/venv/lib/python3.6/site-packages/Flask-1.0.2.dist-info/WHEEL @@ -0,0 +1,6 @@ +Wheel-Version: 1.0 +Generator: bdist_wheel (0.31.0) +Root-Is-Purelib: true +Tag: py2-none-any +Tag: py3-none-any + diff --git a/flask/venv/lib/python3.6/site-packages/Flask-1.0.2.dist-info/entry_points.txt b/flask/venv/lib/python3.6/site-packages/Flask-1.0.2.dist-info/entry_points.txt new file mode 100644 index 0000000..1eb0252 --- /dev/null +++ b/flask/venv/lib/python3.6/site-packages/Flask-1.0.2.dist-info/entry_points.txt @@ -0,0 +1,3 @@ +[console_scripts] +flask = flask.cli:main + diff --git a/flask/venv/lib/python3.6/site-packages/Flask-1.0.2.dist-info/top_level.txt b/flask/venv/lib/python3.6/site-packages/Flask-1.0.2.dist-info/top_level.txt new file mode 100644 index 0000000..7e10602 --- /dev/null +++ b/flask/venv/lib/python3.6/site-packages/Flask-1.0.2.dist-info/top_level.txt @@ -0,0 +1 @@ +flask diff --git a/flask/venv/lib/python3.6/site-packages/Jinja2-2.10.dist-info/DESCRIPTION.rst b/flask/venv/lib/python3.6/site-packages/Jinja2-2.10.dist-info/DESCRIPTION.rst new file mode 100644 index 0000000..1594da5 --- /dev/null +++ b/flask/venv/lib/python3.6/site-packages/Jinja2-2.10.dist-info/DESCRIPTION.rst @@ -0,0 +1,37 @@ + +Jinja2 +~~~~~~ + +Jinja2 is a template engine written in pure Python. It provides a +`Django`_ inspired non-XML syntax but supports inline expressions and +an optional `sandboxed`_ environment. + +Nutshell +-------- + +Here a small example of a Jinja template:: + + {% extends 'base.html' %} + {% block title %}Memberlist{% endblock %} + {% block content %} + + {% endblock %} + +Philosophy +---------- + +Application logic is for the controller but don't try to make the life +for the template designer too hard by giving him too few functionality. + +For more informations visit the new `Jinja2 webpage`_ and `documentation`_. + +.. _sandboxed: https://en.wikipedia.org/wiki/Sandbox_(computer_security) +.. _Django: https://www.djangoproject.com/ +.. _Jinja2 webpage: http://jinja.pocoo.org/ +.. _documentation: http://jinja.pocoo.org/2/documentation/ + + diff --git a/flask/venv/lib/python3.6/site-packages/Jinja2-2.10.dist-info/INSTALLER b/flask/venv/lib/python3.6/site-packages/Jinja2-2.10.dist-info/INSTALLER new file mode 100644 index 0000000..a1b589e --- /dev/null +++ b/flask/venv/lib/python3.6/site-packages/Jinja2-2.10.dist-info/INSTALLER @@ -0,0 +1 @@ +pip diff --git a/flask/venv/lib/python3.6/site-packages/Jinja2-2.10.dist-info/LICENSE.txt b/flask/venv/lib/python3.6/site-packages/Jinja2-2.10.dist-info/LICENSE.txt new file mode 100644 index 0000000..10145a2 --- /dev/null +++ b/flask/venv/lib/python3.6/site-packages/Jinja2-2.10.dist-info/LICENSE.txt @@ -0,0 +1,31 @@ +Copyright (c) 2009 by the Jinja Team, see AUTHORS for more details. + +Some 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. + + * The names of the contributors may not 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 +OWNER 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/flask/venv/lib/python3.6/site-packages/Jinja2-2.10.dist-info/METADATA b/flask/venv/lib/python3.6/site-packages/Jinja2-2.10.dist-info/METADATA new file mode 100644 index 0000000..40f2b46 --- /dev/null +++ b/flask/venv/lib/python3.6/site-packages/Jinja2-2.10.dist-info/METADATA @@ -0,0 +1,68 @@ +Metadata-Version: 2.0 +Name: Jinja2 +Version: 2.10 +Summary: A small but fast and easy to use stand-alone template engine written in pure python. +Home-page: http://jinja.pocoo.org/ +Author: Armin Ronacher +Author-email: armin.ronacher@active-4.com +License: BSD +Description-Content-Type: UNKNOWN +Platform: UNKNOWN +Classifier: Development Status :: 5 - Production/Stable +Classifier: Environment :: Web Environment +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.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: Topic :: Internet :: WWW/HTTP :: Dynamic Content +Classifier: Topic :: Software Development :: Libraries :: Python Modules +Classifier: Topic :: Text Processing :: Markup :: HTML +Requires-Dist: MarkupSafe (>=0.23) +Provides-Extra: i18n +Requires-Dist: Babel (>=0.8); extra == 'i18n' + + +Jinja2 +~~~~~~ + +Jinja2 is a template engine written in pure Python. It provides a +`Django`_ inspired non-XML syntax but supports inline expressions and +an optional `sandboxed`_ environment. + +Nutshell +-------- + +Here a small example of a Jinja template:: + + {% extends 'base.html' %} + {% block title %}Memberlist{% endblock %} + {% block content %} + + {% endblock %} + +Philosophy +---------- + +Application logic is for the controller but don't try to make the life +for the template designer too hard by giving him too few functionality. + +For more informations visit the new `Jinja2 webpage`_ and `documentation`_. + +.. _sandboxed: https://en.wikipedia.org/wiki/Sandbox_(computer_security) +.. _Django: https://www.djangoproject.com/ +.. _Jinja2 webpage: http://jinja.pocoo.org/ +.. _documentation: http://jinja.pocoo.org/2/documentation/ + + diff --git a/flask/venv/lib/python3.6/site-packages/Jinja2-2.10.dist-info/RECORD b/flask/venv/lib/python3.6/site-packages/Jinja2-2.10.dist-info/RECORD new file mode 100644 index 0000000..e4d7ce6 --- /dev/null +++ b/flask/venv/lib/python3.6/site-packages/Jinja2-2.10.dist-info/RECORD @@ -0,0 +1,63 @@ +Jinja2-2.10.dist-info/DESCRIPTION.rst,sha256=b5ckFDoM7vVtz_mAsJD4OPteFKCqE7beu353g4COoYI,978 +Jinja2-2.10.dist-info/LICENSE.txt,sha256=JvzUNv3Io51EiWrAPm8d_SXjhJnEjyDYvB3Tvwqqils,1554 +Jinja2-2.10.dist-info/METADATA,sha256=18EgU8zR6-av-0-5y_gXebzK4GnBB_76lALUsl-6QHM,2258 +Jinja2-2.10.dist-info/RECORD,, +Jinja2-2.10.dist-info/WHEEL,sha256=kdsN-5OJAZIiHN-iO4Rhl82KyS0bDWf4uBwMbkNafr8,110 +Jinja2-2.10.dist-info/entry_points.txt,sha256=NdzVcOrqyNyKDxD09aERj__3bFx2paZhizFDsKmVhiA,72 +Jinja2-2.10.dist-info/metadata.json,sha256=NPUJ9TMBxVQAv_kTJzvU8HwmP-4XZvbK9mz6_4YUVl4,1473 +Jinja2-2.10.dist-info/top_level.txt,sha256=PkeVWtLb3-CqjWi1fO29OCbj55EhX_chhKrCdrVe_zs,7 +jinja2/__init__.py,sha256=xJHjaMoy51_KXn1wf0cysH6tUUifUxZCwSOfcJGEYZw,2614 +jinja2/_compat.py,sha256=xP60CE5Qr8FTYcDE1f54tbZLKGvMwYml4-8T7Q4KG9k,2596 +jinja2/_identifier.py,sha256=W1QBSY-iJsyt6oR_nKSuNNCzV95vLIOYgUNPUI1d5gU,1726 +jinja2/asyncfilters.py,sha256=cTDPvrS8Hp_IkwsZ1m9af_lr5nHysw7uTa5gV0NmZVE,4144 +jinja2/asyncsupport.py,sha256=UErQ3YlTLaSjFb94P4MVn08-aVD9jJxty2JVfMRb-1M,7878 +jinja2/bccache.py,sha256=nQldx0ZRYANMyfvOihRoYFKSlUdd5vJkS7BjxNwlOZM,12794 +jinja2/compiler.py,sha256=BqC5U6JxObSRhblyT_a6Tp5GtEU5z3US1a4jLQaxxgo,65386 +jinja2/constants.py,sha256=uwwV8ZUhHhacAuz5PTwckfsbqBaqM7aKfyJL7kGX5YQ,1626 +jinja2/debug.py,sha256=WTVeUFGUa4v6ReCsYv-iVPa3pkNB75OinJt3PfxNdXs,12045 +jinja2/defaults.py,sha256=Em-95hmsJxIenDCZFB1YSvf9CNhe9rBmytN3yUrBcWA,1400 +jinja2/environment.py,sha256=VnkAkqw8JbjZct4tAyHlpBrka2vqB-Z58RAP-32P1ZY,50849 +jinja2/exceptions.py,sha256=_Rj-NVi98Q6AiEjYQOsP8dEIdu5AlmRHzcSNOPdWix4,4428 +jinja2/ext.py,sha256=atMQydEC86tN1zUsdQiHw5L5cF62nDbqGue25Yiu3N4,24500 +jinja2/filters.py,sha256=yOAJk0MsH-_gEC0i0U6NweVQhbtYaC-uE8xswHFLF4w,36528 +jinja2/idtracking.py,sha256=2GbDSzIvGArEBGLkovLkqEfmYxmWsEf8c3QZwM4uNsw,9197 +jinja2/lexer.py,sha256=ySEPoXd1g7wRjsuw23uimS6nkGN5aqrYwcOKxCaVMBQ,28559 +jinja2/loaders.py,sha256=xiTuURKAEObyym0nU8PCIXu_Qp8fn0AJ5oIADUUm-5Q,17382 +jinja2/meta.py,sha256=fmKHxkmZYAOm9QyWWy8EMd6eefAIh234rkBMW2X4ZR8,4340 +jinja2/nativetypes.py,sha256=_sJhS8f-8Q0QMIC0dm1YEdLyxEyoO-kch8qOL5xUDfE,7308 +jinja2/nodes.py,sha256=L10L_nQDfubLhO3XjpF9qz46FSh2clL-3e49ogVlMmA,30853 +jinja2/optimizer.py,sha256=MsdlFACJ0FRdPtjmCAdt7JQ9SGrXFaDNUaslsWQaG3M,1722 +jinja2/parser.py,sha256=lPzTEbcpTRBLw8ii6OYyExHeAhaZLMA05Hpv4ll3ULk,35875 +jinja2/runtime.py,sha256=DHdD38Pq8gj7uWQC5usJyWFoNWL317A9AvXOW_CLB34,27755 +jinja2/sandbox.py,sha256=TVyZHlNqqTzsv9fv2NvJNmSdWRHTguhyMHdxjWms32U,16708 +jinja2/tests.py,sha256=iJQLwbapZr-EKquTG_fVOVdwHUUKf3SX9eNkjQDF8oU,4237 +jinja2/utils.py,sha256=q24VupGZotQ-uOyrJxCaXtDWhZC1RgsQG7kcdmjck2Q,20629 +jinja2/visitor.py,sha256=JD1H1cANA29JcntFfN5fPyqQxB4bI4wC00BzZa-XHks,3316 +Jinja2-2.10.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +jinja2/__pycache__/lexer.cpython-36.pyc,, +jinja2/__pycache__/sandbox.cpython-36.pyc,, +jinja2/__pycache__/debug.cpython-36.pyc,, +jinja2/__pycache__/constants.cpython-36.pyc,, +jinja2/__pycache__/idtracking.cpython-36.pyc,, +jinja2/__pycache__/parser.cpython-36.pyc,, +jinja2/__pycache__/exceptions.cpython-36.pyc,, +jinja2/__pycache__/ext.cpython-36.pyc,, +jinja2/__pycache__/meta.cpython-36.pyc,, +jinja2/__pycache__/environment.cpython-36.pyc,, +jinja2/__pycache__/loaders.cpython-36.pyc,, +jinja2/__pycache__/asyncsupport.cpython-36.pyc,, +jinja2/__pycache__/asyncfilters.cpython-36.pyc,, +jinja2/__pycache__/tests.cpython-36.pyc,, +jinja2/__pycache__/optimizer.cpython-36.pyc,, +jinja2/__pycache__/compiler.cpython-36.pyc,, +jinja2/__pycache__/bccache.cpython-36.pyc,, +jinja2/__pycache__/_identifier.cpython-36.pyc,, +jinja2/__pycache__/_compat.cpython-36.pyc,, +jinja2/__pycache__/defaults.cpython-36.pyc,, +jinja2/__pycache__/utils.cpython-36.pyc,, +jinja2/__pycache__/nodes.cpython-36.pyc,, +jinja2/__pycache__/filters.cpython-36.pyc,, +jinja2/__pycache__/runtime.cpython-36.pyc,, +jinja2/__pycache__/__init__.cpython-36.pyc,, +jinja2/__pycache__/nativetypes.cpython-36.pyc,, +jinja2/__pycache__/visitor.cpython-36.pyc,, diff --git a/flask/venv/lib/python3.6/site-packages/Jinja2-2.10.dist-info/WHEEL b/flask/venv/lib/python3.6/site-packages/Jinja2-2.10.dist-info/WHEEL new file mode 100644 index 0000000..7332a41 --- /dev/null +++ b/flask/venv/lib/python3.6/site-packages/Jinja2-2.10.dist-info/WHEEL @@ -0,0 +1,6 @@ +Wheel-Version: 1.0 +Generator: bdist_wheel (0.30.0) +Root-Is-Purelib: true +Tag: py2-none-any +Tag: py3-none-any + diff --git a/flask/venv/lib/python3.6/site-packages/Jinja2-2.10.dist-info/entry_points.txt b/flask/venv/lib/python3.6/site-packages/Jinja2-2.10.dist-info/entry_points.txt new file mode 100644 index 0000000..32e6b75 --- /dev/null +++ b/flask/venv/lib/python3.6/site-packages/Jinja2-2.10.dist-info/entry_points.txt @@ -0,0 +1,4 @@ + + [babel.extractors] + jinja2 = jinja2.ext:babel_extract[i18n] + \ No newline at end of file diff --git a/flask/venv/lib/python3.6/site-packages/Jinja2-2.10.dist-info/metadata.json b/flask/venv/lib/python3.6/site-packages/Jinja2-2.10.dist-info/metadata.json new file mode 100644 index 0000000..7f5dc38 --- /dev/null +++ b/flask/venv/lib/python3.6/site-packages/Jinja2-2.10.dist-info/metadata.json @@ -0,0 +1 @@ +{"classifiers": ["Development Status :: 5 - Production/Stable", "Environment :: Web Environment", "Intended Audience :: Developers", "License :: OSI Approved :: BSD License", "Operating System :: OS Independent", "Programming Language :: Python", "Programming Language :: Python :: 2", "Programming Language :: Python :: 2.6", "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 :: Internet :: WWW/HTTP :: Dynamic Content", "Topic :: Software Development :: Libraries :: Python Modules", "Topic :: Text Processing :: Markup :: HTML"], "description_content_type": "UNKNOWN", "extensions": {"python.details": {"contacts": [{"email": "armin.ronacher@active-4.com", "name": "Armin Ronacher", "role": "author"}], "document_names": {"description": "DESCRIPTION.rst", "license": "LICENSE.txt"}, "project_urls": {"Home": "http://jinja.pocoo.org/"}}, "python.exports": {"babel.extractors": {"jinja2": "jinja2.ext:babel_extract [i18n]"}}}, "extras": ["i18n"], "generator": "bdist_wheel (0.30.0)", "license": "BSD", "metadata_version": "2.0", "name": "Jinja2", "run_requires": [{"extra": "i18n", "requires": ["Babel (>=0.8)"]}, {"requires": ["MarkupSafe (>=0.23)"]}], "summary": "A small but fast and easy to use stand-alone template engine written in pure python.", "version": "2.10"} \ No newline at end of file diff --git a/flask/venv/lib/python3.6/site-packages/Jinja2-2.10.dist-info/top_level.txt b/flask/venv/lib/python3.6/site-packages/Jinja2-2.10.dist-info/top_level.txt new file mode 100644 index 0000000..7f7afbf --- /dev/null +++ b/flask/venv/lib/python3.6/site-packages/Jinja2-2.10.dist-info/top_level.txt @@ -0,0 +1 @@ +jinja2 diff --git a/flask/venv/lib/python3.6/site-packages/MarkupSafe-1.1.1.dist-info/INSTALLER b/flask/venv/lib/python3.6/site-packages/MarkupSafe-1.1.1.dist-info/INSTALLER new file mode 100644 index 0000000..a1b589e --- /dev/null +++ b/flask/venv/lib/python3.6/site-packages/MarkupSafe-1.1.1.dist-info/INSTALLER @@ -0,0 +1 @@ +pip diff --git a/flask/venv/lib/python3.6/site-packages/MarkupSafe-1.1.1.dist-info/LICENSE.rst b/flask/venv/lib/python3.6/site-packages/MarkupSafe-1.1.1.dist-info/LICENSE.rst new file mode 100644 index 0000000..9d227a0 --- /dev/null +++ b/flask/venv/lib/python3.6/site-packages/MarkupSafe-1.1.1.dist-info/LICENSE.rst @@ -0,0 +1,28 @@ +Copyright 2010 Pallets + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + +1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + +2. 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. + +3. Neither the name of the copyright holder nor the names 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/flask/venv/lib/python3.6/site-packages/MarkupSafe-1.1.1.dist-info/METADATA b/flask/venv/lib/python3.6/site-packages/MarkupSafe-1.1.1.dist-info/METADATA new file mode 100644 index 0000000..b208d93 --- /dev/null +++ b/flask/venv/lib/python3.6/site-packages/MarkupSafe-1.1.1.dist-info/METADATA @@ -0,0 +1,103 @@ +Metadata-Version: 2.1 +Name: MarkupSafe +Version: 1.1.1 +Summary: Safely add untrusted strings to HTML/XML markup. +Home-page: https://palletsprojects.com/p/markupsafe/ +Author: Armin Ronacher +Author-email: armin.ronacher@active-4.com +Maintainer: The Pallets Team +Maintainer-email: contact@palletsprojects.com +License: BSD-3-Clause +Project-URL: Documentation, https://markupsafe.palletsprojects.com/ +Project-URL: Code, https://github.com/pallets/markupsafe +Project-URL: Issue tracker, https://github.com/pallets/markupsafe/issues +Platform: UNKNOWN +Classifier: Development Status :: 5 - Production/Stable +Classifier: Environment :: Web Environment +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 :: 3.7 +Classifier: Topic :: Internet :: WWW/HTTP :: Dynamic Content +Classifier: Topic :: Software Development :: Libraries :: Python Modules +Classifier: Topic :: Text Processing :: Markup :: HTML +Requires-Python: >=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.* + +MarkupSafe +========== + +MarkupSafe implements a text object that escapes characters so it is +safe to use in HTML and XML. Characters that have special meanings are +replaced so that they display as the actual characters. This mitigates +injection attacks, meaning untrusted user input can safely be displayed +on a page. + + +Installing +---------- + +Install and update using `pip`_: + +.. code-block:: text + + pip install -U MarkupSafe + +.. _pip: https://pip.pypa.io/en/stable/quickstart/ + + +Examples +-------- + +.. code-block:: pycon + + >>> from markupsafe import Markup, escape + >>> # escape replaces special characters and wraps in Markup + >>> escape('') + Markup(u'<script>alert(document.cookie);</script>') + >>> # wrap in Markup to mark text "safe" and prevent escaping + >>> Markup('Hello') + Markup('hello') + >>> escape(Markup('Hello')) + Markup('hello') + >>> # Markup is a text subclass (str on Python 3, unicode on Python 2) + >>> # methods and operators escape their arguments + >>> template = Markup("Hello %s") + >>> template % '"World"' + Markup('Hello "World"') + + +Donate +------ + +The Pallets organization develops and supports MarkupSafe and other +libraries that use it. In order to grow the community of contributors +and users, and allow the maintainers to devote more time to the +projects, `please donate today`_. + +.. _please donate today: https://palletsprojects.com/donate + + +Links +----- + +* Website: https://palletsprojects.com/p/markupsafe/ +* Documentation: https://markupsafe.palletsprojects.com/ +* License: `BSD-3-Clause `_ +* Releases: https://pypi.org/project/MarkupSafe/ +* Code: https://github.com/pallets/markupsafe +* Issue tracker: https://github.com/pallets/markupsafe/issues +* Test status: + + * Linux, Mac: https://travis-ci.org/pallets/markupsafe + * Windows: https://ci.appveyor.com/project/pallets/markupsafe + +* Test coverage: https://codecov.io/gh/pallets/markupsafe + + diff --git a/flask/venv/lib/python3.6/site-packages/MarkupSafe-1.1.1.dist-info/RECORD b/flask/venv/lib/python3.6/site-packages/MarkupSafe-1.1.1.dist-info/RECORD new file mode 100644 index 0000000..5235a53 --- /dev/null +++ b/flask/venv/lib/python3.6/site-packages/MarkupSafe-1.1.1.dist-info/RECORD @@ -0,0 +1,16 @@ +markupsafe/__init__.py,sha256=oTblO5f9KFM-pvnq9bB0HgElnqkJyqHnFN1Nx2NIvnY,10126 +markupsafe/_compat.py,sha256=uEW1ybxEjfxIiuTbRRaJpHsPFf4yQUMMKaPgYEC5XbU,558 +markupsafe/_constants.py,sha256=zo2ajfScG-l1Sb_52EP3MlDCqO7Y1BVHUXXKRsVDRNk,4690 +markupsafe/_native.py,sha256=d-8S_zzYt2y512xYcuSxq0NeG2DUUvG80wVdTn-4KI8,1873 +markupsafe/_speedups.c,sha256=k0fzEIK3CP6MmMqeY0ob43TP90mVN0DTyn7BAl3RqSg,9884 +markupsafe/_speedups.cpython-36m-darwin.so,sha256=gAFPy56Sic0xoW6ZX3vNlSIudH37VfkTL5p5huZTCKQ,35080 +MarkupSafe-1.1.1.dist-info/LICENSE.rst,sha256=SJqOEQhQntmKN7uYPhHg9-HTHwvY-Zp5yESOf_N9B-o,1475 +MarkupSafe-1.1.1.dist-info/METADATA,sha256=nJHwJ4_4ka-V39QH883jPrslj6inNdyyNASBXbYgHXQ,3570 +MarkupSafe-1.1.1.dist-info/WHEEL,sha256=jbwwsYxUMSTI4YtVtq_YJIxL7IgPdHeCKUMmQlt2K6U,109 +MarkupSafe-1.1.1.dist-info/top_level.txt,sha256=qy0Plje5IJuvsCBjejJyhDCjEAdcDLK_2agVcex8Z6U,11 +MarkupSafe-1.1.1.dist-info/RECORD,, +MarkupSafe-1.1.1.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +markupsafe/__pycache__/_native.cpython-36.pyc,, +markupsafe/__pycache__/_constants.cpython-36.pyc,, +markupsafe/__pycache__/_compat.cpython-36.pyc,, +markupsafe/__pycache__/__init__.cpython-36.pyc,, diff --git a/flask/venv/lib/python3.6/site-packages/MarkupSafe-1.1.1.dist-info/WHEEL b/flask/venv/lib/python3.6/site-packages/MarkupSafe-1.1.1.dist-info/WHEEL new file mode 100644 index 0000000..368d7aa --- /dev/null +++ b/flask/venv/lib/python3.6/site-packages/MarkupSafe-1.1.1.dist-info/WHEEL @@ -0,0 +1,5 @@ +Wheel-Version: 1.0 +Generator: bdist_wheel (0.33.1) +Root-Is-Purelib: false +Tag: cp36-cp36m-macosx_10_6_intel + diff --git a/flask/venv/lib/python3.6/site-packages/MarkupSafe-1.1.1.dist-info/top_level.txt b/flask/venv/lib/python3.6/site-packages/MarkupSafe-1.1.1.dist-info/top_level.txt new file mode 100644 index 0000000..75bf729 --- /dev/null +++ b/flask/venv/lib/python3.6/site-packages/MarkupSafe-1.1.1.dist-info/top_level.txt @@ -0,0 +1 @@ +markupsafe diff --git a/flask/venv/lib/python3.6/site-packages/Werkzeug-0.14.1.dist-info/DESCRIPTION.rst b/flask/venv/lib/python3.6/site-packages/Werkzeug-0.14.1.dist-info/DESCRIPTION.rst new file mode 100644 index 0000000..675f08d --- /dev/null +++ b/flask/venv/lib/python3.6/site-packages/Werkzeug-0.14.1.dist-info/DESCRIPTION.rst @@ -0,0 +1,80 @@ +Werkzeug +======== + +Werkzeug is a comprehensive `WSGI`_ web application library. It began as +a simple collection of various utilities for WSGI applications and has +become one of the most advanced WSGI utility libraries. + +It includes: + +* An interactive debugger that allows inspecting stack traces and source + code in the browser with an interactive interpreter for any frame in + the stack. +* A full-featured request object with objects to interact with headers, + query args, form data, files, and cookies. +* A response object that can wrap other WSGI applications and handle + streaming data. +* A routing system for matching URLs to endpoints and generating URLs + for endpoints, with an extensible system for capturing variables from + URLs. +* HTTP utilities to handle entity tags, cache control, dates, user + agents, cookies, files, and more. +* A threaded WSGI server for use while developing applications locally. +* A test client for simulating HTTP requests during testing without + requiring running a server. + +Werkzeug is Unicode aware and doesn't enforce any dependencies. It is up +to the developer to choose a template engine, database adapter, and even +how to handle requests. It can be used to build all sorts of end user +applications such as blogs, wikis, or bulletin boards. + +`Flask`_ wraps Werkzeug, using it to handle the details of WSGI while +providing more structure and patterns for defining powerful +applications. + + +Installing +---------- + +Install and update using `pip`_: + +.. code-block:: text + + pip install -U Werkzeug + + +A Simple Example +---------------- + +.. code-block:: python + + from werkzeug.wrappers import Request, Response + + @Request.application + def application(request): + return Response('Hello, World!') + + if __name__ == '__main__': + from werkzeug.serving import run_simple + run_simple('localhost', 4000, application) + + +Links +----- + +* Website: https://www.palletsprojects.com/p/werkzeug/ +* Releases: https://pypi.org/project/Werkzeug/ +* Code: https://github.com/pallets/werkzeug +* Issue tracker: https://github.com/pallets/werkzeug/issues +* Test status: + + * Linux, Mac: https://travis-ci.org/pallets/werkzeug + * Windows: https://ci.appveyor.com/project/davidism/werkzeug + +* Test coverage: https://codecov.io/gh/pallets/werkzeug + +.. _WSGI: https://wsgi.readthedocs.io/en/latest/ +.. _Flask: https://www.palletsprojects.com/p/flask/ +.. _pip: https://pip.pypa.io/en/stable/quickstart/ + + diff --git a/flask/venv/lib/python3.6/site-packages/Werkzeug-0.14.1.dist-info/INSTALLER b/flask/venv/lib/python3.6/site-packages/Werkzeug-0.14.1.dist-info/INSTALLER new file mode 100644 index 0000000..a1b589e --- /dev/null +++ b/flask/venv/lib/python3.6/site-packages/Werkzeug-0.14.1.dist-info/INSTALLER @@ -0,0 +1 @@ +pip diff --git a/flask/venv/lib/python3.6/site-packages/Werkzeug-0.14.1.dist-info/LICENSE.txt b/flask/venv/lib/python3.6/site-packages/Werkzeug-0.14.1.dist-info/LICENSE.txt new file mode 100644 index 0000000..1cc75bb --- /dev/null +++ b/flask/venv/lib/python3.6/site-packages/Werkzeug-0.14.1.dist-info/LICENSE.txt @@ -0,0 +1,31 @@ +Copyright © 2007 by the Pallets team. + +Some 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 holder nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE AND DOCUMENTATION 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 AND DOCUMENTATION, EVEN IF ADVISED OF THE POSSIBILITY OF +SUCH DAMAGE. diff --git a/flask/venv/lib/python3.6/site-packages/Werkzeug-0.14.1.dist-info/METADATA b/flask/venv/lib/python3.6/site-packages/Werkzeug-0.14.1.dist-info/METADATA new file mode 100644 index 0000000..bfc3c4e --- /dev/null +++ b/flask/venv/lib/python3.6/site-packages/Werkzeug-0.14.1.dist-info/METADATA @@ -0,0 +1,116 @@ +Metadata-Version: 2.0 +Name: Werkzeug +Version: 0.14.1 +Summary: The comprehensive WSGI web application library. +Home-page: https://www.palletsprojects.org/p/werkzeug/ +Author: Armin Ronacher +Author-email: armin.ronacher@active-4.com +License: BSD +Description-Content-Type: UNKNOWN +Platform: any +Classifier: Development Status :: 5 - Production/Stable +Classifier: Environment :: Web Environment +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.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: Topic :: Internet :: WWW/HTTP :: Dynamic Content +Classifier: Topic :: Software Development :: Libraries :: Python Modules +Provides-Extra: dev +Requires-Dist: coverage; extra == 'dev' +Requires-Dist: pytest; extra == 'dev' +Requires-Dist: sphinx; extra == 'dev' +Requires-Dist: tox; extra == 'dev' +Provides-Extra: termcolor +Requires-Dist: termcolor; extra == 'termcolor' +Provides-Extra: watchdog +Requires-Dist: watchdog; extra == 'watchdog' + +Werkzeug +======== + +Werkzeug is a comprehensive `WSGI`_ web application library. It began as +a simple collection of various utilities for WSGI applications and has +become one of the most advanced WSGI utility libraries. + +It includes: + +* An interactive debugger that allows inspecting stack traces and source + code in the browser with an interactive interpreter for any frame in + the stack. +* A full-featured request object with objects to interact with headers, + query args, form data, files, and cookies. +* A response object that can wrap other WSGI applications and handle + streaming data. +* A routing system for matching URLs to endpoints and generating URLs + for endpoints, with an extensible system for capturing variables from + URLs. +* HTTP utilities to handle entity tags, cache control, dates, user + agents, cookies, files, and more. +* A threaded WSGI server for use while developing applications locally. +* A test client for simulating HTTP requests during testing without + requiring running a server. + +Werkzeug is Unicode aware and doesn't enforce any dependencies. It is up +to the developer to choose a template engine, database adapter, and even +how to handle requests. It can be used to build all sorts of end user +applications such as blogs, wikis, or bulletin boards. + +`Flask`_ wraps Werkzeug, using it to handle the details of WSGI while +providing more structure and patterns for defining powerful +applications. + + +Installing +---------- + +Install and update using `pip`_: + +.. code-block:: text + + pip install -U Werkzeug + + +A Simple Example +---------------- + +.. code-block:: python + + from werkzeug.wrappers import Request, Response + + @Request.application + def application(request): + return Response('Hello, World!') + + if __name__ == '__main__': + from werkzeug.serving import run_simple + run_simple('localhost', 4000, application) + + +Links +----- + +* Website: https://www.palletsprojects.com/p/werkzeug/ +* Releases: https://pypi.org/project/Werkzeug/ +* Code: https://github.com/pallets/werkzeug +* Issue tracker: https://github.com/pallets/werkzeug/issues +* Test status: + + * Linux, Mac: https://travis-ci.org/pallets/werkzeug + * Windows: https://ci.appveyor.com/project/davidism/werkzeug + +* Test coverage: https://codecov.io/gh/pallets/werkzeug + +.. _WSGI: https://wsgi.readthedocs.io/en/latest/ +.. _Flask: https://www.palletsprojects.com/p/flask/ +.. _pip: https://pip.pypa.io/en/stable/quickstart/ + + diff --git a/flask/venv/lib/python3.6/site-packages/Werkzeug-0.14.1.dist-info/RECORD b/flask/venv/lib/python3.6/site-packages/Werkzeug-0.14.1.dist-info/RECORD new file mode 100644 index 0000000..51590a6 --- /dev/null +++ b/flask/venv/lib/python3.6/site-packages/Werkzeug-0.14.1.dist-info/RECORD @@ -0,0 +1,97 @@ +Werkzeug-0.14.1.dist-info/DESCRIPTION.rst,sha256=rOCN36jwsWtWsTpqPG96z7FMilB5qI1CIARSKRuUmz8,2452 +Werkzeug-0.14.1.dist-info/LICENSE.txt,sha256=xndz_dD4m269AF9l_Xbl5V3tM1N3C1LoZC2PEPxWO-8,1534 +Werkzeug-0.14.1.dist-info/METADATA,sha256=FbfadrPdJNUWAxMOKxGUtHe5R3IDSBKYYmAz3FvI3uY,3872 +Werkzeug-0.14.1.dist-info/RECORD,, +Werkzeug-0.14.1.dist-info/WHEEL,sha256=GrqQvamwgBV4nLoJe0vhYRSWzWsx7xjlt74FT0SWYfE,110 +Werkzeug-0.14.1.dist-info/metadata.json,sha256=4489UTt6HBp2NQil95-pBkjU4Je93SMHvMxZ_rjOpqA,1452 +Werkzeug-0.14.1.dist-info/top_level.txt,sha256=QRyj2VjwJoQkrwjwFIOlB8Xg3r9un0NtqVHQF-15xaw,9 +werkzeug/__init__.py,sha256=NR0d4n_-U9BLVKlOISean3zUt2vBwhvK-AZE6M0sC0k,6842 +werkzeug/_compat.py,sha256=8c4U9o6A_TR9nKCcTbpZNxpqCXcXDVIbFawwKM2s92c,6311 +werkzeug/_internal.py,sha256=GhEyGMlsSz_tYjsDWO9TG35VN7304MM8gjKDrXLEdVc,13873 +werkzeug/_reloader.py,sha256=AyPphcOHPbu6qzW0UbrVvTDJdre5WgpxbhIJN_TqzUc,9264 +werkzeug/datastructures.py,sha256=3IgNKNqrz-ZjmAG7y3YgEYK-enDiMT_b652PsypWcYg,90080 +werkzeug/exceptions.py,sha256=3wp95Hqj9FqV8MdikV99JRcHse_fSMn27V8tgP5Hw2c,20505 +werkzeug/filesystem.py,sha256=hHWeWo_gqLMzTRfYt8-7n2wWcWUNTnDyudQDLOBEICE,2175 +werkzeug/formparser.py,sha256=mUuCwjzjb8_E4RzrAT2AioLuZSYpqR1KXTK6LScRYzA,21722 +werkzeug/http.py,sha256=RQg4MJuhRv2isNRiEh__Phh09ebpfT3Kuu_GfrZ54_c,40079 +werkzeug/local.py,sha256=QdQhWV5L8p1Y1CJ1CDStwxaUs24SuN5aebHwjVD08C8,14553 +werkzeug/posixemulation.py,sha256=xEF2Bxc-vUCPkiu4IbfWVd3LW7DROYAT-ExW6THqyzw,3519 +werkzeug/routing.py,sha256=2JVtdSgxKGeANy4Z_FP-dKESvKtkYGCZ1J2fARCLGCY,67214 +werkzeug/script.py,sha256=DwaVDcXdaOTffdNvlBdLitxWXjKaRVT32VbhDtljFPY,11365 +werkzeug/security.py,sha256=0m107exslz4QJLWQCpfQJ04z3re4eGHVggRvrQVAdWc,9193 +werkzeug/serving.py,sha256=A0flnIJHufdn2QJ9oeuHfrXwP3LzP8fn3rNW6hbxKUg,31926 +werkzeug/test.py,sha256=XmECSmnpASiYQTct4oMiWr0LT5jHWCtKqnpYKZd2ui8,36100 +werkzeug/testapp.py,sha256=3HQRW1sHZKXuAjCvFMet4KXtQG3loYTFnvn6LWt-4zI,9396 +werkzeug/urls.py,sha256=dUeLg2IeTm0WLmSvFeD4hBZWGdOs-uHudR5-t8n9zPo,36771 +werkzeug/useragents.py,sha256=BhYMf4cBTHyN4U0WsQedePIocmNlH_34C-UwqSThGCc,5865 +werkzeug/utils.py,sha256=BrY1j0DHQ8RTb0K1StIobKuMJhN9SQQkWEARbrh2qpk,22972 +werkzeug/websocket.py,sha256=PpSeDxXD_0UsPAa5hQhQNM6mxibeUgn8lA8eRqiS0vM,11344 +werkzeug/wrappers.py,sha256=kbyL_aFjxELwPgMwfNCYjKu-CR6kNkh-oO8wv3GXbk8,84511 +werkzeug/wsgi.py,sha256=1Nob-aeChWQf7MsiicO8RZt6J90iRzEcik44ev9Qu8s,49347 +werkzeug/contrib/__init__.py,sha256=f7PfttZhbrImqpr5Ezre8CXgwvcGUJK7zWNpO34WWrw,623 +werkzeug/contrib/atom.py,sha256=qqfJcfIn2RYY-3hO3Oz0aLq9YuNubcPQ_KZcNsDwVJo,15575 +werkzeug/contrib/cache.py,sha256=xBImHNj09BmX_7kC5NUCx8f_l4L8_O7zi0jCL21UZKE,32163 +werkzeug/contrib/fixers.py,sha256=gR06T-w71ur-tHQ_31kP_4jpOncPJ4Wc1dOqTvYusr8,10179 +werkzeug/contrib/iterio.py,sha256=RlqDvGhz0RneTpzE8dVc-yWCUv4nkPl1jEc_EDp2fH0,10814 +werkzeug/contrib/jsrouting.py,sha256=QTmgeDoKXvNK02KzXgx9lr3cAH6fAzpwF5bBdPNvJPs,8564 +werkzeug/contrib/limiter.py,sha256=iS8-ahPZ-JLRnmfIBzxpm7O_s3lPsiDMVWv7llAIDCI,1334 +werkzeug/contrib/lint.py,sha256=Mj9NeUN7s4zIUWeQOAVjrmtZIcl3Mm2yDe9BSIr9YGE,12558 +werkzeug/contrib/profiler.py,sha256=ISwCWvwVyGpDLRBRpLjo_qUWma6GXYBrTAco4PEQSHY,5151 +werkzeug/contrib/securecookie.py,sha256=uWMyHDHY3lkeBRiCSayGqWkAIy4a7xAbSE_Hln9ecqc,12196 +werkzeug/contrib/sessions.py,sha256=39LVNvLbm5JWpbxM79WC2l87MJFbqeISARjwYbkJatw,12577 +werkzeug/contrib/testtools.py,sha256=G9xN-qeihJlhExrIZMCahvQOIDxdL9NiX874jiiHFMs,2453 +werkzeug/contrib/wrappers.py,sha256=v7OYlz7wQtDlS9fey75UiRZ1IkUWqCpzbhsLy4k14Hw,10398 +werkzeug/debug/__init__.py,sha256=uSn9BqCZ5E3ySgpoZtundpROGsn-uYvZtSFiTfAX24M,17452 +werkzeug/debug/console.py,sha256=n3-dsKk1TsjnN-u4ZgmuWCU_HO0qw5IA7ttjhyyMM6I,5607 +werkzeug/debug/repr.py,sha256=bKqstDYGfECpeLerd48s_hxuqK4b6UWnjMu3d_DHO8I,9340 +werkzeug/debug/tbtools.py,sha256=rBudXCmkVdAKIcdhxANxgf09g6kQjJWW9_5bjSpr4OY,18451 +werkzeug/debug/shared/FONT_LICENSE,sha256=LwAVEI1oYnvXiNMT9SnCH_TaLCxCpeHziDrMg0gPkAI,4673 +werkzeug/debug/shared/console.png,sha256=bxax6RXXlvOij_KeqvSNX0ojJf83YbnZ7my-3Gx9w2A,507 +werkzeug/debug/shared/debugger.js,sha256=PKPVYuyO4SX1hkqLOwCLvmIEO5154WatFYaXE-zIfKI,6264 +werkzeug/debug/shared/jquery.js,sha256=7LkWEzqTdpEfELxcZZlS6wAx5Ff13zZ83lYO2_ujj7g,95957 +werkzeug/debug/shared/less.png,sha256=-4-kNRaXJSONVLahrQKUxMwXGm9R4OnZ9SxDGpHlIR4,191 +werkzeug/debug/shared/more.png,sha256=GngN7CioHQoV58rH6ojnkYi8c_qED2Aka5FO5UXrReY,200 +werkzeug/debug/shared/source.png,sha256=RoGcBTE4CyCB85GBuDGTFlAnUqxwTBiIfDqW15EpnUQ,818 +werkzeug/debug/shared/style.css,sha256=IEO0PC2pWmh2aEyGCaN--txuWsRCliuhlbEhPDFwh0A,6270 +werkzeug/debug/shared/ubuntu.ttf,sha256=1eaHFyepmy4FyDvjLVzpITrGEBu_CZYY94jE0nED1c0,70220 +Werkzeug-0.14.1.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +werkzeug/__pycache__/posixemulation.cpython-36.pyc,, +werkzeug/__pycache__/exceptions.cpython-36.pyc,, +werkzeug/__pycache__/websocket.cpython-36.pyc,, +werkzeug/__pycache__/datastructures.cpython-36.pyc,, +werkzeug/__pycache__/filesystem.cpython-36.pyc,, +werkzeug/__pycache__/useragents.cpython-36.pyc,, +werkzeug/__pycache__/serving.cpython-36.pyc,, +werkzeug/__pycache__/testapp.cpython-36.pyc,, +werkzeug/__pycache__/_compat.cpython-36.pyc,, +werkzeug/__pycache__/script.cpython-36.pyc,, +werkzeug/__pycache__/security.cpython-36.pyc,, +werkzeug/__pycache__/_internal.cpython-36.pyc,, +werkzeug/__pycache__/routing.cpython-36.pyc,, +werkzeug/__pycache__/_reloader.cpython-36.pyc,, +werkzeug/__pycache__/local.cpython-36.pyc,, +werkzeug/__pycache__/http.cpython-36.pyc,, +werkzeug/__pycache__/utils.cpython-36.pyc,, +werkzeug/__pycache__/wsgi.cpython-36.pyc,, +werkzeug/__pycache__/formparser.cpython-36.pyc,, +werkzeug/__pycache__/wrappers.cpython-36.pyc,, +werkzeug/__pycache__/__init__.cpython-36.pyc,, +werkzeug/__pycache__/test.cpython-36.pyc,, +werkzeug/__pycache__/urls.cpython-36.pyc,, +werkzeug/contrib/__pycache__/sessions.cpython-36.pyc,, +werkzeug/contrib/__pycache__/lint.cpython-36.pyc,, +werkzeug/contrib/__pycache__/jsrouting.cpython-36.pyc,, +werkzeug/contrib/__pycache__/iterio.cpython-36.pyc,, +werkzeug/contrib/__pycache__/testtools.cpython-36.pyc,, +werkzeug/contrib/__pycache__/securecookie.cpython-36.pyc,, +werkzeug/contrib/__pycache__/fixers.cpython-36.pyc,, +werkzeug/contrib/__pycache__/profiler.cpython-36.pyc,, +werkzeug/contrib/__pycache__/cache.cpython-36.pyc,, +werkzeug/contrib/__pycache__/limiter.cpython-36.pyc,, +werkzeug/contrib/__pycache__/wrappers.cpython-36.pyc,, +werkzeug/contrib/__pycache__/__init__.cpython-36.pyc,, +werkzeug/contrib/__pycache__/atom.cpython-36.pyc,, +werkzeug/debug/__pycache__/repr.cpython-36.pyc,, +werkzeug/debug/__pycache__/console.cpython-36.pyc,, +werkzeug/debug/__pycache__/tbtools.cpython-36.pyc,, +werkzeug/debug/__pycache__/__init__.cpython-36.pyc,, diff --git a/flask/venv/lib/python3.6/site-packages/Werkzeug-0.14.1.dist-info/WHEEL b/flask/venv/lib/python3.6/site-packages/Werkzeug-0.14.1.dist-info/WHEEL new file mode 100644 index 0000000..0de529b --- /dev/null +++ b/flask/venv/lib/python3.6/site-packages/Werkzeug-0.14.1.dist-info/WHEEL @@ -0,0 +1,6 @@ +Wheel-Version: 1.0 +Generator: bdist_wheel (0.26.0) +Root-Is-Purelib: true +Tag: py2-none-any +Tag: py3-none-any + diff --git a/flask/venv/lib/python3.6/site-packages/Werkzeug-0.14.1.dist-info/metadata.json b/flask/venv/lib/python3.6/site-packages/Werkzeug-0.14.1.dist-info/metadata.json new file mode 100644 index 0000000..bca8d12 --- /dev/null +++ b/flask/venv/lib/python3.6/site-packages/Werkzeug-0.14.1.dist-info/metadata.json @@ -0,0 +1 @@ +{"generator": "bdist_wheel (0.26.0)", "summary": "The comprehensive WSGI web application library.", "classifiers": ["Development Status :: 5 - Production/Stable", "Environment :: Web Environment", "Intended Audience :: Developers", "License :: OSI Approved :: BSD License", "Operating System :: OS Independent", "Programming Language :: Python", "Programming Language :: Python :: 2", "Programming Language :: Python :: 2.6", "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 :: Internet :: WWW/HTTP :: Dynamic Content", "Topic :: Software Development :: Libraries :: Python Modules"], "description_content_type": "UNKNOWN", "extensions": {"python.details": {"project_urls": {"Home": "https://www.palletsprojects.org/p/werkzeug/"}, "contacts": [{"email": "armin.ronacher@active-4.com", "name": "Armin Ronacher", "role": "author"}], "document_names": {"description": "DESCRIPTION.rst", "license": "LICENSE.txt"}}}, "license": "BSD", "metadata_version": "2.0", "name": "Werkzeug", "platform": "any", "extras": ["dev", "termcolor", "watchdog"], "run_requires": [{"requires": ["coverage", "pytest", "sphinx", "tox"], "extra": "dev"}, {"requires": ["termcolor"], "extra": "termcolor"}, {"requires": ["watchdog"], "extra": "watchdog"}], "version": "0.14.1"} \ No newline at end of file diff --git a/flask/venv/lib/python3.6/site-packages/Werkzeug-0.14.1.dist-info/top_level.txt b/flask/venv/lib/python3.6/site-packages/Werkzeug-0.14.1.dist-info/top_level.txt new file mode 100644 index 0000000..6fe8da8 --- /dev/null +++ b/flask/venv/lib/python3.6/site-packages/Werkzeug-0.14.1.dist-info/top_level.txt @@ -0,0 +1 @@ +werkzeug diff --git a/flask/venv/lib/python3.6/site-packages/__pycache__/easy_install.cpython-36.pyc b/flask/venv/lib/python3.6/site-packages/__pycache__/easy_install.cpython-36.pyc new file mode 100644 index 0000000000000000000000000000000000000000..dfa4dd9e6fca57a28976b60a87446a436c2797c6 GIT binary patch literal 327 zcmYj~Jx;_h5QXg|K!n&6AVEZzV&g>1PlFK67Bmz<6(Lz>#~}`mZQ03+rJ&iKeQ!3IY`@Oex6cTnH}78semnPe2R;Cmh-1JHf!%`uLK(DS8Dhl4 zHNps@Ym{z0?OydN>1v+LnOj{b*D)!Rg>GA>V2CMgnNXCzdmKvf5RK<$8Vy^Nf?iNM zz9`mmO3Qu6yWVtKOPBosGVY;Nd{b@c8866g`tcPX6){#US;xteSyE{U+&WSm5?6I~ z(EuEq$NcC-7L8Jl&hk3w|e7-6P&y^t`qnnTkYLH^pw|JKZ`hWNDA&`W-XeYG3= JqaemR_!A&(Uu6IQ literal 0 HcmV?d00001 diff --git a/flask/venv/lib/python3.6/site-packages/click/__init__.py b/flask/venv/lib/python3.6/site-packages/click/__init__.py new file mode 100644 index 0000000..d3c3366 --- /dev/null +++ b/flask/venv/lib/python3.6/site-packages/click/__init__.py @@ -0,0 +1,97 @@ +# -*- coding: utf-8 -*- +""" +click +~~~~~ + +Click is a simple Python module inspired by the stdlib optparse to make +writing command line scripts fun. Unlike other modules, it's based +around a simple API that does not come with too much magic and is +composable. + +:copyright: © 2014 by the Pallets team. +:license: BSD, see LICENSE.rst for more details. +""" + +# Core classes +from .core import Context, BaseCommand, Command, MultiCommand, Group, \ + CommandCollection, Parameter, Option, Argument + +# Globals +from .globals import get_current_context + +# Decorators +from .decorators import pass_context, pass_obj, make_pass_decorator, \ + command, group, argument, option, confirmation_option, \ + password_option, version_option, help_option + +# Types +from .types import ParamType, File, Path, Choice, IntRange, Tuple, \ + DateTime, STRING, INT, FLOAT, BOOL, UUID, UNPROCESSED, FloatRange + +# Utilities +from .utils import echo, get_binary_stream, get_text_stream, open_file, \ + format_filename, get_app_dir, get_os_args + +# Terminal functions +from .termui import prompt, confirm, get_terminal_size, echo_via_pager, \ + progressbar, clear, style, unstyle, secho, edit, launch, getchar, \ + pause + +# Exceptions +from .exceptions import ClickException, UsageError, BadParameter, \ + FileError, Abort, NoSuchOption, BadOptionUsage, BadArgumentUsage, \ + MissingParameter + +# Formatting +from .formatting import HelpFormatter, wrap_text + +# Parsing +from .parser import OptionParser + + +__all__ = [ + # Core classes + 'Context', 'BaseCommand', 'Command', 'MultiCommand', 'Group', + 'CommandCollection', 'Parameter', 'Option', 'Argument', + + # Globals + 'get_current_context', + + # Decorators + 'pass_context', 'pass_obj', 'make_pass_decorator', 'command', 'group', + 'argument', 'option', 'confirmation_option', 'password_option', + 'version_option', 'help_option', + + # Types + 'ParamType', 'File', 'Path', 'Choice', 'IntRange', 'Tuple', + 'DateTime', 'STRING', 'INT', 'FLOAT', 'BOOL', 'UUID', 'UNPROCESSED', + 'FloatRange', + + # Utilities + 'echo', 'get_binary_stream', 'get_text_stream', 'open_file', + 'format_filename', 'get_app_dir', 'get_os_args', + + # Terminal functions + 'prompt', 'confirm', 'get_terminal_size', 'echo_via_pager', + 'progressbar', 'clear', 'style', 'unstyle', 'secho', 'edit', 'launch', + 'getchar', 'pause', + + # Exceptions + 'ClickException', 'UsageError', 'BadParameter', 'FileError', + 'Abort', 'NoSuchOption', 'BadOptionUsage', 'BadArgumentUsage', + 'MissingParameter', + + # Formatting + 'HelpFormatter', 'wrap_text', + + # Parsing + 'OptionParser', +] + + +# Controls if click should emit the warning about the use of unicode +# literals. +disable_unicode_literals_warning = False + + +__version__ = '7.0' diff --git a/flask/venv/lib/python3.6/site-packages/click/__pycache__/__init__.cpython-36.pyc b/flask/venv/lib/python3.6/site-packages/click/__pycache__/__init__.cpython-36.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d235d08c3a73c68f4c33943ac336e885a9b1936c GIT binary patch literal 2670 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 z%0A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 literal 0 HcmV?d00001 diff --git a/flask/venv/lib/python3.6/site-packages/click/__pycache__/_termui_impl.cpython-36.pyc b/flask/venv/lib/python3.6/site-packages/click/__pycache__/_termui_impl.cpython-36.pyc new file mode 100644 index 0000000000000000000000000000000000000000..5f04f008c224edd2f68b125b20c3870c6c83517d GIT binary patch literal 14036 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 Y4td_>NByt!3fu}SIsS*x#ws28|Aw2M1poj5 literal 0 HcmV?d00001 diff --git a/flask/venv/lib/python3.6/site-packages/click/__pycache__/_textwrap.cpython-36.pyc b/flask/venv/lib/python3.6/site-packages/click/__pycache__/_textwrap.cpython-36.pyc new file mode 100644 index 0000000000000000000000000000000000000000..4efa7d81a18c40229319edb9076c609353833d57 GIT binary patch literal 1349 zcmZuxOOM+&5avUYwOYqX+$Os{6h&`UfUMWZ3n+pjK#IN&zBFhGAuXX5xoc@SxILsVU&DNB$wVBB0WV4zUB#+^k)+L*WgbkF?EA%u4}cdXQ@ull*!Qk zVQ^5M!L(n2P$Z#}BurAt-jIYVugkoqi7$N_fGvC)XgF)BS5i$WSm-7Dj;WQhM7v(4`^Xz;p1vc*zus*6@yW3)#YFR=lA3m-Jhg+paXaqjX=LT+=XQ~6e;*E`R(2-w&E)fP(pIUtvmP35v(|@SmCvP>m6*!dNBliSOL~G-b_9* zNLxpvIBw$Op&F!tq=#fsPPi4$v1_ zu!F{aho_k9^7R+6Wd|S#@Zv7O5yBkOtAkxAcKj!C&xJzhbf$!Gkr1=FY=Cyc^@X@- z(z4qzpW>0oBXfx2OBDZ=vC*&(2LB6qMJ*y5vasLpZ)|X7L;N1(w~Mxasxm+6a$?l~ TrE}rauAXlYNsFBV-t&I|!y!}g literal 0 HcmV?d00001 diff --git a/flask/venv/lib/python3.6/site-packages/click/__pycache__/_unicodefun.cpython-36.pyc b/flask/venv/lib/python3.6/site-packages/click/__pycache__/_unicodefun.cpython-36.pyc new file mode 100644 index 0000000000000000000000000000000000000000..cfba4324ce04533676e86db1d45b05b5e00b48e5 GIT binary patch literal 3391 zcma)9yOZ0-8OMSk2;xq%9;egO9*ibZa*mJGSxThQ*coXqQX-E=zOj@j;v~j^*d+-N z1fbo;y@qVew4QODB9)ue$sgcaRcf@UT&Gi&-v{7MXS)ec*vGfK-}|N8r%t*5ezN@Y z>RH41k8$E>Vf_G~`XdHzaF!T@dS(Mw?ahJ7P2NgcGizWmL$J6l?6|`%ZZ1u3T*lwP z;cagJ)fjYnhdY>E-sLXl70#X;8!O)fxAE+IhH-<_L zV_|5fL3(MbbwZ=fxW!vbwqU%qF!vwNackO@@tnn0+y*=Cr5W4YUNZRwV4Ve9vE^oH=i3j#_O9eK?@9ao=M`Z?D}J&M>3cRY0}>D{S+JDFO5Sx zOrmhw+gL4K-yapakOc2c0u^X2%a%G&vRxq=`Qs!T28k+LKv%j-2U4rONKZ<8z zN^_WTQ95DfkCI@l$}>e85y(#>EhIfY6=t(MN`$O#Y_y~U?1R=w&dOHA_y1wYH2~g@ z`nimD11#T!$KR%;RdYCRt>dAww9Nwy|siV%weY~lOGZU-eD%~nZ01l zm^0lWpTN2GwaMVPux7iqCOpmB3uGF60NZYp@jNcH2({pzo(Qi{!plbW@<+P&-dWg- zW_c!c&+}ePBIV)VL<-{d5oi3 zCP6&Kty!R>EcKKS-bCwM-S5}t?Bzj{2(5CN#n6H3!MpnTfu3aP?LJgRUK&mlu`7}d z2Z7*o0j7OlQgoK>$}t8cb1+QAPrZN?4Sp&kmrk=&@*+L%ysQs5%t3b;@Y-XlqsoKp z;R4;f>W32%PJPJn6A~USDDrp%?q#u6d^VhoR*o&-2mIK%y4VoD%DMgp>uWJHLP zduo2eA9ufTblB_xfP$`Exxie7uNm*?9MKY-x`0pv*^q_@wqxE;`2)*UgKAg^4`qb z@r600K~NY3=U1n;e8bNy?ALEz8c2m_DHYD!-!OFryK}TlZ_aH<@ger-tNl7wYy3jI zt}o8pOSWX|2EjR7IQzec+?V3Ze0_;ir#Mg*2-Wqk*mhRiwL-%+i@i zHHG3h%Xk$UM^ORK->H1syWMMYdOJ{I6v+)#1zzdR-VR+vI zLz?mis)H6YFU^n*|b^DJfE_K#Du?kh*}oVZ%i!O0qrLowOQ?R76swNPv7==`KzGDGRM1FqOs7Ez zJ6^w`uA}rIRJ4mNy=ZhJ_~Cao%X?9hz^t&FH!38&LISG@i>itom9?Xo^7aA+b=U4j zWi+cw*2Cx9Po8)<5-DmM>7B|IdDscd_q^>4;hgCIqb`ZGf48@PT%Ia)GsM@pDQ;Ti zs<&av8wgc-69d*ir}Z!D^*i|0s(wii@Y1Hj8!8I_Y+B^y8oIMwiV=cd@FUhsi#oot z`)EHDIVqtuGll9{3{g2lp;X!4$#RjF*3OfiN977d3S}QOU}fj?=Z~b!s2QZbFH%(3 zgESOndw8G)D1$z=eXc@{*GZHD)}~6Hmui5*DWR1Xu`zI| zFxSUFF3RV9cyu&6@SAP{_;)`BUd1sOCKY27g?NpfMz4p03$*=kV?WyrABZdPu-5$D|Ya7<4vPPwMBtq5lS`(-<5u;h3wP^_Fwi GIrl#f{^Jh- literal 0 HcmV?d00001 diff --git a/flask/venv/lib/python3.6/site-packages/click/__pycache__/_winconsole.cpython-36.pyc b/flask/venv/lib/python3.6/site-packages/click/__pycache__/_winconsole.cpython-36.pyc new file mode 100644 index 0000000000000000000000000000000000000000..14aafad4249c08ae3e6c0937677f959058bb947d GIT binary patch literal 8793 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 literal 0 HcmV?d00001 diff --git a/flask/venv/lib/python3.6/site-packages/click/__pycache__/core.cpython-36.pyc b/flask/venv/lib/python3.6/site-packages/click/__pycache__/core.cpython-36.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b1eeb72165b3eaa51f19565060f95efb3d4698d1 GIT binary patch literal 59864 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 XIm_qz?0aV4#rH)%-<>%z`@#PY=MIgI literal 0 HcmV?d00001 diff --git a/flask/venv/lib/python3.6/site-packages/click/__pycache__/decorators.cpython-36.pyc b/flask/venv/lib/python3.6/site-packages/click/__pycache__/decorators.cpython-36.pyc new file mode 100644 index 0000000000000000000000000000000000000000..1d71a4d26891248c79f2e398d5c00b79dd68a452 GIT binary patch literal 11622 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 Cv#f6b literal 0 HcmV?d00001 diff --git a/flask/venv/lib/python3.6/site-packages/click/__pycache__/formatting.cpython-36.pyc b/flask/venv/lib/python3.6/site-packages/click/__pycache__/formatting.cpython-36.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e926358f461ca600e59d659a6d3c7b85e6a16733 GIT binary patch literal 8567 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 H;?n;B4R&@i literal 0 HcmV?d00001 diff --git a/flask/venv/lib/python3.6/site-packages/click/__pycache__/globals.cpython-36.pyc b/flask/venv/lib/python3.6/site-packages/click/__pycache__/globals.cpython-36.pyc new file mode 100644 index 0000000000000000000000000000000000000000..0989d944cface7e47224f5d1c8d1b913be68ca33 GIT binary patch literal 1896 zcmZux&yO256t-uQY&M%+q*g6(Kr$7m1hvVAwtympKoynt5}|DlutG|lu_xoKGalKV z><@)Y(<^@n;-BF>S5C{Hzy+Q?Gi?^t(s=yyz0co!-+OX+*!lBh`^(==g#JQ1ErjuR z@R<>G3^6Rx3ZG$&INqYOfOT2O8n5wL$eOJ68l5%R9&5wD$qreE9l%bD?Y~65qZ_!7 zdbnsx6;b&j!fp=D{k!lzhtGTs-PMsr7BjpJSo1^l5;c$wY#0aU9sLD{;}~s_>DvYi zxA+zQ8KuEbh&8}Pi@pjFI^{OksUbGuB+9kssU?vV(K(4!YWbz@6EaDJArVczMlj9erFR##$?Sa_^AB7gyxlHqkj4bI7!hHCa=c1LcOy#wvv^5tCHa;r3u%Om~`#)0zrN z=dz3)2kv8g0h|G6nhL`SeV36Dzk~>$=BX7c{)5&^&-(sc(KMDu=Ql31uRor+ z1aaU15`}0&4%|-1@y)-`dd*^Q!7a5`7p1S8PUBEl7BvvQ!o>OrLI`m$EkMJGb!1@Sg zx8&|>ikJHbFtBKemjS~Iv<;Tw25m7$EC4x&*Ps6g3C5kKQhrg#vsO^8ZO?UIJDcNP zLpuOPdpczzveRkNfuyNITeN7F@st5sVPr2oPi1%L?sQ!?*U$I}RtyvqgaUmR`p6CI z=Hlw%yN8wVw@{TB2GGIvr>A_S)_~e2s8tz}e9b|ru3osM67RSddZ-?E5oRje!Q&#R zJ*WfNs4+c&)f&@17?0m@>VUfUdr+UjU;|*z_jPvz<(eE$pxO?lf{mn|TT=H*SqIfsmuoZUhx0~(ef4amB^8f$< literal 0 HcmV?d00001 diff --git a/flask/venv/lib/python3.6/site-packages/click/__pycache__/parser.cpython-36.pyc b/flask/venv/lib/python3.6/site-packages/click/__pycache__/parser.cpython-36.pyc new file mode 100644 index 0000000000000000000000000000000000000000..069286b12e27479d6e0f33edf9667a488d5a0c16 GIT binary patch literal 11485 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 V7ai{f&-H3v)mvV=v2=E+_CJQ)7DM~ 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 cE4lMgJ9 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 Q#tfETGgqItHdZhG50Zv-CIA2c literal 0 HcmV?d00001 diff --git a/flask/venv/lib/python3.6/site-packages/click/__pycache__/types.cpython-36.pyc b/flask/venv/lib/python3.6/site-packages/click/__pycache__/types.cpython-36.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ec9d5a6388a9bafeae76d7d6a7075899e3d7b9c9 GIT binary patch literal 21881 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%0A6g%y(UdbL3o*?7ZWERw4BcShH?;zp zSW8#b>v$V7nJwvwCG-BQ`Z|p|njLTaIj&`D%f{ebipo^{FTLIl;a7^@z)4np3`U~! zF5jml78q;$P;4KZBvOoyqAH2bgF6vqxwUd(K`mJs{012S?J6rQR&Ai#Qw1j^i=M8C9r!dC*$(Oy~;Y_K@XitqrRB)r;p< zohy`h*DGS8sU!mM-=LvvaSnNdR<~g1uGg!|L6s2`=_|YxWlGfCLq;Zr>d5qnmL*8| zO+5Hr91%gcr;Ao@IQ#WkA2Y`w)%Qott-WIp28g%GI>L41y2n1&VrpE7;tn z?0Y#I)XQ1LOU~}orLU{yua-{YBN_@`c#6h_?xp7wx)TsXl;q|KJWGUjBggC#h!l?4 zj=!;SNu2m}5{tY9>LUN+K1_Zn4%*YE{gzKeyeK(zNy+!doyGIsOT_WW_4@g@ zm(PED`TSizc-G6#NM%hjiu`tM%w55idz~wnD<96;8ik%$*eXDy(W0ujHn1~z21m2A z9FpO!yg%-kq*%>#jknPH2%8ZOLw596?Ak_Qz z3(i^Cw^TMojRM|*`&6xg%DI@yaso#-kuJ?;=Lh?Tg!&KmwNNi9A&+-BWD(^u_!V4E zmgkDk;Y(rbhj1hggJ0mWh%Lja!536CZL3J@bS_6sioh{hO?fT2Ac9hthg!wCbTQf0 zAtL!dvpdcwY|>Hc)k2v&h|eXHW%%OweWFYzG=It7L?$1@psZ>I{@$`ZEs(YdMD|CB zR&a*jE?L1 z9TJ6`YwORN`Txnz(wRR#*3IX0MSKhG{#Uk5Q%3w+WyO1A^IO1;6&w+H$N2nWZl^ss zArRkC((y5fjgYt)L`G1@swFnSy~7{^_cRFq&Ed`{`~=+13Kh1`qM#GBU0D60vyA2J z!Z7EK^b%0BA*vCg1|Za0v6laoin+I96MJ)*$k1^e#eUK_iAA!1E812evjt!C`uW6xQ3;FOSMOpnlk0e1k*jicGb4dr9T(aFtoj!wBC;)rl@ z5f+83Tk0L~@Pe4TSN6!k3-=9mg}xZ-fqtURU(E=*E9rZ-`b()}=@!T8oRKH+qT&~r+$nArhOC4pb{$&DqGlrZ zf-O!D$X0Lh0?9$A-ytO;;6@V?-408-y6g{+)yK}sr26$CkAl*f(l%NYYM~1Z&q29p z8d8d@Q#-3=9*5H^+^aOnDplNPIy~d#|I?iDb2u@~In4M%ek_RNH7#L!VvA!gr-n%) zjVwaQa}Fn%3_28`p%B$TA^33qI!w?@j+mh;hy5uc?@I)c#7~izgOD*jc%If)>-IAY z(Wi^LTWI@#;fSgz?23rGlD(jKzl9_JBNQt*o>$DxuC_yWM9`Hsc|EqOe{Ev!!jObA zF(XLJ75<$8^jZLz$o*;CQghG^ZDgoY4zP(Z$4A< zEshYt$wOUbWbmu)>CnaW6}FzszKY_#u}LRkui*IAWM5SPz9Z7_47&OyrJo?^{~7r= zEfo8?q~DOGh?IMN+4q|n9i+1F*l^LP zDDdd}Ja4ktVBxa3hXRb}>-b5EY(?GR?O)Eg{4OVhx)is-ZTSc10$mHo$1wW*(zbZ* z)~$D+WoG&#w02^=qt7R6Kfp-7!^U%2TUEUGxrpoNd+*)6A;iT%TOHWa?+0E^T{Ka0 z6^kA z0ZGL*h4C3l$&Fe;FgWwLLPls)HEc?4qORg<6GG8}N@dAzKy(gk9@fz&YxdI2AzO~> zZkxEK@5TVtFl>U`NpMlT@EFRTn}Sq8XxZ0O)OAMKX3XmJ<9&TTBJ$C9Fh)dEiucBd zh;zPzBYF+RVP}P3+9~f;kgPEy&I%Lh8roTbqzxwTAYFqd-)vH3T8R6}848mJ+D26!LbejGAvoI&;U9$?Rru@5cn zaDZ5m429UoeuCqL53%XvZZamA79qER5RfZPA+R`zw(%}~C+G^X)pDOO=V=T~utAll z0w;S!$d%Bh>&C|7#)gI!k<2YPRpFP35lV~=2%a#|{jo4-#Gz(^64zuah7tXj1Y|)D zhCKli87TcclN>ApLi!RqzZZ0w+ro|r2nRHd;w&doeX*d0 zz-*mLlp=2(NZx28AqZh0ZFfr&MpOu=koFbnsZQfnu)~tU*THUY090W@0a(8m>RlSW zRdn;#lBDcpt|;w+!rR=;V_z~FhEaL0^5Dcm5{Ybd0o6Da(Bbw%jueO|avu7KufZ=7 zI|;4Wz|jK;K`|24z2wMVAc3VN=t_$+FQ^y*<`MG1c9Z0|L~+0{9!)-o>PCzYVq(*} z;_8sh2bno(?;-0mK>!2W_8HEDcab`TcG4{~;z5QB1auHjgvKy6*eTOFHYs=-xZ(8D z=ixpG;RtB~1(FuUl_22j)-}M)Ys$CU?#8apppyKb>vSSA%i>asv{64^Iz+?`bmH(ALd+xlDcdnL|6lz%)*f=%t?Xa5N+&FqVyx-0+1EL!E$t=3bsJ-ZHF-ud?`)B5aa-TDc(SoDfdzSRv!!sC?yYa?tuY5y zLWCn>ZWDW)k2xa=$s$tbQh#Iz837m}C_<;U=#9L@W;KS7C#G6U%GwLN+M*oiAAhM7 zUdJKI^y9us`qr8SL?RkZc=5nqu}@J-id@i%ovp&8EQx#(ViT|~lCqwaY*(g>)>X)& z$Kqoaip3$(M>pmlQ9_810*)*FZ!oipK@1H!0?a@D=D^b(Lcf(b8s~T>dZu~bQfHVS z0Lc%J7PQWnDI+9fptSaxxwx8`57)8RCqNOE?-h0`d!-$ln{C{Vi>D^P@jYzW?U&QH{^ed7u2{So zSMlyNH%U#SJD1<7={sx>`;{~CtY}vM#WeOSCgO4c1!5ZGIqF{V(Y;C*$)sJmA0YJG z!@vE?4=dl1z;Gd?5_Ei0eNv)C@S&HGCVSKNy3Uq!Ho3bfdtITwi~%|tW+PB z)eMV6^u<;hGm`rjcAFxo8^`1a!SCSp?En#n*a1-VhbwBBbhbmB!@6kqqwS<}^Ogjl zCzV@wbtF2~f5pY3IB{@UQn^1AJ)}v9=0u~WC5`SoF(+<5{wq=rsg};T1@6#c^Knk> z1#CqkXb7Q0Wzy5UHHVVk-7=mIYC>756$>M#jTY8ahvjO$_C#N5Vue_pJvYYiSb_`c zj1n$7jZ12tBNQ)-Q#Rmt@L)G1bo&MFk=hnan~FW9_^gE^|09A{a73@57}el>=;k|R zY%FD4PIkKGG}Pj-GO^`Uybbu=-vheW!BPpV4(9jsks3%(2K&XeP8Ae!3(bk5kn|_~8yg26 z6h^eJD@D#u9}y)4gmuVe(ehp7CZOJ~2xJPZ6cngwDhT@;qI+%x9Y&&bp&LjN;zMqy zWo=O#@dAas)ey>4uD7H@V3>)R=Jz5O@wH(t;s(YPKE$Sfw7uaxgvKHHis`#)Jgol+ zF=SX$kVI+18m;XS&2J0e9WZ6O@yI-pZ2I2M}~zR4UK3Rz8B{ z;psge#Gx%BO$h`aYm|CY7h!K67vDPjl9b3vWTYFD-Q^&DiOU0^_MxvaqcPg;AR$su zHwZ}v!9>WL!({FuFzH#Y;rfqyYy;78$e#8Wdk7&99w9)C!DoOdjZS;)ecq60d5%I; zw#P6&C~I7=u;r+6LoFVoj^QF)9$f%gdgwZq8{^`@(z;uucC1!54uTis?Max)&5g{m zAcB3>31Wouj{(4`lg~0NgOBA2(dba(_%*i_Ea&V+g5Chc6Z)pZ5~%@TqZ~Gym$?M& zX(l*8Ni&Ftdidkm%yMD!X#rE+i@dA0Sp(0usj=c2)$gfp&7%Ttdu(q?w5JNR zC-N_mz{yn3bQ)7PGQpvK2LP(yMNzLpLl>5xOyx`u-}Oj2SYl_KD6umRlGHNol{1}G zhx823EV9rfR5+Q+sjNPwm7-7B=ig=Vdn|s;;!_rXkHz0-@%t<$=>GqSI);OXMj_Mv z(_c$x5J|~c>Y3Z5zC4+cGr~Xq7I0k05v`yAF11DQI{neSIw0O(=NY2zYy>nQNG&cN zAohOW?ACBq%C6EhIv6qk04)t2eL733!h72&GJ9ddE`2iJ3K1FQHw8&RC!8yUG2Meb z1$Ax~k!ORGGMdNh=GFo`qoyn4;*LU=n-KC-6eh}|XWuU~1n;M2#J~+pU5N`j^oBCQ z49RA=D$98p$(t+C;VX#3`r*(s8hsycO|gdfK|Tw4DZQlIwAEqow###HRsTSlNtbr%I zvw%A9cdZ36>T6b(6iAzy7W1q{ z`-W$>SUURbRDSPtc4iG~>0*(O?bPkn_4U>D)z!87^hDDqN0<6LfMCSp5ga|y;vvuc zcjQL1II+)adj}TJf^7>wZQ*wQSHRf{j)>8YqZW@R$?}b&k7RkTBx&?$F{GR@Xi+nI=1KwJ?l+Z=0sgT5xIw-=k6~c2Tdf3pU zV)v-5Qvsp$(`ze^$zc`wx&)Op>Xcay0Qwg_BD3LS@Tn0;vng#VQx|2Fyf4{?=|ceu zCd?C|cDnt}z5FXKt1xN~`^hlOESXSp78ltOzAYq83-VH6@I4=xV;CFMKAmsiI=6T6 zr3nm5k{$7(5u`DSi&sy|xWy%STE;9fdq?st1#y!!FsRUi8r`nOp2j~&L;m>7<2nwB z$Y(S@lFUpdnL$N>&;v;o*7Cq*R;IgyJMd$PSvod%JTa@5dKW}{1UtHhml6w~O*pi? z+50uLEL%p*6q7m3#qy*~F@*e=1QVIq{AXz6aJzI#yqUF&$g$b+cJo1zTXRr?g)icS zSb)HnZ!mz}3pNhSlZID1Nqm&y@O%9;)5#kkR(O!%>%<1*qcmCVee4*1Y-J8lQ?#8F z73z;s{SeHbO})-E)<-?{#%cz6(HNZ7kc(?zm^YWz{LFjT6ZF!)5z5j;+h+D1su^b z3Qas&U&vHH9b0f=nm>Zj{;~061P}@fwDENaKm%36B7F)}h|7HUCgX>hK@3)gZ8Ok3 zTp+@LM)(hCaTEIhsLD@*(ej{6UOtSXS)ahTl%s;c5y)2wB#8n^k|*HnH23K_wLV3< zFXvedJz;->%i9^6Fu#sQQ@UP82tJ!)IOzVAO>lmb zsdX%Q?O80vsfX$c>V!3Ps+#adDEex4RYOi$wwqWc9-JmMI>b?DX0 zO#DEA@G?n6K6|hfo3RyR|D942|n<~9+obimhamP zC5GNAztYQt*p_Eg=8CR_iv zF+K&jXPiKvKjLRi7N8j)g=YM7tr=@=H=frp)k}kKU(dd?*uVf?tG) z`uD`0n#{fle+{L)^+Y zirTq7C)u!6^SDjIZ$ZGtU7FRuD2qjYo24jUW+|J}1~;58DpBNqiiUJXR7F0I1g)1m zNe`7PLcUueK6?E@3zBbA)k+S=6UpbD5`20lXh-7tmkorZtaCs$-Y&2m4p%-ABA<4U zL{^>SBLUpE`1CFdhFD1`jD#|XEiMY8tP}xXeU(*Y3IzK^x5j?JGvO`6f{Q${Ux$K@ z??b&owk}#FcLQqHi!c`F3Uj|TXU`p-tInO6`;ED;&CSfcG&hUm=-k}gZ_fpDPW81i K@{r|U;r{^Xj86^# literal 0 HcmV?d00001 diff --git a/flask/venv/lib/python3.6/site-packages/click/__pycache__/utils.cpython-36.pyc b/flask/venv/lib/python3.6/site-packages/click/__pycache__/utils.cpython-36.pyc new file mode 100644 index 0000000000000000000000000000000000000000..31929cab4b8e28eec5ea9d8e6774ce4be196e3b6 GIT binary patch literal 15262 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 E0^!F;t^fc4 literal 0 HcmV?d00001 diff --git a/flask/venv/lib/python3.6/site-packages/click/_bashcomplete.py b/flask/venv/lib/python3.6/site-packages/click/_bashcomplete.py new file mode 100644 index 0000000..a5f1084 --- /dev/null +++ b/flask/venv/lib/python3.6/site-packages/click/_bashcomplete.py @@ -0,0 +1,293 @@ +import copy +import os +import re + +from .utils import echo +from .parser import split_arg_string +from .core import MultiCommand, Option, Argument +from .types import Choice + +try: + from collections import abc +except ImportError: + import collections as abc + +WORDBREAK = '=' + +# Note, only BASH version 4.4 and later have the nosort option. +COMPLETION_SCRIPT_BASH = ''' +%(complete_func)s() { + local IFS=$'\n' + COMPREPLY=( $( env COMP_WORDS="${COMP_WORDS[*]}" \\ + COMP_CWORD=$COMP_CWORD \\ + %(autocomplete_var)s=complete $1 ) ) + return 0 +} + +%(complete_func)setup() { + local COMPLETION_OPTIONS="" + local BASH_VERSION_ARR=(${BASH_VERSION//./ }) + # Only BASH version 4.4 and later have the nosort option. + if [ ${BASH_VERSION_ARR[0]} -gt 4 ] || ([ ${BASH_VERSION_ARR[0]} -eq 4 ] && [ ${BASH_VERSION_ARR[1]} -ge 4 ]); then + COMPLETION_OPTIONS="-o nosort" + fi + + complete $COMPLETION_OPTIONS -F %(complete_func)s %(script_names)s +} + +%(complete_func)setup +''' + +COMPLETION_SCRIPT_ZSH = ''' +%(complete_func)s() { + local -a completions + local -a completions_with_descriptions + local -a response + response=("${(@f)$( env COMP_WORDS=\"${words[*]}\" \\ + COMP_CWORD=$((CURRENT-1)) \\ + %(autocomplete_var)s=\"complete_zsh\" \\ + %(script_names)s )}") + + for key descr in ${(kv)response}; do + if [[ "$descr" == "_" ]]; then + completions+=("$key") + else + completions_with_descriptions+=("$key":"$descr") + fi + done + + if [ -n "$completions_with_descriptions" ]; then + _describe -V unsorted completions_with_descriptions -U -Q + fi + + if [ -n "$completions" ]; then + compadd -U -V unsorted -Q -a completions + fi + compstate[insert]="automenu" +} + +compdef %(complete_func)s %(script_names)s +''' + +_invalid_ident_char_re = re.compile(r'[^a-zA-Z0-9_]') + + +def get_completion_script(prog_name, complete_var, shell): + cf_name = _invalid_ident_char_re.sub('', prog_name.replace('-', '_')) + script = COMPLETION_SCRIPT_ZSH if shell == 'zsh' else COMPLETION_SCRIPT_BASH + return (script % { + 'complete_func': '_%s_completion' % cf_name, + 'script_names': prog_name, + 'autocomplete_var': complete_var, + }).strip() + ';' + + +def resolve_ctx(cli, prog_name, args): + """ + Parse into a hierarchy of contexts. Contexts are connected through the parent variable. + :param cli: command definition + :param prog_name: the program that is running + :param args: full list of args + :return: the final context/command parsed + """ + ctx = cli.make_context(prog_name, args, resilient_parsing=True) + args = ctx.protected_args + ctx.args + while args: + if isinstance(ctx.command, MultiCommand): + if not ctx.command.chain: + cmd_name, cmd, args = ctx.command.resolve_command(ctx, args) + if cmd is None: + return ctx + ctx = cmd.make_context(cmd_name, args, parent=ctx, + resilient_parsing=True) + args = ctx.protected_args + ctx.args + else: + # Walk chained subcommand contexts saving the last one. + while args: + cmd_name, cmd, args = ctx.command.resolve_command(ctx, args) + if cmd is None: + return ctx + sub_ctx = cmd.make_context(cmd_name, args, parent=ctx, + allow_extra_args=True, + allow_interspersed_args=False, + resilient_parsing=True) + args = sub_ctx.args + ctx = sub_ctx + args = sub_ctx.protected_args + sub_ctx.args + else: + break + return ctx + + +def start_of_option(param_str): + """ + :param param_str: param_str to check + :return: whether or not this is the start of an option declaration (i.e. starts "-" or "--") + """ + return param_str and param_str[:1] == '-' + + +def is_incomplete_option(all_args, cmd_param): + """ + :param all_args: the full original list of args supplied + :param cmd_param: the current command paramter + :return: whether or not the last option declaration (i.e. starts "-" or "--") is incomplete and + corresponds to this cmd_param. In other words whether this cmd_param option can still accept + values + """ + if not isinstance(cmd_param, Option): + return False + if cmd_param.is_flag: + return False + last_option = None + for index, arg_str in enumerate(reversed([arg for arg in all_args if arg != WORDBREAK])): + if index + 1 > cmd_param.nargs: + break + if start_of_option(arg_str): + last_option = arg_str + + return True if last_option and last_option in cmd_param.opts else False + + +def is_incomplete_argument(current_params, cmd_param): + """ + :param current_params: the current params and values for this argument as already entered + :param cmd_param: the current command parameter + :return: whether or not the last argument is incomplete and corresponds to this cmd_param. In + other words whether or not the this cmd_param argument can still accept values + """ + if not isinstance(cmd_param, Argument): + return False + current_param_values = current_params[cmd_param.name] + if current_param_values is None: + return True + if cmd_param.nargs == -1: + return True + if isinstance(current_param_values, abc.Iterable) \ + and cmd_param.nargs > 1 and len(current_param_values) < cmd_param.nargs: + return True + return False + + +def get_user_autocompletions(ctx, args, incomplete, cmd_param): + """ + :param ctx: context associated with the parsed command + :param args: full list of args + :param incomplete: the incomplete text to autocomplete + :param cmd_param: command definition + :return: all the possible user-specified completions for the param + """ + results = [] + if isinstance(cmd_param.type, Choice): + # Choices don't support descriptions. + results = [(c, None) + for c in cmd_param.type.choices if str(c).startswith(incomplete)] + elif cmd_param.autocompletion is not None: + dynamic_completions = cmd_param.autocompletion(ctx=ctx, + args=args, + incomplete=incomplete) + results = [c if isinstance(c, tuple) else (c, None) + for c in dynamic_completions] + return results + + +def get_visible_commands_starting_with(ctx, starts_with): + """ + :param ctx: context associated with the parsed command + :starts_with: string that visible commands must start with. + :return: all visible (not hidden) commands that start with starts_with. + """ + for c in ctx.command.list_commands(ctx): + if c.startswith(starts_with): + command = ctx.command.get_command(ctx, c) + if not command.hidden: + yield command + + +def add_subcommand_completions(ctx, incomplete, completions_out): + # Add subcommand completions. + if isinstance(ctx.command, MultiCommand): + completions_out.extend( + [(c.name, c.get_short_help_str()) for c in get_visible_commands_starting_with(ctx, incomplete)]) + + # Walk up the context list and add any other completion possibilities from chained commands + while ctx.parent is not None: + ctx = ctx.parent + if isinstance(ctx.command, MultiCommand) and ctx.command.chain: + remaining_commands = [c for c in get_visible_commands_starting_with(ctx, incomplete) + if c.name not in ctx.protected_args] + completions_out.extend([(c.name, c.get_short_help_str()) for c in remaining_commands]) + + +def get_choices(cli, prog_name, args, incomplete): + """ + :param cli: command definition + :param prog_name: the program that is running + :param args: full list of args + :param incomplete: the incomplete text to autocomplete + :return: all the possible completions for the incomplete + """ + all_args = copy.deepcopy(args) + + ctx = resolve_ctx(cli, prog_name, args) + if ctx is None: + return [] + + # In newer versions of bash long opts with '='s are partitioned, but it's easier to parse + # without the '=' + if start_of_option(incomplete) and WORDBREAK in incomplete: + partition_incomplete = incomplete.partition(WORDBREAK) + all_args.append(partition_incomplete[0]) + incomplete = partition_incomplete[2] + elif incomplete == WORDBREAK: + incomplete = '' + + completions = [] + if start_of_option(incomplete): + # completions for partial options + for param in ctx.command.params: + if isinstance(param, Option) and not param.hidden: + param_opts = [param_opt for param_opt in param.opts + + param.secondary_opts if param_opt not in all_args or param.multiple] + completions.extend([(o, param.help) for o in param_opts if o.startswith(incomplete)]) + return completions + # completion for option values from user supplied values + for param in ctx.command.params: + if is_incomplete_option(all_args, param): + return get_user_autocompletions(ctx, all_args, incomplete, param) + # completion for argument values from user supplied values + for param in ctx.command.params: + if is_incomplete_argument(ctx.params, param): + return get_user_autocompletions(ctx, all_args, incomplete, param) + + add_subcommand_completions(ctx, incomplete, completions) + # Sort before returning so that proper ordering can be enforced in custom types. + return sorted(completions) + + +def do_complete(cli, prog_name, include_descriptions): + cwords = split_arg_string(os.environ['COMP_WORDS']) + cword = int(os.environ['COMP_CWORD']) + args = cwords[1:cword] + try: + incomplete = cwords[cword] + except IndexError: + incomplete = '' + + for item in get_choices(cli, prog_name, args, incomplete): + echo(item[0]) + if include_descriptions: + # ZSH has trouble dealing with empty array parameters when returned from commands, so use a well defined character '_' to indicate no description is present. + echo(item[1] if item[1] else '_') + + return True + + +def bashcomplete(cli, prog_name, complete_var, complete_instr): + if complete_instr.startswith('source'): + shell = 'zsh' if complete_instr == 'source_zsh' else 'bash' + echo(get_completion_script(prog_name, complete_var, shell)) + return True + elif complete_instr == 'complete' or complete_instr == 'complete_zsh': + return do_complete(cli, prog_name, complete_instr == 'complete_zsh') + return False diff --git a/flask/venv/lib/python3.6/site-packages/click/_compat.py b/flask/venv/lib/python3.6/site-packages/click/_compat.py new file mode 100644 index 0000000..937e230 --- /dev/null +++ b/flask/venv/lib/python3.6/site-packages/click/_compat.py @@ -0,0 +1,703 @@ +import re +import io +import os +import sys +import codecs +from weakref import WeakKeyDictionary + + +PY2 = sys.version_info[0] == 2 +CYGWIN = sys.platform.startswith('cygwin') +# Determine local App Engine environment, per Google's own suggestion +APP_ENGINE = ('APPENGINE_RUNTIME' in os.environ and + 'Development/' in os.environ['SERVER_SOFTWARE']) +WIN = sys.platform.startswith('win') and not APP_ENGINE +DEFAULT_COLUMNS = 80 + + +_ansi_re = re.compile(r'\033\[((?:\d|;)*)([a-zA-Z])') + + +def get_filesystem_encoding(): + return sys.getfilesystemencoding() or sys.getdefaultencoding() + + +def _make_text_stream(stream, encoding, errors, + force_readable=False, force_writable=False): + if encoding is None: + encoding = get_best_encoding(stream) + if errors is None: + errors = 'replace' + return _NonClosingTextIOWrapper(stream, encoding, errors, + line_buffering=True, + force_readable=force_readable, + force_writable=force_writable) + + +def is_ascii_encoding(encoding): + """Checks if a given encoding is ascii.""" + try: + return codecs.lookup(encoding).name == 'ascii' + except LookupError: + return False + + +def get_best_encoding(stream): + """Returns the default stream encoding if not found.""" + rv = getattr(stream, 'encoding', None) or sys.getdefaultencoding() + if is_ascii_encoding(rv): + return 'utf-8' + return rv + + +class _NonClosingTextIOWrapper(io.TextIOWrapper): + + def __init__(self, stream, encoding, errors, + force_readable=False, force_writable=False, **extra): + self._stream = stream = _FixupStream(stream, force_readable, + force_writable) + io.TextIOWrapper.__init__(self, stream, encoding, errors, **extra) + + # The io module is a place where the Python 3 text behavior + # was forced upon Python 2, so we need to unbreak + # it to look like Python 2. + if PY2: + def write(self, x): + if isinstance(x, str) or is_bytes(x): + try: + self.flush() + except Exception: + pass + return self.buffer.write(str(x)) + return io.TextIOWrapper.write(self, x) + + def writelines(self, lines): + for line in lines: + self.write(line) + + def __del__(self): + try: + self.detach() + except Exception: + pass + + def isatty(self): + # https://bitbucket.org/pypy/pypy/issue/1803 + return self._stream.isatty() + + +class _FixupStream(object): + """The new io interface needs more from streams than streams + traditionally implement. As such, this fix-up code is necessary in + some circumstances. + + The forcing of readable and writable flags are there because some tools + put badly patched objects on sys (one such offender are certain version + of jupyter notebook). + """ + + def __init__(self, stream, force_readable=False, force_writable=False): + self._stream = stream + self._force_readable = force_readable + self._force_writable = force_writable + + def __getattr__(self, name): + return getattr(self._stream, name) + + def read1(self, size): + f = getattr(self._stream, 'read1', None) + if f is not None: + return f(size) + # We only dispatch to readline instead of read in Python 2 as we + # do not want cause problems with the different implementation + # of line buffering. + if PY2: + return self._stream.readline(size) + return self._stream.read(size) + + def readable(self): + if self._force_readable: + return True + x = getattr(self._stream, 'readable', None) + if x is not None: + return x() + try: + self._stream.read(0) + except Exception: + return False + return True + + def writable(self): + if self._force_writable: + return True + x = getattr(self._stream, 'writable', None) + if x is not None: + return x() + try: + self._stream.write('') + except Exception: + try: + self._stream.write(b'') + except Exception: + return False + return True + + def seekable(self): + x = getattr(self._stream, 'seekable', None) + if x is not None: + return x() + try: + self._stream.seek(self._stream.tell()) + except Exception: + return False + return True + + +if PY2: + text_type = unicode + bytes = str + raw_input = raw_input + string_types = (str, unicode) + int_types = (int, long) + iteritems = lambda x: x.iteritems() + range_type = xrange + + def is_bytes(x): + return isinstance(x, (buffer, bytearray)) + + _identifier_re = re.compile(r'^[a-zA-Z_][a-zA-Z0-9_]*$') + + # For Windows, we need to force stdout/stdin/stderr to binary if it's + # fetched for that. This obviously is not the most correct way to do + # it as it changes global state. Unfortunately, there does not seem to + # be a clear better way to do it as just reopening the file in binary + # mode does not change anything. + # + # An option would be to do what Python 3 does and to open the file as + # binary only, patch it back to the system, and then use a wrapper + # stream that converts newlines. It's not quite clear what's the + # correct option here. + # + # This code also lives in _winconsole for the fallback to the console + # emulation stream. + # + # There are also Windows environments where the `msvcrt` module is not + # available (which is why we use try-catch instead of the WIN variable + # here), such as the Google App Engine development server on Windows. In + # those cases there is just nothing we can do. + def set_binary_mode(f): + return f + + try: + import msvcrt + except ImportError: + pass + else: + def set_binary_mode(f): + try: + fileno = f.fileno() + except Exception: + pass + else: + msvcrt.setmode(fileno, os.O_BINARY) + return f + + try: + import fcntl + except ImportError: + pass + else: + def set_binary_mode(f): + try: + fileno = f.fileno() + except Exception: + pass + else: + flags = fcntl.fcntl(fileno, fcntl.F_GETFL) + fcntl.fcntl(fileno, fcntl.F_SETFL, flags & ~os.O_NONBLOCK) + return f + + def isidentifier(x): + return _identifier_re.search(x) is not None + + def get_binary_stdin(): + return set_binary_mode(sys.stdin) + + def get_binary_stdout(): + _wrap_std_stream('stdout') + return set_binary_mode(sys.stdout) + + def get_binary_stderr(): + _wrap_std_stream('stderr') + return set_binary_mode(sys.stderr) + + def get_text_stdin(encoding=None, errors=None): + rv = _get_windows_console_stream(sys.stdin, encoding, errors) + if rv is not None: + return rv + return _make_text_stream(sys.stdin, encoding, errors, + force_readable=True) + + def get_text_stdout(encoding=None, errors=None): + _wrap_std_stream('stdout') + rv = _get_windows_console_stream(sys.stdout, encoding, errors) + if rv is not None: + return rv + return _make_text_stream(sys.stdout, encoding, errors, + force_writable=True) + + def get_text_stderr(encoding=None, errors=None): + _wrap_std_stream('stderr') + rv = _get_windows_console_stream(sys.stderr, encoding, errors) + if rv is not None: + return rv + return _make_text_stream(sys.stderr, encoding, errors, + force_writable=True) + + def filename_to_ui(value): + if isinstance(value, bytes): + value = value.decode(get_filesystem_encoding(), 'replace') + return value +else: + import io + text_type = str + raw_input = input + string_types = (str,) + int_types = (int,) + range_type = range + isidentifier = lambda x: x.isidentifier() + iteritems = lambda x: iter(x.items()) + + def is_bytes(x): + return isinstance(x, (bytes, memoryview, bytearray)) + + def _is_binary_reader(stream, default=False): + try: + return isinstance(stream.read(0), bytes) + except Exception: + return default + # This happens in some cases where the stream was already + # closed. In this case, we assume the default. + + def _is_binary_writer(stream, default=False): + try: + stream.write(b'') + except Exception: + try: + stream.write('') + return False + except Exception: + pass + return default + return True + + def _find_binary_reader(stream): + # We need to figure out if the given stream is already binary. + # This can happen because the official docs recommend detaching + # the streams to get binary streams. Some code might do this, so + # we need to deal with this case explicitly. + if _is_binary_reader(stream, False): + return stream + + buf = getattr(stream, 'buffer', None) + + # Same situation here; this time we assume that the buffer is + # actually binary in case it's closed. + if buf is not None and _is_binary_reader(buf, True): + return buf + + def _find_binary_writer(stream): + # We need to figure out if the given stream is already binary. + # This can happen because the official docs recommend detatching + # the streams to get binary streams. Some code might do this, so + # we need to deal with this case explicitly. + if _is_binary_writer(stream, False): + return stream + + buf = getattr(stream, 'buffer', None) + + # Same situation here; this time we assume that the buffer is + # actually binary in case it's closed. + if buf is not None and _is_binary_writer(buf, True): + return buf + + def _stream_is_misconfigured(stream): + """A stream is misconfigured if its encoding is ASCII.""" + # If the stream does not have an encoding set, we assume it's set + # to ASCII. This appears to happen in certain unittest + # environments. It's not quite clear what the correct behavior is + # but this at least will force Click to recover somehow. + return is_ascii_encoding(getattr(stream, 'encoding', None) or 'ascii') + + def _is_compatible_text_stream(stream, encoding, errors): + stream_encoding = getattr(stream, 'encoding', None) + stream_errors = getattr(stream, 'errors', None) + + # Perfect match. + if stream_encoding == encoding and stream_errors == errors: + return True + + # Otherwise, it's only a compatible stream if we did not ask for + # an encoding. + if encoding is None: + return stream_encoding is not None + + return False + + def _force_correct_text_reader(text_reader, encoding, errors, + force_readable=False): + if _is_binary_reader(text_reader, False): + binary_reader = text_reader + else: + # If there is no target encoding set, we need to verify that the + # reader is not actually misconfigured. + if encoding is None and not _stream_is_misconfigured(text_reader): + return text_reader + + if _is_compatible_text_stream(text_reader, encoding, errors): + return text_reader + + # If the reader has no encoding, we try to find the underlying + # binary reader for it. If that fails because the environment is + # misconfigured, we silently go with the same reader because this + # is too common to happen. In that case, mojibake is better than + # exceptions. + binary_reader = _find_binary_reader(text_reader) + if binary_reader is None: + return text_reader + + # At this point, we default the errors to replace instead of strict + # because nobody handles those errors anyways and at this point + # we're so fundamentally fucked that nothing can repair it. + if errors is None: + errors = 'replace' + return _make_text_stream(binary_reader, encoding, errors, + force_readable=force_readable) + + def _force_correct_text_writer(text_writer, encoding, errors, + force_writable=False): + if _is_binary_writer(text_writer, False): + binary_writer = text_writer + else: + # If there is no target encoding set, we need to verify that the + # writer is not actually misconfigured. + if encoding is None and not _stream_is_misconfigured(text_writer): + return text_writer + + if _is_compatible_text_stream(text_writer, encoding, errors): + return text_writer + + # If the writer has no encoding, we try to find the underlying + # binary writer for it. If that fails because the environment is + # misconfigured, we silently go with the same writer because this + # is too common to happen. In that case, mojibake is better than + # exceptions. + binary_writer = _find_binary_writer(text_writer) + if binary_writer is None: + return text_writer + + # At this point, we default the errors to replace instead of strict + # because nobody handles those errors anyways and at this point + # we're so fundamentally fucked that nothing can repair it. + if errors is None: + errors = 'replace' + return _make_text_stream(binary_writer, encoding, errors, + force_writable=force_writable) + + def get_binary_stdin(): + reader = _find_binary_reader(sys.stdin) + if reader is None: + raise RuntimeError('Was not able to determine binary ' + 'stream for sys.stdin.') + return reader + + def get_binary_stdout(): + writer = _find_binary_writer(sys.stdout) + if writer is None: + raise RuntimeError('Was not able to determine binary ' + 'stream for sys.stdout.') + return writer + + def get_binary_stderr(): + writer = _find_binary_writer(sys.stderr) + if writer is None: + raise RuntimeError('Was not able to determine binary ' + 'stream for sys.stderr.') + return writer + + def get_text_stdin(encoding=None, errors=None): + rv = _get_windows_console_stream(sys.stdin, encoding, errors) + if rv is not None: + return rv + return _force_correct_text_reader(sys.stdin, encoding, errors, + force_readable=True) + + def get_text_stdout(encoding=None, errors=None): + rv = _get_windows_console_stream(sys.stdout, encoding, errors) + if rv is not None: + return rv + return _force_correct_text_writer(sys.stdout, encoding, errors, + force_writable=True) + + def get_text_stderr(encoding=None, errors=None): + rv = _get_windows_console_stream(sys.stderr, encoding, errors) + if rv is not None: + return rv + return _force_correct_text_writer(sys.stderr, encoding, errors, + force_writable=True) + + def filename_to_ui(value): + if isinstance(value, bytes): + value = value.decode(get_filesystem_encoding(), 'replace') + else: + value = value.encode('utf-8', 'surrogateescape') \ + .decode('utf-8', 'replace') + return value + + +def get_streerror(e, default=None): + if hasattr(e, 'strerror'): + msg = e.strerror + else: + if default is not None: + msg = default + else: + msg = str(e) + if isinstance(msg, bytes): + msg = msg.decode('utf-8', 'replace') + return msg + + +def open_stream(filename, mode='r', encoding=None, errors='strict', + atomic=False): + # Standard streams first. These are simple because they don't need + # special handling for the atomic flag. It's entirely ignored. + if filename == '-': + if any(m in mode for m in ['w', 'a', 'x']): + if 'b' in mode: + return get_binary_stdout(), False + return get_text_stdout(encoding=encoding, errors=errors), False + if 'b' in mode: + return get_binary_stdin(), False + return get_text_stdin(encoding=encoding, errors=errors), False + + # Non-atomic writes directly go out through the regular open functions. + if not atomic: + if encoding is None: + return open(filename, mode), True + return io.open(filename, mode, encoding=encoding, errors=errors), True + + # Some usability stuff for atomic writes + if 'a' in mode: + raise ValueError( + 'Appending to an existing file is not supported, because that ' + 'would involve an expensive `copy`-operation to a temporary ' + 'file. Open the file in normal `w`-mode and copy explicitly ' + 'if that\'s what you\'re after.' + ) + if 'x' in mode: + raise ValueError('Use the `overwrite`-parameter instead.') + if 'w' not in mode: + raise ValueError('Atomic writes only make sense with `w`-mode.') + + # Atomic writes are more complicated. They work by opening a file + # as a proxy in the same folder and then using the fdopen + # functionality to wrap it in a Python file. Then we wrap it in an + # atomic file that moves the file over on close. + import tempfile + fd, tmp_filename = tempfile.mkstemp(dir=os.path.dirname(filename), + prefix='.__atomic-write') + + if encoding is not None: + f = io.open(fd, mode, encoding=encoding, errors=errors) + else: + f = os.fdopen(fd, mode) + + return _AtomicFile(f, tmp_filename, os.path.realpath(filename)), True + + +# Used in a destructor call, needs extra protection from interpreter cleanup. +if hasattr(os, 'replace'): + _replace = os.replace + _can_replace = True +else: + _replace = os.rename + _can_replace = not WIN + + +class _AtomicFile(object): + + def __init__(self, f, tmp_filename, real_filename): + self._f = f + self._tmp_filename = tmp_filename + self._real_filename = real_filename + self.closed = False + + @property + def name(self): + return self._real_filename + + def close(self, delete=False): + if self.closed: + return + self._f.close() + if not _can_replace: + try: + os.remove(self._real_filename) + except OSError: + pass + _replace(self._tmp_filename, self._real_filename) + self.closed = True + + def __getattr__(self, name): + return getattr(self._f, name) + + def __enter__(self): + return self + + def __exit__(self, exc_type, exc_value, tb): + self.close(delete=exc_type is not None) + + def __repr__(self): + return repr(self._f) + + +auto_wrap_for_ansi = None +colorama = None +get_winterm_size = None + + +def strip_ansi(value): + return _ansi_re.sub('', value) + + +def should_strip_ansi(stream=None, color=None): + if color is None: + if stream is None: + stream = sys.stdin + return not isatty(stream) + return not color + + +# If we're on Windows, we provide transparent integration through +# colorama. This will make ANSI colors through the echo function +# work automatically. +if WIN: + # Windows has a smaller terminal + DEFAULT_COLUMNS = 79 + + from ._winconsole import _get_windows_console_stream, _wrap_std_stream + + def _get_argv_encoding(): + import locale + return locale.getpreferredencoding() + + if PY2: + def raw_input(prompt=''): + sys.stderr.flush() + if prompt: + stdout = _default_text_stdout() + stdout.write(prompt) + stdin = _default_text_stdin() + return stdin.readline().rstrip('\r\n') + + try: + import colorama + except ImportError: + pass + else: + _ansi_stream_wrappers = WeakKeyDictionary() + + def auto_wrap_for_ansi(stream, color=None): + """This function wraps a stream so that calls through colorama + are issued to the win32 console API to recolor on demand. It + also ensures to reset the colors if a write call is interrupted + to not destroy the console afterwards. + """ + try: + cached = _ansi_stream_wrappers.get(stream) + except Exception: + cached = None + if cached is not None: + return cached + strip = should_strip_ansi(stream, color) + ansi_wrapper = colorama.AnsiToWin32(stream, strip=strip) + rv = ansi_wrapper.stream + _write = rv.write + + def _safe_write(s): + try: + return _write(s) + except: + ansi_wrapper.reset_all() + raise + + rv.write = _safe_write + try: + _ansi_stream_wrappers[stream] = rv + except Exception: + pass + return rv + + def get_winterm_size(): + win = colorama.win32.GetConsoleScreenBufferInfo( + colorama.win32.STDOUT).srWindow + return win.Right - win.Left, win.Bottom - win.Top +else: + def _get_argv_encoding(): + return getattr(sys.stdin, 'encoding', None) or get_filesystem_encoding() + + _get_windows_console_stream = lambda *x: None + _wrap_std_stream = lambda *x: None + + +def term_len(x): + return len(strip_ansi(x)) + + +def isatty(stream): + try: + return stream.isatty() + except Exception: + return False + + +def _make_cached_stream_func(src_func, wrapper_func): + cache = WeakKeyDictionary() + def func(): + stream = src_func() + try: + rv = cache.get(stream) + except Exception: + rv = None + if rv is not None: + return rv + rv = wrapper_func() + try: + stream = src_func() # In case wrapper_func() modified the stream + cache[stream] = rv + except Exception: + pass + return rv + return func + + +_default_text_stdin = _make_cached_stream_func( + lambda: sys.stdin, get_text_stdin) +_default_text_stdout = _make_cached_stream_func( + lambda: sys.stdout, get_text_stdout) +_default_text_stderr = _make_cached_stream_func( + lambda: sys.stderr, get_text_stderr) + + +binary_streams = { + 'stdin': get_binary_stdin, + 'stdout': get_binary_stdout, + 'stderr': get_binary_stderr, +} + +text_streams = { + 'stdin': get_text_stdin, + 'stdout': get_text_stdout, + 'stderr': get_text_stderr, +} diff --git a/flask/venv/lib/python3.6/site-packages/click/_termui_impl.py b/flask/venv/lib/python3.6/site-packages/click/_termui_impl.py new file mode 100644 index 0000000..00a8e5e --- /dev/null +++ b/flask/venv/lib/python3.6/site-packages/click/_termui_impl.py @@ -0,0 +1,621 @@ +# -*- coding: utf-8 -*- +""" +click._termui_impl +~~~~~~~~~~~~~~~~~~ + +This module contains implementations for the termui module. To keep the +import time of Click down, some infrequently used functionality is +placed in this module and only imported as needed. + +:copyright: © 2014 by the Pallets team. +:license: BSD, see LICENSE.rst for more details. +""" + +import os +import sys +import time +import math +import contextlib +from ._compat import _default_text_stdout, range_type, PY2, isatty, \ + open_stream, strip_ansi, term_len, get_best_encoding, WIN, int_types, \ + CYGWIN +from .utils import echo +from .exceptions import ClickException + + +if os.name == 'nt': + BEFORE_BAR = '\r' + AFTER_BAR = '\n' +else: + BEFORE_BAR = '\r\033[?25l' + AFTER_BAR = '\033[?25h\n' + + +def _length_hint(obj): + """Returns the length hint of an object.""" + try: + return len(obj) + except (AttributeError, TypeError): + try: + get_hint = type(obj).__length_hint__ + except AttributeError: + return None + try: + hint = get_hint(obj) + except TypeError: + return None + if hint is NotImplemented or \ + not isinstance(hint, int_types) or \ + hint < 0: + return None + return hint + + +class ProgressBar(object): + + def __init__(self, iterable, length=None, fill_char='#', empty_char=' ', + bar_template='%(bar)s', info_sep=' ', show_eta=True, + show_percent=None, show_pos=False, item_show_func=None, + label=None, file=None, color=None, width=30): + self.fill_char = fill_char + self.empty_char = empty_char + self.bar_template = bar_template + self.info_sep = info_sep + self.show_eta = show_eta + self.show_percent = show_percent + self.show_pos = show_pos + self.item_show_func = item_show_func + self.label = label or '' + if file is None: + file = _default_text_stdout() + self.file = file + self.color = color + self.width = width + self.autowidth = width == 0 + + if length is None: + length = _length_hint(iterable) + if iterable is None: + if length is None: + raise TypeError('iterable or length is required') + iterable = range_type(length) + self.iter = iter(iterable) + self.length = length + self.length_known = length is not None + self.pos = 0 + self.avg = [] + self.start = self.last_eta = time.time() + self.eta_known = False + self.finished = False + self.max_width = None + self.entered = False + self.current_item = None + self.is_hidden = not isatty(self.file) + self._last_line = None + self.short_limit = 0.5 + + def __enter__(self): + self.entered = True + self.render_progress() + return self + + def __exit__(self, exc_type, exc_value, tb): + self.render_finish() + + def __iter__(self): + if not self.entered: + raise RuntimeError('You need to use progress bars in a with block.') + self.render_progress() + return self.generator() + + def is_fast(self): + return time.time() - self.start <= self.short_limit + + def render_finish(self): + if self.is_hidden or self.is_fast(): + return + self.file.write(AFTER_BAR) + self.file.flush() + + @property + def pct(self): + if self.finished: + return 1.0 + return min(self.pos / (float(self.length) or 1), 1.0) + + @property + def time_per_iteration(self): + if not self.avg: + return 0.0 + return sum(self.avg) / float(len(self.avg)) + + @property + def eta(self): + if self.length_known and not self.finished: + return self.time_per_iteration * (self.length - self.pos) + return 0.0 + + def format_eta(self): + if self.eta_known: + t = int(self.eta) + seconds = t % 60 + t //= 60 + minutes = t % 60 + t //= 60 + hours = t % 24 + t //= 24 + if t > 0: + days = t + return '%dd %02d:%02d:%02d' % (days, hours, minutes, seconds) + else: + return '%02d:%02d:%02d' % (hours, minutes, seconds) + return '' + + def format_pos(self): + pos = str(self.pos) + if self.length_known: + pos += '/%s' % self.length + return pos + + def format_pct(self): + return ('% 4d%%' % int(self.pct * 100))[1:] + + def format_bar(self): + if self.length_known: + bar_length = int(self.pct * self.width) + bar = self.fill_char * bar_length + bar += self.empty_char * (self.width - bar_length) + elif self.finished: + bar = self.fill_char * self.width + else: + bar = list(self.empty_char * (self.width or 1)) + if self.time_per_iteration != 0: + bar[int((math.cos(self.pos * self.time_per_iteration) + / 2.0 + 0.5) * self.width)] = self.fill_char + bar = ''.join(bar) + return bar + + def format_progress_line(self): + show_percent = self.show_percent + + info_bits = [] + if self.length_known and show_percent is None: + show_percent = not self.show_pos + + if self.show_pos: + info_bits.append(self.format_pos()) + if show_percent: + info_bits.append(self.format_pct()) + if self.show_eta and self.eta_known and not self.finished: + info_bits.append(self.format_eta()) + if self.item_show_func is not None: + item_info = self.item_show_func(self.current_item) + if item_info is not None: + info_bits.append(item_info) + + return (self.bar_template % { + 'label': self.label, + 'bar': self.format_bar(), + 'info': self.info_sep.join(info_bits) + }).rstrip() + + def render_progress(self): + from .termui import get_terminal_size + + if self.is_hidden: + return + + buf = [] + # Update width in case the terminal has been resized + if self.autowidth: + old_width = self.width + self.width = 0 + clutter_length = term_len(self.format_progress_line()) + new_width = max(0, get_terminal_size()[0] - clutter_length) + if new_width < old_width: + buf.append(BEFORE_BAR) + buf.append(' ' * self.max_width) + self.max_width = new_width + self.width = new_width + + clear_width = self.width + if self.max_width is not None: + clear_width = self.max_width + + buf.append(BEFORE_BAR) + line = self.format_progress_line() + line_len = term_len(line) + if self.max_width is None or self.max_width < line_len: + self.max_width = line_len + + buf.append(line) + buf.append(' ' * (clear_width - line_len)) + line = ''.join(buf) + # Render the line only if it changed. + + if line != self._last_line and not self.is_fast(): + self._last_line = line + echo(line, file=self.file, color=self.color, nl=False) + self.file.flush() + + def make_step(self, n_steps): + self.pos += n_steps + if self.length_known and self.pos >= self.length: + self.finished = True + + if (time.time() - self.last_eta) < 1.0: + return + + self.last_eta = time.time() + + # self.avg is a rolling list of length <= 7 of steps where steps are + # defined as time elapsed divided by the total progress through + # self.length. + if self.pos: + step = (time.time() - self.start) / self.pos + else: + step = time.time() - self.start + + self.avg = self.avg[-6:] + [step] + + self.eta_known = self.length_known + + def update(self, n_steps): + self.make_step(n_steps) + self.render_progress() + + def finish(self): + self.eta_known = 0 + self.current_item = None + self.finished = True + + def generator(self): + """ + Returns a generator which yields the items added to the bar during + construction, and updates the progress bar *after* the yielded block + returns. + """ + if not self.entered: + raise RuntimeError('You need to use progress bars in a with block.') + + if self.is_hidden: + for rv in self.iter: + yield rv + else: + for rv in self.iter: + self.current_item = rv + yield rv + self.update(1) + self.finish() + self.render_progress() + + +def pager(generator, color=None): + """Decide what method to use for paging through text.""" + stdout = _default_text_stdout() + if not isatty(sys.stdin) or not isatty(stdout): + return _nullpager(stdout, generator, color) + pager_cmd = (os.environ.get('PAGER', None) or '').strip() + if pager_cmd: + if WIN: + return _tempfilepager(generator, pager_cmd, color) + return _pipepager(generator, pager_cmd, color) + if os.environ.get('TERM') in ('dumb', 'emacs'): + return _nullpager(stdout, generator, color) + if WIN or sys.platform.startswith('os2'): + return _tempfilepager(generator, 'more <', color) + if hasattr(os, 'system') and os.system('(less) 2>/dev/null') == 0: + return _pipepager(generator, 'less', color) + + import tempfile + fd, filename = tempfile.mkstemp() + os.close(fd) + try: + if hasattr(os, 'system') and os.system('more "%s"' % filename) == 0: + return _pipepager(generator, 'more', color) + return _nullpager(stdout, generator, color) + finally: + os.unlink(filename) + + +def _pipepager(generator, cmd, color): + """Page through text by feeding it to another program. Invoking a + pager through this might support colors. + """ + import subprocess + env = dict(os.environ) + + # If we're piping to less we might support colors under the + # condition that + cmd_detail = cmd.rsplit('/', 1)[-1].split() + if color is None and cmd_detail[0] == 'less': + less_flags = os.environ.get('LESS', '') + ' '.join(cmd_detail[1:]) + if not less_flags: + env['LESS'] = '-R' + color = True + elif 'r' in less_flags or 'R' in less_flags: + color = True + + c = subprocess.Popen(cmd, shell=True, stdin=subprocess.PIPE, + env=env) + encoding = get_best_encoding(c.stdin) + try: + for text in generator: + if not color: + text = strip_ansi(text) + + c.stdin.write(text.encode(encoding, 'replace')) + except (IOError, KeyboardInterrupt): + pass + else: + c.stdin.close() + + # Less doesn't respect ^C, but catches it for its own UI purposes (aborting + # search or other commands inside less). + # + # That means when the user hits ^C, the parent process (click) terminates, + # but less is still alive, paging the output and messing up the terminal. + # + # If the user wants to make the pager exit on ^C, they should set + # `LESS='-K'`. It's not our decision to make. + while True: + try: + c.wait() + except KeyboardInterrupt: + pass + else: + break + + +def _tempfilepager(generator, cmd, color): + """Page through text by invoking a program on a temporary file.""" + import tempfile + filename = tempfile.mktemp() + # TODO: This never terminates if the passed generator never terminates. + text = "".join(generator) + if not color: + text = strip_ansi(text) + encoding = get_best_encoding(sys.stdout) + with open_stream(filename, 'wb')[0] as f: + f.write(text.encode(encoding)) + try: + os.system(cmd + ' "' + filename + '"') + finally: + os.unlink(filename) + + +def _nullpager(stream, generator, color): + """Simply print unformatted text. This is the ultimate fallback.""" + for text in generator: + if not color: + text = strip_ansi(text) + stream.write(text) + + +class Editor(object): + + def __init__(self, editor=None, env=None, require_save=True, + extension='.txt'): + self.editor = editor + self.env = env + self.require_save = require_save + self.extension = extension + + def get_editor(self): + if self.editor is not None: + return self.editor + for key in 'VISUAL', 'EDITOR': + rv = os.environ.get(key) + if rv: + return rv + if WIN: + return 'notepad' + for editor in 'vim', 'nano': + if os.system('which %s >/dev/null 2>&1' % editor) == 0: + return editor + return 'vi' + + def edit_file(self, filename): + import subprocess + editor = self.get_editor() + if self.env: + environ = os.environ.copy() + environ.update(self.env) + else: + environ = None + try: + c = subprocess.Popen('%s "%s"' % (editor, filename), + env=environ, shell=True) + exit_code = c.wait() + if exit_code != 0: + raise ClickException('%s: Editing failed!' % editor) + except OSError as e: + raise ClickException('%s: Editing failed: %s' % (editor, e)) + + def edit(self, text): + import tempfile + + text = text or '' + if text and not text.endswith('\n'): + text += '\n' + + fd, name = tempfile.mkstemp(prefix='editor-', suffix=self.extension) + try: + if WIN: + encoding = 'utf-8-sig' + text = text.replace('\n', '\r\n') + else: + encoding = 'utf-8' + text = text.encode(encoding) + + f = os.fdopen(fd, 'wb') + f.write(text) + f.close() + timestamp = os.path.getmtime(name) + + self.edit_file(name) + + if self.require_save \ + and os.path.getmtime(name) == timestamp: + return None + + f = open(name, 'rb') + try: + rv = f.read() + finally: + f.close() + return rv.decode('utf-8-sig').replace('\r\n', '\n') + finally: + os.unlink(name) + + +def open_url(url, wait=False, locate=False): + import subprocess + + def _unquote_file(url): + try: + import urllib + except ImportError: + import urllib + if url.startswith('file://'): + url = urllib.unquote(url[7:]) + return url + + if sys.platform == 'darwin': + args = ['open'] + if wait: + args.append('-W') + if locate: + args.append('-R') + args.append(_unquote_file(url)) + null = open('/dev/null', 'w') + try: + return subprocess.Popen(args, stderr=null).wait() + finally: + null.close() + elif WIN: + if locate: + url = _unquote_file(url) + args = 'explorer /select,"%s"' % _unquote_file( + url.replace('"', '')) + else: + args = 'start %s "" "%s"' % ( + wait and '/WAIT' or '', url.replace('"', '')) + return os.system(args) + elif CYGWIN: + if locate: + url = _unquote_file(url) + args = 'cygstart "%s"' % (os.path.dirname(url).replace('"', '')) + else: + args = 'cygstart %s "%s"' % ( + wait and '-w' or '', url.replace('"', '')) + return os.system(args) + + try: + if locate: + url = os.path.dirname(_unquote_file(url)) or '.' + else: + url = _unquote_file(url) + c = subprocess.Popen(['xdg-open', url]) + if wait: + return c.wait() + return 0 + except OSError: + if url.startswith(('http://', 'https://')) and not locate and not wait: + import webbrowser + webbrowser.open(url) + return 0 + return 1 + + +def _translate_ch_to_exc(ch): + if ch == u'\x03': + raise KeyboardInterrupt() + if ch == u'\x04' and not WIN: # Unix-like, Ctrl+D + raise EOFError() + if ch == u'\x1a' and WIN: # Windows, Ctrl+Z + raise EOFError() + + +if WIN: + import msvcrt + + @contextlib.contextmanager + def raw_terminal(): + yield + + def getchar(echo): + # The function `getch` will return a bytes object corresponding to + # the pressed character. Since Windows 10 build 1803, it will also + # return \x00 when called a second time after pressing a regular key. + # + # `getwch` does not share this probably-bugged behavior. Moreover, it + # returns a Unicode object by default, which is what we want. + # + # Either of these functions will return \x00 or \xe0 to indicate + # a special key, and you need to call the same function again to get + # the "rest" of the code. The fun part is that \u00e0 is + # "latin small letter a with grave", so if you type that on a French + # keyboard, you _also_ get a \xe0. + # E.g., consider the Up arrow. This returns \xe0 and then \x48. The + # resulting Unicode string reads as "a with grave" + "capital H". + # This is indistinguishable from when the user actually types + # "a with grave" and then "capital H". + # + # When \xe0 is returned, we assume it's part of a special-key sequence + # and call `getwch` again, but that means that when the user types + # the \u00e0 character, `getchar` doesn't return until a second + # character is typed. + # The alternative is returning immediately, but that would mess up + # cross-platform handling of arrow keys and others that start with + # \xe0. Another option is using `getch`, but then we can't reliably + # read non-ASCII characters, because return values of `getch` are + # limited to the current 8-bit codepage. + # + # Anyway, Click doesn't claim to do this Right(tm), and using `getwch` + # is doing the right thing in more situations than with `getch`. + if echo: + func = msvcrt.getwche + else: + func = msvcrt.getwch + + rv = func() + if rv in (u'\x00', u'\xe0'): + # \x00 and \xe0 are control characters that indicate special key, + # see above. + rv += func() + _translate_ch_to_exc(rv) + return rv +else: + import tty + import termios + + @contextlib.contextmanager + def raw_terminal(): + if not isatty(sys.stdin): + f = open('/dev/tty') + fd = f.fileno() + else: + fd = sys.stdin.fileno() + f = None + try: + old_settings = termios.tcgetattr(fd) + try: + tty.setraw(fd) + yield fd + finally: + termios.tcsetattr(fd, termios.TCSADRAIN, old_settings) + sys.stdout.flush() + if f is not None: + f.close() + except termios.error: + pass + + def getchar(echo): + with raw_terminal() as fd: + ch = os.read(fd, 32) + ch = ch.decode(get_best_encoding(sys.stdin), 'replace') + if echo and isatty(sys.stdout): + sys.stdout.write(ch) + _translate_ch_to_exc(ch) + return ch diff --git a/flask/venv/lib/python3.6/site-packages/click/_textwrap.py b/flask/venv/lib/python3.6/site-packages/click/_textwrap.py new file mode 100644 index 0000000..7e77603 --- /dev/null +++ b/flask/venv/lib/python3.6/site-packages/click/_textwrap.py @@ -0,0 +1,38 @@ +import textwrap +from contextlib import contextmanager + + +class TextWrapper(textwrap.TextWrapper): + + def _handle_long_word(self, reversed_chunks, cur_line, cur_len, width): + space_left = max(width - cur_len, 1) + + if self.break_long_words: + last = reversed_chunks[-1] + cut = last[:space_left] + res = last[space_left:] + cur_line.append(cut) + reversed_chunks[-1] = res + elif not cur_line: + cur_line.append(reversed_chunks.pop()) + + @contextmanager + def extra_indent(self, indent): + old_initial_indent = self.initial_indent + old_subsequent_indent = self.subsequent_indent + self.initial_indent += indent + self.subsequent_indent += indent + try: + yield + finally: + self.initial_indent = old_initial_indent + self.subsequent_indent = old_subsequent_indent + + def indent_only(self, text): + rv = [] + for idx, line in enumerate(text.splitlines()): + indent = self.initial_indent + if idx > 0: + indent = self.subsequent_indent + rv.append(indent + line) + return '\n'.join(rv) diff --git a/flask/venv/lib/python3.6/site-packages/click/_unicodefun.py b/flask/venv/lib/python3.6/site-packages/click/_unicodefun.py new file mode 100644 index 0000000..620edff --- /dev/null +++ b/flask/venv/lib/python3.6/site-packages/click/_unicodefun.py @@ -0,0 +1,125 @@ +import os +import sys +import codecs + +from ._compat import PY2 + + +# If someone wants to vendor click, we want to ensure the +# correct package is discovered. Ideally we could use a +# relative import here but unfortunately Python does not +# support that. +click = sys.modules[__name__.rsplit('.', 1)[0]] + + +def _find_unicode_literals_frame(): + import __future__ + if not hasattr(sys, '_getframe'): # not all Python implementations have it + return 0 + frm = sys._getframe(1) + idx = 1 + while frm is not None: + if frm.f_globals.get('__name__', '').startswith('click.'): + frm = frm.f_back + idx += 1 + elif frm.f_code.co_flags & __future__.unicode_literals.compiler_flag: + return idx + else: + break + return 0 + + +def _check_for_unicode_literals(): + if not __debug__: + return + if not PY2 or click.disable_unicode_literals_warning: + return + bad_frame = _find_unicode_literals_frame() + if bad_frame <= 0: + return + from warnings import warn + warn(Warning('Click detected the use of the unicode_literals ' + '__future__ import. This is heavily discouraged ' + 'because it can introduce subtle bugs in your ' + 'code. You should instead use explicit u"" literals ' + 'for your unicode strings. For more information see ' + 'https://click.palletsprojects.com/python3/'), + stacklevel=bad_frame) + + +def _verify_python3_env(): + """Ensures that the environment is good for unicode on Python 3.""" + if PY2: + return + try: + import locale + fs_enc = codecs.lookup(locale.getpreferredencoding()).name + except Exception: + fs_enc = 'ascii' + if fs_enc != 'ascii': + return + + extra = '' + if os.name == 'posix': + import subprocess + try: + rv = subprocess.Popen(['locale', '-a'], stdout=subprocess.PIPE, + stderr=subprocess.PIPE).communicate()[0] + except OSError: + rv = b'' + good_locales = set() + has_c_utf8 = False + + # Make sure we're operating on text here. + if isinstance(rv, bytes): + rv = rv.decode('ascii', 'replace') + + for line in rv.splitlines(): + locale = line.strip() + if locale.lower().endswith(('.utf-8', '.utf8')): + good_locales.add(locale) + if locale.lower() in ('c.utf8', 'c.utf-8'): + has_c_utf8 = True + + extra += '\n\n' + if not good_locales: + extra += ( + 'Additional information: on this system no suitable UTF-8\n' + 'locales were discovered. This most likely requires resolving\n' + 'by reconfiguring the locale system.' + ) + elif has_c_utf8: + extra += ( + 'This system supports the C.UTF-8 locale which is recommended.\n' + 'You might be able to resolve your issue by exporting the\n' + 'following environment variables:\n\n' + ' export LC_ALL=C.UTF-8\n' + ' export LANG=C.UTF-8' + ) + else: + extra += ( + 'This system lists a couple of UTF-8 supporting locales that\n' + 'you can pick from. The following suitable locales were\n' + 'discovered: %s' + ) % ', '.join(sorted(good_locales)) + + bad_locale = None + for locale in os.environ.get('LC_ALL'), os.environ.get('LANG'): + if locale and locale.lower().endswith(('.utf-8', '.utf8')): + bad_locale = locale + if locale is not None: + break + if bad_locale is not None: + extra += ( + '\n\nClick discovered that you exported a UTF-8 locale\n' + 'but the locale system could not pick up from it because\n' + 'it does not exist. The exported locale is "%s" but it\n' + 'is not supported' + ) % bad_locale + + raise RuntimeError( + 'Click will abort further execution because Python 3 was' + ' configured to use ASCII as encoding for the environment.' + ' Consult https://click.palletsprojects.com/en/7.x/python3/ for' + ' mitigation steps.' + extra + ) diff --git a/flask/venv/lib/python3.6/site-packages/click/_winconsole.py b/flask/venv/lib/python3.6/site-packages/click/_winconsole.py new file mode 100644 index 0000000..bbb080d --- /dev/null +++ b/flask/venv/lib/python3.6/site-packages/click/_winconsole.py @@ -0,0 +1,307 @@ +# -*- coding: utf-8 -*- +# This module is based on the excellent work by Adam Bartoš who +# provided a lot of what went into the implementation here in +# the discussion to issue1602 in the Python bug tracker. +# +# There are some general differences in regards to how this works +# compared to the original patches as we do not need to patch +# the entire interpreter but just work in our little world of +# echo and prmopt. + +import io +import os +import sys +import zlib +import time +import ctypes +import msvcrt +from ._compat import _NonClosingTextIOWrapper, text_type, PY2 +from ctypes import byref, POINTER, c_int, c_char, c_char_p, \ + c_void_p, py_object, c_ssize_t, c_ulong, windll, WINFUNCTYPE +try: + from ctypes import pythonapi + PyObject_GetBuffer = pythonapi.PyObject_GetBuffer + PyBuffer_Release = pythonapi.PyBuffer_Release +except ImportError: + pythonapi = None +from ctypes.wintypes import LPWSTR, LPCWSTR + + +c_ssize_p = POINTER(c_ssize_t) + +kernel32 = windll.kernel32 +GetStdHandle = kernel32.GetStdHandle +ReadConsoleW = kernel32.ReadConsoleW +WriteConsoleW = kernel32.WriteConsoleW +GetLastError = kernel32.GetLastError +GetCommandLineW = WINFUNCTYPE(LPWSTR)( + ('GetCommandLineW', windll.kernel32)) +CommandLineToArgvW = WINFUNCTYPE( + POINTER(LPWSTR), LPCWSTR, POINTER(c_int))( + ('CommandLineToArgvW', windll.shell32)) + + +STDIN_HANDLE = GetStdHandle(-10) +STDOUT_HANDLE = GetStdHandle(-11) +STDERR_HANDLE = GetStdHandle(-12) + + +PyBUF_SIMPLE = 0 +PyBUF_WRITABLE = 1 + +ERROR_SUCCESS = 0 +ERROR_NOT_ENOUGH_MEMORY = 8 +ERROR_OPERATION_ABORTED = 995 + +STDIN_FILENO = 0 +STDOUT_FILENO = 1 +STDERR_FILENO = 2 + +EOF = b'\x1a' +MAX_BYTES_WRITTEN = 32767 + + +class Py_buffer(ctypes.Structure): + _fields_ = [ + ('buf', c_void_p), + ('obj', py_object), + ('len', c_ssize_t), + ('itemsize', c_ssize_t), + ('readonly', c_int), + ('ndim', c_int), + ('format', c_char_p), + ('shape', c_ssize_p), + ('strides', c_ssize_p), + ('suboffsets', c_ssize_p), + ('internal', c_void_p) + ] + + if PY2: + _fields_.insert(-1, ('smalltable', c_ssize_t * 2)) + + +# On PyPy we cannot get buffers so our ability to operate here is +# serverly limited. +if pythonapi is None: + get_buffer = None +else: + def get_buffer(obj, writable=False): + buf = Py_buffer() + flags = PyBUF_WRITABLE if writable else PyBUF_SIMPLE + PyObject_GetBuffer(py_object(obj), byref(buf), flags) + try: + buffer_type = c_char * buf.len + return buffer_type.from_address(buf.buf) + finally: + PyBuffer_Release(byref(buf)) + + +class _WindowsConsoleRawIOBase(io.RawIOBase): + + def __init__(self, handle): + self.handle = handle + + def isatty(self): + io.RawIOBase.isatty(self) + return True + + +class _WindowsConsoleReader(_WindowsConsoleRawIOBase): + + def readable(self): + return True + + def readinto(self, b): + bytes_to_be_read = len(b) + if not bytes_to_be_read: + return 0 + elif bytes_to_be_read % 2: + raise ValueError('cannot read odd number of bytes from ' + 'UTF-16-LE encoded console') + + buffer = get_buffer(b, writable=True) + code_units_to_be_read = bytes_to_be_read // 2 + code_units_read = c_ulong() + + rv = ReadConsoleW(self.handle, buffer, code_units_to_be_read, + byref(code_units_read), None) + if GetLastError() == ERROR_OPERATION_ABORTED: + # wait for KeyboardInterrupt + time.sleep(0.1) + if not rv: + raise OSError('Windows error: %s' % GetLastError()) + + if buffer[0] == EOF: + return 0 + return 2 * code_units_read.value + + +class _WindowsConsoleWriter(_WindowsConsoleRawIOBase): + + def writable(self): + return True + + @staticmethod + def _get_error_message(errno): + if errno == ERROR_SUCCESS: + return 'ERROR_SUCCESS' + elif errno == ERROR_NOT_ENOUGH_MEMORY: + return 'ERROR_NOT_ENOUGH_MEMORY' + return 'Windows error %s' % errno + + def write(self, b): + bytes_to_be_written = len(b) + buf = get_buffer(b) + code_units_to_be_written = min(bytes_to_be_written, + MAX_BYTES_WRITTEN) // 2 + code_units_written = c_ulong() + + WriteConsoleW(self.handle, buf, code_units_to_be_written, + byref(code_units_written), None) + bytes_written = 2 * code_units_written.value + + if bytes_written == 0 and bytes_to_be_written > 0: + raise OSError(self._get_error_message(GetLastError())) + return bytes_written + + +class ConsoleStream(object): + + def __init__(self, text_stream, byte_stream): + self._text_stream = text_stream + self.buffer = byte_stream + + @property + def name(self): + return self.buffer.name + + def write(self, x): + if isinstance(x, text_type): + return self._text_stream.write(x) + try: + self.flush() + except Exception: + pass + return self.buffer.write(x) + + def writelines(self, lines): + for line in lines: + self.write(line) + + def __getattr__(self, name): + return getattr(self._text_stream, name) + + def isatty(self): + return self.buffer.isatty() + + def __repr__(self): + return '' % ( + self.name, + self.encoding, + ) + + +class WindowsChunkedWriter(object): + """ + Wraps a stream (such as stdout), acting as a transparent proxy for all + attribute access apart from method 'write()' which we wrap to write in + limited chunks due to a Windows limitation on binary console streams. + """ + def __init__(self, wrapped): + # double-underscore everything to prevent clashes with names of + # attributes on the wrapped stream object. + self.__wrapped = wrapped + + def __getattr__(self, name): + return getattr(self.__wrapped, name) + + def write(self, text): + total_to_write = len(text) + written = 0 + + while written < total_to_write: + to_write = min(total_to_write - written, MAX_BYTES_WRITTEN) + self.__wrapped.write(text[written:written+to_write]) + written += to_write + + +_wrapped_std_streams = set() + + +def _wrap_std_stream(name): + # Python 2 & Windows 7 and below + if PY2 and sys.getwindowsversion()[:2] <= (6, 1) and name not in _wrapped_std_streams: + setattr(sys, name, WindowsChunkedWriter(getattr(sys, name))) + _wrapped_std_streams.add(name) + + +def _get_text_stdin(buffer_stream): + text_stream = _NonClosingTextIOWrapper( + io.BufferedReader(_WindowsConsoleReader(STDIN_HANDLE)), + 'utf-16-le', 'strict', line_buffering=True) + return ConsoleStream(text_stream, buffer_stream) + + +def _get_text_stdout(buffer_stream): + text_stream = _NonClosingTextIOWrapper( + io.BufferedWriter(_WindowsConsoleWriter(STDOUT_HANDLE)), + 'utf-16-le', 'strict', line_buffering=True) + return ConsoleStream(text_stream, buffer_stream) + + +def _get_text_stderr(buffer_stream): + text_stream = _NonClosingTextIOWrapper( + io.BufferedWriter(_WindowsConsoleWriter(STDERR_HANDLE)), + 'utf-16-le', 'strict', line_buffering=True) + return ConsoleStream(text_stream, buffer_stream) + + +if PY2: + def _hash_py_argv(): + return zlib.crc32('\x00'.join(sys.argv[1:])) + + _initial_argv_hash = _hash_py_argv() + + def _get_windows_argv(): + argc = c_int(0) + argv_unicode = CommandLineToArgvW(GetCommandLineW(), byref(argc)) + argv = [argv_unicode[i] for i in range(0, argc.value)] + + if not hasattr(sys, 'frozen'): + argv = argv[1:] + while len(argv) > 0: + arg = argv[0] + if not arg.startswith('-') or arg == '-': + break + argv = argv[1:] + if arg.startswith(('-c', '-m')): + break + + return argv[1:] + + +_stream_factories = { + 0: _get_text_stdin, + 1: _get_text_stdout, + 2: _get_text_stderr, +} + + +def _get_windows_console_stream(f, encoding, errors): + if get_buffer is not None and \ + encoding in ('utf-16-le', None) \ + and errors in ('strict', None) and \ + hasattr(f, 'isatty') and f.isatty(): + func = _stream_factories.get(f.fileno()) + if func is not None: + if not PY2: + f = getattr(f, 'buffer', None) + if f is None: + return None + else: + # If we are on Python 2 we need to set the stream that we + # deal with to binary mode as otherwise the exercise if a + # bit moot. The same problems apply as for + # get_binary_stdin and friends from _compat. + msvcrt.setmode(f.fileno(), os.O_BINARY) + return func(f) diff --git a/flask/venv/lib/python3.6/site-packages/click/core.py b/flask/venv/lib/python3.6/site-packages/click/core.py new file mode 100644 index 0000000..7a1e342 --- /dev/null +++ b/flask/venv/lib/python3.6/site-packages/click/core.py @@ -0,0 +1,1856 @@ +import errno +import inspect +import os +import sys +from contextlib import contextmanager +from itertools import repeat +from functools import update_wrapper + +from .types import convert_type, IntRange, BOOL +from .utils import PacifyFlushWrapper, make_str, make_default_short_help, \ + echo, get_os_args +from .exceptions import ClickException, UsageError, BadParameter, Abort, \ + MissingParameter, Exit +from .termui import prompt, confirm, style +from .formatting import HelpFormatter, join_options +from .parser import OptionParser, split_opt +from .globals import push_context, pop_context + +from ._compat import PY2, isidentifier, iteritems, string_types +from ._unicodefun import _check_for_unicode_literals, _verify_python3_env + + +_missing = object() + + +SUBCOMMAND_METAVAR = 'COMMAND [ARGS]...' +SUBCOMMANDS_METAVAR = 'COMMAND1 [ARGS]... [COMMAND2 [ARGS]...]...' + +DEPRECATED_HELP_NOTICE = ' (DEPRECATED)' +DEPRECATED_INVOKE_NOTICE = 'DeprecationWarning: ' + \ + 'The command %(name)s is deprecated.' + + +def _maybe_show_deprecated_notice(cmd): + if cmd.deprecated: + echo(style(DEPRECATED_INVOKE_NOTICE % {'name': cmd.name}, fg='red'), err=True) + + +def fast_exit(code): + """Exit without garbage collection, this speeds up exit by about 10ms for + things like bash completion. + """ + sys.stdout.flush() + sys.stderr.flush() + os._exit(code) + + +def _bashcomplete(cmd, prog_name, complete_var=None): + """Internal handler for the bash completion support.""" + if complete_var is None: + complete_var = '_%s_COMPLETE' % (prog_name.replace('-', '_')).upper() + complete_instr = os.environ.get(complete_var) + if not complete_instr: + return + + from ._bashcomplete import bashcomplete + if bashcomplete(cmd, prog_name, complete_var, complete_instr): + fast_exit(1) + + +def _check_multicommand(base_command, cmd_name, cmd, register=False): + if not base_command.chain or not isinstance(cmd, MultiCommand): + return + if register: + hint = 'It is not possible to add multi commands as children to ' \ + 'another multi command that is in chain mode' + else: + hint = 'Found a multi command as subcommand to a multi command ' \ + 'that is in chain mode. This is not supported' + raise RuntimeError('%s. Command "%s" is set to chain and "%s" was ' + 'added as subcommand but it in itself is a ' + 'multi command. ("%s" is a %s within a chained ' + '%s named "%s").' % ( + hint, base_command.name, cmd_name, + cmd_name, cmd.__class__.__name__, + base_command.__class__.__name__, + base_command.name)) + + +def batch(iterable, batch_size): + return list(zip(*repeat(iter(iterable), batch_size))) + + +def invoke_param_callback(callback, ctx, param, value): + code = getattr(callback, '__code__', None) + args = getattr(code, 'co_argcount', 3) + + if args < 3: + # This will become a warning in Click 3.0: + from warnings import warn + warn(Warning('Invoked legacy parameter callback "%s". The new ' + 'signature for such callbacks starting with ' + 'click 2.0 is (ctx, param, value).' + % callback), stacklevel=3) + return callback(ctx, value) + return callback(ctx, param, value) + + +@contextmanager +def augment_usage_errors(ctx, param=None): + """Context manager that attaches extra information to exceptions that + fly. + """ + try: + yield + except BadParameter as e: + if e.ctx is None: + e.ctx = ctx + if param is not None and e.param is None: + e.param = param + raise + except UsageError as e: + if e.ctx is None: + e.ctx = ctx + raise + + +def iter_params_for_processing(invocation_order, declaration_order): + """Given a sequence of parameters in the order as should be considered + for processing and an iterable of parameters that exist, this returns + a list in the correct order as they should be processed. + """ + def sort_key(item): + try: + idx = invocation_order.index(item) + except ValueError: + idx = float('inf') + return (not item.is_eager, idx) + + return sorted(declaration_order, key=sort_key) + + +class Context(object): + """The context is a special internal object that holds state relevant + for the script execution at every single level. It's normally invisible + to commands unless they opt-in to getting access to it. + + The context is useful as it can pass internal objects around and can + control special execution features such as reading data from + environment variables. + + A context can be used as context manager in which case it will call + :meth:`close` on teardown. + + .. versionadded:: 2.0 + Added the `resilient_parsing`, `help_option_names`, + `token_normalize_func` parameters. + + .. versionadded:: 3.0 + Added the `allow_extra_args` and `allow_interspersed_args` + parameters. + + .. versionadded:: 4.0 + Added the `color`, `ignore_unknown_options`, and + `max_content_width` parameters. + + :param command: the command class for this context. + :param parent: the parent context. + :param info_name: the info name for this invocation. Generally this + is the most descriptive name for the script or + command. For the toplevel script it is usually + the name of the script, for commands below it it's + the name of the script. + :param obj: an arbitrary object of user data. + :param auto_envvar_prefix: the prefix to use for automatic environment + variables. If this is `None` then reading + from environment variables is disabled. This + does not affect manually set environment + variables which are always read. + :param default_map: a dictionary (like object) with default values + for parameters. + :param terminal_width: the width of the terminal. The default is + inherit from parent context. If no context + defines the terminal width then auto + detection will be applied. + :param max_content_width: the maximum width for content rendered by + Click (this currently only affects help + pages). This defaults to 80 characters if + not overridden. In other words: even if the + terminal is larger than that, Click will not + format things wider than 80 characters by + default. In addition to that, formatters might + add some safety mapping on the right. + :param resilient_parsing: if this flag is enabled then Click will + parse without any interactivity or callback + invocation. Default values will also be + ignored. This is useful for implementing + things such as completion support. + :param allow_extra_args: if this is set to `True` then extra arguments + at the end will not raise an error and will be + kept on the context. The default is to inherit + from the command. + :param allow_interspersed_args: if this is set to `False` then options + and arguments cannot be mixed. The + default is to inherit from the command. + :param ignore_unknown_options: instructs click to ignore options it does + not know and keeps them for later + processing. + :param help_option_names: optionally a list of strings that define how + the default help parameter is named. The + default is ``['--help']``. + :param token_normalize_func: an optional function that is used to + normalize tokens (options, choices, + etc.). This for instance can be used to + implement case insensitive behavior. + :param color: controls if the terminal supports ANSI colors or not. The + default is autodetection. This is only needed if ANSI + codes are used in texts that Click prints which is by + default not the case. This for instance would affect + help output. + """ + + def __init__(self, command, parent=None, info_name=None, obj=None, + auto_envvar_prefix=None, default_map=None, + terminal_width=None, max_content_width=None, + resilient_parsing=False, allow_extra_args=None, + allow_interspersed_args=None, + ignore_unknown_options=None, help_option_names=None, + token_normalize_func=None, color=None): + #: the parent context or `None` if none exists. + self.parent = parent + #: the :class:`Command` for this context. + self.command = command + #: the descriptive information name + self.info_name = info_name + #: the parsed parameters except if the value is hidden in which + #: case it's not remembered. + self.params = {} + #: the leftover arguments. + self.args = [] + #: protected arguments. These are arguments that are prepended + #: to `args` when certain parsing scenarios are encountered but + #: must be never propagated to another arguments. This is used + #: to implement nested parsing. + self.protected_args = [] + if obj is None and parent is not None: + obj = parent.obj + #: the user object stored. + self.obj = obj + self._meta = getattr(parent, 'meta', {}) + + #: A dictionary (-like object) with defaults for parameters. + if default_map is None \ + and parent is not None \ + and parent.default_map is not None: + default_map = parent.default_map.get(info_name) + self.default_map = default_map + + #: This flag indicates if a subcommand is going to be executed. A + #: group callback can use this information to figure out if it's + #: being executed directly or because the execution flow passes + #: onwards to a subcommand. By default it's None, but it can be + #: the name of the subcommand to execute. + #: + #: If chaining is enabled this will be set to ``'*'`` in case + #: any commands are executed. It is however not possible to + #: figure out which ones. If you require this knowledge you + #: should use a :func:`resultcallback`. + self.invoked_subcommand = None + + if terminal_width is None and parent is not None: + terminal_width = parent.terminal_width + #: The width of the terminal (None is autodetection). + self.terminal_width = terminal_width + + if max_content_width is None and parent is not None: + max_content_width = parent.max_content_width + #: The maximum width of formatted content (None implies a sensible + #: default which is 80 for most things). + self.max_content_width = max_content_width + + if allow_extra_args is None: + allow_extra_args = command.allow_extra_args + #: Indicates if the context allows extra args or if it should + #: fail on parsing. + #: + #: .. versionadded:: 3.0 + self.allow_extra_args = allow_extra_args + + if allow_interspersed_args is None: + allow_interspersed_args = command.allow_interspersed_args + #: Indicates if the context allows mixing of arguments and + #: options or not. + #: + #: .. versionadded:: 3.0 + self.allow_interspersed_args = allow_interspersed_args + + if ignore_unknown_options is None: + ignore_unknown_options = command.ignore_unknown_options + #: Instructs click to ignore options that a command does not + #: understand and will store it on the context for later + #: processing. This is primarily useful for situations where you + #: want to call into external programs. Generally this pattern is + #: strongly discouraged because it's not possibly to losslessly + #: forward all arguments. + #: + #: .. versionadded:: 4.0 + self.ignore_unknown_options = ignore_unknown_options + + if help_option_names is None: + if parent is not None: + help_option_names = parent.help_option_names + else: + help_option_names = ['--help'] + + #: The names for the help options. + self.help_option_names = help_option_names + + if token_normalize_func is None and parent is not None: + token_normalize_func = parent.token_normalize_func + + #: An optional normalization function for tokens. This is + #: options, choices, commands etc. + self.token_normalize_func = token_normalize_func + + #: Indicates if resilient parsing is enabled. In that case Click + #: will do its best to not cause any failures and default values + #: will be ignored. Useful for completion. + self.resilient_parsing = resilient_parsing + + # If there is no envvar prefix yet, but the parent has one and + # the command on this level has a name, we can expand the envvar + # prefix automatically. + if auto_envvar_prefix is None: + if parent is not None \ + and parent.auto_envvar_prefix is not None and \ + self.info_name is not None: + auto_envvar_prefix = '%s_%s' % (parent.auto_envvar_prefix, + self.info_name.upper()) + else: + auto_envvar_prefix = auto_envvar_prefix.upper() + self.auto_envvar_prefix = auto_envvar_prefix + + if color is None and parent is not None: + color = parent.color + + #: Controls if styling output is wanted or not. + self.color = color + + self._close_callbacks = [] + self._depth = 0 + + def __enter__(self): + self._depth += 1 + push_context(self) + return self + + def __exit__(self, exc_type, exc_value, tb): + self._depth -= 1 + if self._depth == 0: + self.close() + pop_context() + + @contextmanager + def scope(self, cleanup=True): + """This helper method can be used with the context object to promote + it to the current thread local (see :func:`get_current_context`). + The default behavior of this is to invoke the cleanup functions which + can be disabled by setting `cleanup` to `False`. The cleanup + functions are typically used for things such as closing file handles. + + If the cleanup is intended the context object can also be directly + used as a context manager. + + Example usage:: + + with ctx.scope(): + assert get_current_context() is ctx + + This is equivalent:: + + with ctx: + assert get_current_context() is ctx + + .. versionadded:: 5.0 + + :param cleanup: controls if the cleanup functions should be run or + not. The default is to run these functions. In + some situations the context only wants to be + temporarily pushed in which case this can be disabled. + Nested pushes automatically defer the cleanup. + """ + if not cleanup: + self._depth += 1 + try: + with self as rv: + yield rv + finally: + if not cleanup: + self._depth -= 1 + + @property + def meta(self): + """This is a dictionary which is shared with all the contexts + that are nested. It exists so that click utilities can store some + state here if they need to. It is however the responsibility of + that code to manage this dictionary well. + + The keys are supposed to be unique dotted strings. For instance + module paths are a good choice for it. What is stored in there is + irrelevant for the operation of click. However what is important is + that code that places data here adheres to the general semantics of + the system. + + Example usage:: + + LANG_KEY = __name__ + '.lang' + + def set_language(value): + ctx = get_current_context() + ctx.meta[LANG_KEY] = value + + def get_language(): + return get_current_context().meta.get(LANG_KEY, 'en_US') + + .. versionadded:: 5.0 + """ + return self._meta + + def make_formatter(self): + """Creates the formatter for the help and usage output.""" + return HelpFormatter(width=self.terminal_width, + max_width=self.max_content_width) + + def call_on_close(self, f): + """This decorator remembers a function as callback that should be + executed when the context tears down. This is most useful to bind + resource handling to the script execution. For instance, file objects + opened by the :class:`File` type will register their close callbacks + here. + + :param f: the function to execute on teardown. + """ + self._close_callbacks.append(f) + return f + + def close(self): + """Invokes all close callbacks.""" + for cb in self._close_callbacks: + cb() + self._close_callbacks = [] + + @property + def command_path(self): + """The computed command path. This is used for the ``usage`` + information on the help page. It's automatically created by + combining the info names of the chain of contexts to the root. + """ + rv = '' + if self.info_name is not None: + rv = self.info_name + if self.parent is not None: + rv = self.parent.command_path + ' ' + rv + return rv.lstrip() + + def find_root(self): + """Finds the outermost context.""" + node = self + while node.parent is not None: + node = node.parent + return node + + def find_object(self, object_type): + """Finds the closest object of a given type.""" + node = self + while node is not None: + if isinstance(node.obj, object_type): + return node.obj + node = node.parent + + def ensure_object(self, object_type): + """Like :meth:`find_object` but sets the innermost object to a + new instance of `object_type` if it does not exist. + """ + rv = self.find_object(object_type) + if rv is None: + self.obj = rv = object_type() + return rv + + def lookup_default(self, name): + """Looks up the default for a parameter name. This by default + looks into the :attr:`default_map` if available. + """ + if self.default_map is not None: + rv = self.default_map.get(name) + if callable(rv): + rv = rv() + return rv + + def fail(self, message): + """Aborts the execution of the program with a specific error + message. + + :param message: the error message to fail with. + """ + raise UsageError(message, self) + + def abort(self): + """Aborts the script.""" + raise Abort() + + def exit(self, code=0): + """Exits the application with a given exit code.""" + raise Exit(code) + + def get_usage(self): + """Helper method to get formatted usage string for the current + context and command. + """ + return self.command.get_usage(self) + + def get_help(self): + """Helper method to get formatted help page for the current + context and command. + """ + return self.command.get_help(self) + + def invoke(*args, **kwargs): + """Invokes a command callback in exactly the way it expects. There + are two ways to invoke this method: + + 1. the first argument can be a callback and all other arguments and + keyword arguments are forwarded directly to the function. + 2. the first argument is a click command object. In that case all + arguments are forwarded as well but proper click parameters + (options and click arguments) must be keyword arguments and Click + will fill in defaults. + + Note that before Click 3.2 keyword arguments were not properly filled + in against the intention of this code and no context was created. For + more information about this change and why it was done in a bugfix + release see :ref:`upgrade-to-3.2`. + """ + self, callback = args[:2] + ctx = self + + # It's also possible to invoke another command which might or + # might not have a callback. In that case we also fill + # in defaults and make a new context for this command. + if isinstance(callback, Command): + other_cmd = callback + callback = other_cmd.callback + ctx = Context(other_cmd, info_name=other_cmd.name, parent=self) + if callback is None: + raise TypeError('The given command does not have a ' + 'callback that can be invoked.') + + for param in other_cmd.params: + if param.name not in kwargs and param.expose_value: + kwargs[param.name] = param.get_default(ctx) + + args = args[2:] + with augment_usage_errors(self): + with ctx: + return callback(*args, **kwargs) + + def forward(*args, **kwargs): + """Similar to :meth:`invoke` but fills in default keyword + arguments from the current context if the other command expects + it. This cannot invoke callbacks directly, only other commands. + """ + self, cmd = args[:2] + + # It's also possible to invoke another command which might or + # might not have a callback. + if not isinstance(cmd, Command): + raise TypeError('Callback is not a command.') + + for param in self.params: + if param not in kwargs: + kwargs[param] = self.params[param] + + return self.invoke(cmd, **kwargs) + + +class BaseCommand(object): + """The base command implements the minimal API contract of commands. + Most code will never use this as it does not implement a lot of useful + functionality but it can act as the direct subclass of alternative + parsing methods that do not depend on the Click parser. + + For instance, this can be used to bridge Click and other systems like + argparse or docopt. + + Because base commands do not implement a lot of the API that other + parts of Click take for granted, they are not supported for all + operations. For instance, they cannot be used with the decorators + usually and they have no built-in callback system. + + .. versionchanged:: 2.0 + Added the `context_settings` parameter. + + :param name: the name of the command to use unless a group overrides it. + :param context_settings: an optional dictionary with defaults that are + passed to the context object. + """ + #: the default for the :attr:`Context.allow_extra_args` flag. + allow_extra_args = False + #: the default for the :attr:`Context.allow_interspersed_args` flag. + allow_interspersed_args = True + #: the default for the :attr:`Context.ignore_unknown_options` flag. + ignore_unknown_options = False + + def __init__(self, name, context_settings=None): + #: the name the command thinks it has. Upon registering a command + #: on a :class:`Group` the group will default the command name + #: with this information. You should instead use the + #: :class:`Context`\'s :attr:`~Context.info_name` attribute. + self.name = name + if context_settings is None: + context_settings = {} + #: an optional dictionary with defaults passed to the context. + self.context_settings = context_settings + + def get_usage(self, ctx): + raise NotImplementedError('Base commands cannot get usage') + + def get_help(self, ctx): + raise NotImplementedError('Base commands cannot get help') + + def make_context(self, info_name, args, parent=None, **extra): + """This function when given an info name and arguments will kick + off the parsing and create a new :class:`Context`. It does not + invoke the actual command callback though. + + :param info_name: the info name for this invokation. Generally this + is the most descriptive name for the script or + command. For the toplevel script it's usually + the name of the script, for commands below it it's + the name of the script. + :param args: the arguments to parse as list of strings. + :param parent: the parent context if available. + :param extra: extra keyword arguments forwarded to the context + constructor. + """ + for key, value in iteritems(self.context_settings): + if key not in extra: + extra[key] = value + ctx = Context(self, info_name=info_name, parent=parent, **extra) + with ctx.scope(cleanup=False): + self.parse_args(ctx, args) + return ctx + + def parse_args(self, ctx, args): + """Given a context and a list of arguments this creates the parser + and parses the arguments, then modifies the context as necessary. + This is automatically invoked by :meth:`make_context`. + """ + raise NotImplementedError('Base commands do not know how to parse ' + 'arguments.') + + def invoke(self, ctx): + """Given a context, this invokes the command. The default + implementation is raising a not implemented error. + """ + raise NotImplementedError('Base commands are not invokable by default') + + def main(self, args=None, prog_name=None, complete_var=None, + standalone_mode=True, **extra): + """This is the way to invoke a script with all the bells and + whistles as a command line application. This will always terminate + the application after a call. If this is not wanted, ``SystemExit`` + needs to be caught. + + This method is also available by directly calling the instance of + a :class:`Command`. + + .. versionadded:: 3.0 + Added the `standalone_mode` flag to control the standalone mode. + + :param args: the arguments that should be used for parsing. If not + provided, ``sys.argv[1:]`` is used. + :param prog_name: the program name that should be used. By default + the program name is constructed by taking the file + name from ``sys.argv[0]``. + :param complete_var: the environment variable that controls the + bash completion support. The default is + ``"__COMPLETE"`` with prog_name in + uppercase. + :param standalone_mode: the default behavior is to invoke the script + in standalone mode. Click will then + handle exceptions and convert them into + error messages and the function will never + return but shut down the interpreter. If + this is set to `False` they will be + propagated to the caller and the return + value of this function is the return value + of :meth:`invoke`. + :param extra: extra keyword arguments are forwarded to the context + constructor. See :class:`Context` for more information. + """ + # If we are in Python 3, we will verify that the environment is + # sane at this point or reject further execution to avoid a + # broken script. + if not PY2: + _verify_python3_env() + else: + _check_for_unicode_literals() + + if args is None: + args = get_os_args() + else: + args = list(args) + + if prog_name is None: + prog_name = make_str(os.path.basename( + sys.argv and sys.argv[0] or __file__)) + + # Hook for the Bash completion. This only activates if the Bash + # completion is actually enabled, otherwise this is quite a fast + # noop. + _bashcomplete(self, prog_name, complete_var) + + try: + try: + with self.make_context(prog_name, args, **extra) as ctx: + rv = self.invoke(ctx) + if not standalone_mode: + return rv + # it's not safe to `ctx.exit(rv)` here! + # note that `rv` may actually contain data like "1" which + # has obvious effects + # more subtle case: `rv=[None, None]` can come out of + # chained commands which all returned `None` -- so it's not + # even always obvious that `rv` indicates success/failure + # by its truthiness/falsiness + ctx.exit() + except (EOFError, KeyboardInterrupt): + echo(file=sys.stderr) + raise Abort() + except ClickException as e: + if not standalone_mode: + raise + e.show() + sys.exit(e.exit_code) + except IOError as e: + if e.errno == errno.EPIPE: + sys.stdout = PacifyFlushWrapper(sys.stdout) + sys.stderr = PacifyFlushWrapper(sys.stderr) + sys.exit(1) + else: + raise + except Exit as e: + if standalone_mode: + sys.exit(e.exit_code) + else: + # in non-standalone mode, return the exit code + # note that this is only reached if `self.invoke` above raises + # an Exit explicitly -- thus bypassing the check there which + # would return its result + # the results of non-standalone execution may therefore be + # somewhat ambiguous: if there are codepaths which lead to + # `ctx.exit(1)` and to `return 1`, the caller won't be able to + # tell the difference between the two + return e.exit_code + except Abort: + if not standalone_mode: + raise + echo('Aborted!', file=sys.stderr) + sys.exit(1) + + def __call__(self, *args, **kwargs): + """Alias for :meth:`main`.""" + return self.main(*args, **kwargs) + + +class Command(BaseCommand): + """Commands are the basic building block of command line interfaces in + Click. A basic command handles command line parsing and might dispatch + more parsing to commands nested below it. + + .. versionchanged:: 2.0 + Added the `context_settings` parameter. + + :param name: the name of the command to use unless a group overrides it. + :param context_settings: an optional dictionary with defaults that are + passed to the context object. + :param callback: the callback to invoke. This is optional. + :param params: the parameters to register with this command. This can + be either :class:`Option` or :class:`Argument` objects. + :param help: the help string to use for this command. + :param epilog: like the help string but it's printed at the end of the + help page after everything else. + :param short_help: the short help to use for this command. This is + shown on the command listing of the parent command. + :param add_help_option: by default each command registers a ``--help`` + option. This can be disabled by this parameter. + :param hidden: hide this command from help outputs. + + :param deprecated: issues a message indicating that + the command is deprecated. + """ + + def __init__(self, name, context_settings=None, callback=None, + params=None, help=None, epilog=None, short_help=None, + options_metavar='[OPTIONS]', add_help_option=True, + hidden=False, deprecated=False): + BaseCommand.__init__(self, name, context_settings) + #: the callback to execute when the command fires. This might be + #: `None` in which case nothing happens. + self.callback = callback + #: the list of parameters for this command in the order they + #: should show up in the help page and execute. Eager parameters + #: will automatically be handled before non eager ones. + self.params = params or [] + # if a form feed (page break) is found in the help text, truncate help + # text to the content preceding the first form feed + if help and '\f' in help: + help = help.split('\f', 1)[0] + self.help = help + self.epilog = epilog + self.options_metavar = options_metavar + self.short_help = short_help + self.add_help_option = add_help_option + self.hidden = hidden + self.deprecated = deprecated + + def get_usage(self, ctx): + formatter = ctx.make_formatter() + self.format_usage(ctx, formatter) + return formatter.getvalue().rstrip('\n') + + def get_params(self, ctx): + rv = self.params + help_option = self.get_help_option(ctx) + if help_option is not None: + rv = rv + [help_option] + return rv + + def format_usage(self, ctx, formatter): + """Writes the usage line into the formatter.""" + pieces = self.collect_usage_pieces(ctx) + formatter.write_usage(ctx.command_path, ' '.join(pieces)) + + def collect_usage_pieces(self, ctx): + """Returns all the pieces that go into the usage line and returns + it as a list of strings. + """ + rv = [self.options_metavar] + for param in self.get_params(ctx): + rv.extend(param.get_usage_pieces(ctx)) + return rv + + def get_help_option_names(self, ctx): + """Returns the names for the help option.""" + all_names = set(ctx.help_option_names) + for param in self.params: + all_names.difference_update(param.opts) + all_names.difference_update(param.secondary_opts) + return all_names + + def get_help_option(self, ctx): + """Returns the help option object.""" + help_options = self.get_help_option_names(ctx) + if not help_options or not self.add_help_option: + return + + def show_help(ctx, param, value): + if value and not ctx.resilient_parsing: + echo(ctx.get_help(), color=ctx.color) + ctx.exit() + return Option(help_options, is_flag=True, + is_eager=True, expose_value=False, + callback=show_help, + help='Show this message and exit.') + + def make_parser(self, ctx): + """Creates the underlying option parser for this command.""" + parser = OptionParser(ctx) + for param in self.get_params(ctx): + param.add_to_parser(parser, ctx) + return parser + + def get_help(self, ctx): + """Formats the help into a string and returns it. This creates a + formatter and will call into the following formatting methods: + """ + formatter = ctx.make_formatter() + self.format_help(ctx, formatter) + return formatter.getvalue().rstrip('\n') + + def get_short_help_str(self, limit=45): + """Gets short help for the command or makes it by shortening the long help string.""" + return self.short_help or self.help and make_default_short_help(self.help, limit) or '' + + def format_help(self, ctx, formatter): + """Writes the help into the formatter if it exists. + + This calls into the following methods: + + - :meth:`format_usage` + - :meth:`format_help_text` + - :meth:`format_options` + - :meth:`format_epilog` + """ + self.format_usage(ctx, formatter) + self.format_help_text(ctx, formatter) + self.format_options(ctx, formatter) + self.format_epilog(ctx, formatter) + + def format_help_text(self, ctx, formatter): + """Writes the help text to the formatter if it exists.""" + if self.help: + formatter.write_paragraph() + with formatter.indentation(): + help_text = self.help + if self.deprecated: + help_text += DEPRECATED_HELP_NOTICE + formatter.write_text(help_text) + elif self.deprecated: + formatter.write_paragraph() + with formatter.indentation(): + formatter.write_text(DEPRECATED_HELP_NOTICE) + + def format_options(self, ctx, formatter): + """Writes all the options into the formatter if they exist.""" + opts = [] + for param in self.get_params(ctx): + rv = param.get_help_record(ctx) + if rv is not None: + opts.append(rv) + + if opts: + with formatter.section('Options'): + formatter.write_dl(opts) + + def format_epilog(self, ctx, formatter): + """Writes the epilog into the formatter if it exists.""" + if self.epilog: + formatter.write_paragraph() + with formatter.indentation(): + formatter.write_text(self.epilog) + + def parse_args(self, ctx, args): + parser = self.make_parser(ctx) + opts, args, param_order = parser.parse_args(args=args) + + for param in iter_params_for_processing( + param_order, self.get_params(ctx)): + value, args = param.handle_parse_result(ctx, opts, args) + + if args and not ctx.allow_extra_args and not ctx.resilient_parsing: + ctx.fail('Got unexpected extra argument%s (%s)' + % (len(args) != 1 and 's' or '', + ' '.join(map(make_str, args)))) + + ctx.args = args + return args + + def invoke(self, ctx): + """Given a context, this invokes the attached callback (if it exists) + in the right way. + """ + _maybe_show_deprecated_notice(self) + if self.callback is not None: + return ctx.invoke(self.callback, **ctx.params) + + +class MultiCommand(Command): + """A multi command is the basic implementation of a command that + dispatches to subcommands. The most common version is the + :class:`Group`. + + :param invoke_without_command: this controls how the multi command itself + is invoked. By default it's only invoked + if a subcommand is provided. + :param no_args_is_help: this controls what happens if no arguments are + provided. This option is enabled by default if + `invoke_without_command` is disabled or disabled + if it's enabled. If enabled this will add + ``--help`` as argument if no arguments are + passed. + :param subcommand_metavar: the string that is used in the documentation + to indicate the subcommand place. + :param chain: if this is set to `True` chaining of multiple subcommands + is enabled. This restricts the form of commands in that + they cannot have optional arguments but it allows + multiple commands to be chained together. + :param result_callback: the result callback to attach to this multi + command. + """ + allow_extra_args = True + allow_interspersed_args = False + + def __init__(self, name=None, invoke_without_command=False, + no_args_is_help=None, subcommand_metavar=None, + chain=False, result_callback=None, **attrs): + Command.__init__(self, name, **attrs) + if no_args_is_help is None: + no_args_is_help = not invoke_without_command + self.no_args_is_help = no_args_is_help + self.invoke_without_command = invoke_without_command + if subcommand_metavar is None: + if chain: + subcommand_metavar = SUBCOMMANDS_METAVAR + else: + subcommand_metavar = SUBCOMMAND_METAVAR + self.subcommand_metavar = subcommand_metavar + self.chain = chain + #: The result callback that is stored. This can be set or + #: overridden with the :func:`resultcallback` decorator. + self.result_callback = result_callback + + if self.chain: + for param in self.params: + if isinstance(param, Argument) and not param.required: + raise RuntimeError('Multi commands in chain mode cannot ' + 'have optional arguments.') + + def collect_usage_pieces(self, ctx): + rv = Command.collect_usage_pieces(self, ctx) + rv.append(self.subcommand_metavar) + return rv + + def format_options(self, ctx, formatter): + Command.format_options(self, ctx, formatter) + self.format_commands(ctx, formatter) + + def resultcallback(self, replace=False): + """Adds a result callback to the chain command. By default if a + result callback is already registered this will chain them but + this can be disabled with the `replace` parameter. The result + callback is invoked with the return value of the subcommand + (or the list of return values from all subcommands if chaining + is enabled) as well as the parameters as they would be passed + to the main callback. + + Example:: + + @click.group() + @click.option('-i', '--input', default=23) + def cli(input): + return 42 + + @cli.resultcallback() + def process_result(result, input): + return result + input + + .. versionadded:: 3.0 + + :param replace: if set to `True` an already existing result + callback will be removed. + """ + def decorator(f): + old_callback = self.result_callback + if old_callback is None or replace: + self.result_callback = f + return f + def function(__value, *args, **kwargs): + return f(old_callback(__value, *args, **kwargs), + *args, **kwargs) + self.result_callback = rv = update_wrapper(function, f) + return rv + return decorator + + def format_commands(self, ctx, formatter): + """Extra format methods for multi methods that adds all the commands + after the options. + """ + commands = [] + for subcommand in self.list_commands(ctx): + cmd = self.get_command(ctx, subcommand) + # What is this, the tool lied about a command. Ignore it + if cmd is None: + continue + if cmd.hidden: + continue + + commands.append((subcommand, cmd)) + + # allow for 3 times the default spacing + if len(commands): + limit = formatter.width - 6 - max(len(cmd[0]) for cmd in commands) + + rows = [] + for subcommand, cmd in commands: + help = cmd.get_short_help_str(limit) + rows.append((subcommand, help)) + + if rows: + with formatter.section('Commands'): + formatter.write_dl(rows) + + def parse_args(self, ctx, args): + if not args and self.no_args_is_help and not ctx.resilient_parsing: + echo(ctx.get_help(), color=ctx.color) + ctx.exit() + + rest = Command.parse_args(self, ctx, args) + if self.chain: + ctx.protected_args = rest + ctx.args = [] + elif rest: + ctx.protected_args, ctx.args = rest[:1], rest[1:] + + return ctx.args + + def invoke(self, ctx): + def _process_result(value): + if self.result_callback is not None: + value = ctx.invoke(self.result_callback, value, + **ctx.params) + return value + + if not ctx.protected_args: + # If we are invoked without command the chain flag controls + # how this happens. If we are not in chain mode, the return + # value here is the return value of the command. + # If however we are in chain mode, the return value is the + # return value of the result processor invoked with an empty + # list (which means that no subcommand actually was executed). + if self.invoke_without_command: + if not self.chain: + return Command.invoke(self, ctx) + with ctx: + Command.invoke(self, ctx) + return _process_result([]) + ctx.fail('Missing command.') + + # Fetch args back out + args = ctx.protected_args + ctx.args + ctx.args = [] + ctx.protected_args = [] + + # If we're not in chain mode, we only allow the invocation of a + # single command but we also inform the current context about the + # name of the command to invoke. + if not self.chain: + # Make sure the context is entered so we do not clean up + # resources until the result processor has worked. + with ctx: + cmd_name, cmd, args = self.resolve_command(ctx, args) + ctx.invoked_subcommand = cmd_name + Command.invoke(self, ctx) + sub_ctx = cmd.make_context(cmd_name, args, parent=ctx) + with sub_ctx: + return _process_result(sub_ctx.command.invoke(sub_ctx)) + + # In chain mode we create the contexts step by step, but after the + # base command has been invoked. Because at that point we do not + # know the subcommands yet, the invoked subcommand attribute is + # set to ``*`` to inform the command that subcommands are executed + # but nothing else. + with ctx: + ctx.invoked_subcommand = args and '*' or None + Command.invoke(self, ctx) + + # Otherwise we make every single context and invoke them in a + # chain. In that case the return value to the result processor + # is the list of all invoked subcommand's results. + contexts = [] + while args: + cmd_name, cmd, args = self.resolve_command(ctx, args) + sub_ctx = cmd.make_context(cmd_name, args, parent=ctx, + allow_extra_args=True, + allow_interspersed_args=False) + contexts.append(sub_ctx) + args, sub_ctx.args = sub_ctx.args, [] + + rv = [] + for sub_ctx in contexts: + with sub_ctx: + rv.append(sub_ctx.command.invoke(sub_ctx)) + return _process_result(rv) + + def resolve_command(self, ctx, args): + cmd_name = make_str(args[0]) + original_cmd_name = cmd_name + + # Get the command + cmd = self.get_command(ctx, cmd_name) + + # If we can't find the command but there is a normalization + # function available, we try with that one. + if cmd is None and ctx.token_normalize_func is not None: + cmd_name = ctx.token_normalize_func(cmd_name) + cmd = self.get_command(ctx, cmd_name) + + # If we don't find the command we want to show an error message + # to the user that it was not provided. However, there is + # something else we should do: if the first argument looks like + # an option we want to kick off parsing again for arguments to + # resolve things like --help which now should go to the main + # place. + if cmd is None and not ctx.resilient_parsing: + if split_opt(cmd_name)[0]: + self.parse_args(ctx, ctx.args) + ctx.fail('No such command "%s".' % original_cmd_name) + + return cmd_name, cmd, args[1:] + + def get_command(self, ctx, cmd_name): + """Given a context and a command name, this returns a + :class:`Command` object if it exists or returns `None`. + """ + raise NotImplementedError() + + def list_commands(self, ctx): + """Returns a list of subcommand names in the order they should + appear. + """ + return [] + + +class Group(MultiCommand): + """A group allows a command to have subcommands attached. This is the + most common way to implement nesting in Click. + + :param commands: a dictionary of commands. + """ + + def __init__(self, name=None, commands=None, **attrs): + MultiCommand.__init__(self, name, **attrs) + #: the registered subcommands by their exported names. + self.commands = commands or {} + + def add_command(self, cmd, name=None): + """Registers another :class:`Command` with this group. If the name + is not provided, the name of the command is used. + """ + name = name or cmd.name + if name is None: + raise TypeError('Command has no name.') + _check_multicommand(self, name, cmd, register=True) + self.commands[name] = cmd + + def command(self, *args, **kwargs): + """A shortcut decorator for declaring and attaching a command to + the group. This takes the same arguments as :func:`command` but + immediately registers the created command with this instance by + calling into :meth:`add_command`. + """ + def decorator(f): + cmd = command(*args, **kwargs)(f) + self.add_command(cmd) + return cmd + return decorator + + def group(self, *args, **kwargs): + """A shortcut decorator for declaring and attaching a group to + the group. This takes the same arguments as :func:`group` but + immediately registers the created command with this instance by + calling into :meth:`add_command`. + """ + def decorator(f): + cmd = group(*args, **kwargs)(f) + self.add_command(cmd) + return cmd + return decorator + + def get_command(self, ctx, cmd_name): + return self.commands.get(cmd_name) + + def list_commands(self, ctx): + return sorted(self.commands) + + +class CommandCollection(MultiCommand): + """A command collection is a multi command that merges multiple multi + commands together into one. This is a straightforward implementation + that accepts a list of different multi commands as sources and + provides all the commands for each of them. + """ + + def __init__(self, name=None, sources=None, **attrs): + MultiCommand.__init__(self, name, **attrs) + #: The list of registered multi commands. + self.sources = sources or [] + + def add_source(self, multi_cmd): + """Adds a new multi command to the chain dispatcher.""" + self.sources.append(multi_cmd) + + def get_command(self, ctx, cmd_name): + for source in self.sources: + rv = source.get_command(ctx, cmd_name) + if rv is not None: + if self.chain: + _check_multicommand(self, cmd_name, rv) + return rv + + def list_commands(self, ctx): + rv = set() + for source in self.sources: + rv.update(source.list_commands(ctx)) + return sorted(rv) + + +class Parameter(object): + r"""A parameter to a command comes in two versions: they are either + :class:`Option`\s or :class:`Argument`\s. Other subclasses are currently + not supported by design as some of the internals for parsing are + intentionally not finalized. + + Some settings are supported by both options and arguments. + + .. versionchanged:: 2.0 + Changed signature for parameter callback to also be passed the + parameter. In Click 2.0, the old callback format will still work, + but it will raise a warning to give you change to migrate the + code easier. + + :param param_decls: the parameter declarations for this option or + argument. This is a list of flags or argument + names. + :param type: the type that should be used. Either a :class:`ParamType` + or a Python type. The later is converted into the former + automatically if supported. + :param required: controls if this is optional or not. + :param default: the default value if omitted. This can also be a callable, + in which case it's invoked when the default is needed + without any arguments. + :param callback: a callback that should be executed after the parameter + was matched. This is called as ``fn(ctx, param, + value)`` and needs to return the value. Before Click + 2.0, the signature was ``(ctx, value)``. + :param nargs: the number of arguments to match. If not ``1`` the return + value is a tuple instead of single value. The default for + nargs is ``1`` (except if the type is a tuple, then it's + the arity of the tuple). + :param metavar: how the value is represented in the help page. + :param expose_value: if this is `True` then the value is passed onwards + to the command callback and stored on the context, + otherwise it's skipped. + :param is_eager: eager values are processed before non eager ones. This + should not be set for arguments or it will inverse the + order of processing. + :param envvar: a string or list of strings that are environment variables + that should be checked. + """ + param_type_name = 'parameter' + + def __init__(self, param_decls=None, type=None, required=False, + default=None, callback=None, nargs=None, metavar=None, + expose_value=True, is_eager=False, envvar=None, + autocompletion=None): + self.name, self.opts, self.secondary_opts = \ + self._parse_decls(param_decls or (), expose_value) + + self.type = convert_type(type, default) + + # Default nargs to what the type tells us if we have that + # information available. + if nargs is None: + if self.type.is_composite: + nargs = self.type.arity + else: + nargs = 1 + + self.required = required + self.callback = callback + self.nargs = nargs + self.multiple = False + self.expose_value = expose_value + self.default = default + self.is_eager = is_eager + self.metavar = metavar + self.envvar = envvar + self.autocompletion = autocompletion + + @property + def human_readable_name(self): + """Returns the human readable name of this parameter. This is the + same as the name for options, but the metavar for arguments. + """ + return self.name + + def make_metavar(self): + if self.metavar is not None: + return self.metavar + metavar = self.type.get_metavar(self) + if metavar is None: + metavar = self.type.name.upper() + if self.nargs != 1: + metavar += '...' + return metavar + + def get_default(self, ctx): + """Given a context variable this calculates the default value.""" + # Otherwise go with the regular default. + if callable(self.default): + rv = self.default() + else: + rv = self.default + return self.type_cast_value(ctx, rv) + + def add_to_parser(self, parser, ctx): + pass + + def consume_value(self, ctx, opts): + value = opts.get(self.name) + if value is None: + value = self.value_from_envvar(ctx) + if value is None: + value = ctx.lookup_default(self.name) + return value + + def type_cast_value(self, ctx, value): + """Given a value this runs it properly through the type system. + This automatically handles things like `nargs` and `multiple` as + well as composite types. + """ + if self.type.is_composite: + if self.nargs <= 1: + raise TypeError('Attempted to invoke composite type ' + 'but nargs has been set to %s. This is ' + 'not supported; nargs needs to be set to ' + 'a fixed value > 1.' % self.nargs) + if self.multiple: + return tuple(self.type(x or (), self, ctx) for x in value or ()) + return self.type(value or (), self, ctx) + + def _convert(value, level): + if level == 0: + return self.type(value, self, ctx) + return tuple(_convert(x, level - 1) for x in value or ()) + return _convert(value, (self.nargs != 1) + bool(self.multiple)) + + def process_value(self, ctx, value): + """Given a value and context this runs the logic to convert the + value as necessary. + """ + # If the value we were given is None we do nothing. This way + # code that calls this can easily figure out if something was + # not provided. Otherwise it would be converted into an empty + # tuple for multiple invocations which is inconvenient. + if value is not None: + return self.type_cast_value(ctx, value) + + def value_is_missing(self, value): + if value is None: + return True + if (self.nargs != 1 or self.multiple) and value == (): + return True + return False + + def full_process_value(self, ctx, value): + value = self.process_value(ctx, value) + + if value is None and not ctx.resilient_parsing: + value = self.get_default(ctx) + + if self.required and self.value_is_missing(value): + raise MissingParameter(ctx=ctx, param=self) + + return value + + def resolve_envvar_value(self, ctx): + if self.envvar is None: + return + if isinstance(self.envvar, (tuple, list)): + for envvar in self.envvar: + rv = os.environ.get(envvar) + if rv is not None: + return rv + else: + return os.environ.get(self.envvar) + + def value_from_envvar(self, ctx): + rv = self.resolve_envvar_value(ctx) + if rv is not None and self.nargs != 1: + rv = self.type.split_envvar_value(rv) + return rv + + def handle_parse_result(self, ctx, opts, args): + with augment_usage_errors(ctx, param=self): + value = self.consume_value(ctx, opts) + try: + value = self.full_process_value(ctx, value) + except Exception: + if not ctx.resilient_parsing: + raise + value = None + if self.callback is not None: + try: + value = invoke_param_callback( + self.callback, ctx, self, value) + except Exception: + if not ctx.resilient_parsing: + raise + + if self.expose_value: + ctx.params[self.name] = value + return value, args + + def get_help_record(self, ctx): + pass + + def get_usage_pieces(self, ctx): + return [] + + def get_error_hint(self, ctx): + """Get a stringified version of the param for use in error messages to + indicate which param caused the error. + """ + hint_list = self.opts or [self.human_readable_name] + return ' / '.join('"%s"' % x for x in hint_list) + + +class Option(Parameter): + """Options are usually optional values on the command line and + have some extra features that arguments don't have. + + All other parameters are passed onwards to the parameter constructor. + + :param show_default: controls if the default value should be shown on the + help page. Normally, defaults are not shown. If this + value is a string, it shows the string instead of the + value. This is particularly useful for dynamic options. + :param show_envvar: controls if an environment variable should be shown on + the help page. Normally, environment variables + are not shown. + :param prompt: if set to `True` or a non empty string then the user will be + prompted for input. If set to `True` the prompt will be the + option name capitalized. + :param confirmation_prompt: if set then the value will need to be confirmed + if it was prompted for. + :param hide_input: if this is `True` then the input on the prompt will be + hidden from the user. This is useful for password + input. + :param is_flag: forces this option to act as a flag. The default is + auto detection. + :param flag_value: which value should be used for this flag if it's + enabled. This is set to a boolean automatically if + the option string contains a slash to mark two options. + :param multiple: if this is set to `True` then the argument is accepted + multiple times and recorded. This is similar to ``nargs`` + in how it works but supports arbitrary number of + arguments. + :param count: this flag makes an option increment an integer. + :param allow_from_autoenv: if this is enabled then the value of this + parameter will be pulled from an environment + variable in case a prefix is defined on the + context. + :param help: the help string. + :param hidden: hide this option from help outputs. + """ + param_type_name = 'option' + + def __init__(self, param_decls=None, show_default=False, + prompt=False, confirmation_prompt=False, + hide_input=False, is_flag=None, flag_value=None, + multiple=False, count=False, allow_from_autoenv=True, + type=None, help=None, hidden=False, show_choices=True, + show_envvar=False, **attrs): + default_is_missing = attrs.get('default', _missing) is _missing + Parameter.__init__(self, param_decls, type=type, **attrs) + + if prompt is True: + prompt_text = self.name.replace('_', ' ').capitalize() + elif prompt is False: + prompt_text = None + else: + prompt_text = prompt + self.prompt = prompt_text + self.confirmation_prompt = confirmation_prompt + self.hide_input = hide_input + self.hidden = hidden + + # Flags + if is_flag is None: + if flag_value is not None: + is_flag = True + else: + is_flag = bool(self.secondary_opts) + if is_flag and default_is_missing: + self.default = False + if flag_value is None: + flag_value = not self.default + self.is_flag = is_flag + self.flag_value = flag_value + if self.is_flag and isinstance(self.flag_value, bool) \ + and type is None: + self.type = BOOL + self.is_bool_flag = True + else: + self.is_bool_flag = False + + # Counting + self.count = count + if count: + if type is None: + self.type = IntRange(min=0) + if default_is_missing: + self.default = 0 + + self.multiple = multiple + self.allow_from_autoenv = allow_from_autoenv + self.help = help + self.show_default = show_default + self.show_choices = show_choices + self.show_envvar = show_envvar + + # Sanity check for stuff we don't support + if __debug__: + if self.nargs < 0: + raise TypeError('Options cannot have nargs < 0') + if self.prompt and self.is_flag and not self.is_bool_flag: + raise TypeError('Cannot prompt for flags that are not bools.') + if not self.is_bool_flag and self.secondary_opts: + raise TypeError('Got secondary option for non boolean flag.') + if self.is_bool_flag and self.hide_input \ + and self.prompt is not None: + raise TypeError('Hidden input does not work with boolean ' + 'flag prompts.') + if self.count: + if self.multiple: + raise TypeError('Options cannot be multiple and count ' + 'at the same time.') + elif self.is_flag: + raise TypeError('Options cannot be count and flags at ' + 'the same time.') + + def _parse_decls(self, decls, expose_value): + opts = [] + secondary_opts = [] + name = None + possible_names = [] + + for decl in decls: + if isidentifier(decl): + if name is not None: + raise TypeError('Name defined twice') + name = decl + else: + split_char = decl[:1] == '/' and ';' or '/' + if split_char in decl: + first, second = decl.split(split_char, 1) + first = first.rstrip() + if first: + possible_names.append(split_opt(first)) + opts.append(first) + second = second.lstrip() + if second: + secondary_opts.append(second.lstrip()) + else: + possible_names.append(split_opt(decl)) + opts.append(decl) + + if name is None and possible_names: + possible_names.sort(key=lambda x: -len(x[0])) # group long options first + name = possible_names[0][1].replace('-', '_').lower() + if not isidentifier(name): + name = None + + if name is None: + if not expose_value: + return None, opts, secondary_opts + raise TypeError('Could not determine name for option') + + if not opts and not secondary_opts: + raise TypeError('No options defined but a name was passed (%s). ' + 'Did you mean to declare an argument instead ' + 'of an option?' % name) + + return name, opts, secondary_opts + + def add_to_parser(self, parser, ctx): + kwargs = { + 'dest': self.name, + 'nargs': self.nargs, + 'obj': self, + } + + if self.multiple: + action = 'append' + elif self.count: + action = 'count' + else: + action = 'store' + + if self.is_flag: + kwargs.pop('nargs', None) + if self.is_bool_flag and self.secondary_opts: + parser.add_option(self.opts, action=action + '_const', + const=True, **kwargs) + parser.add_option(self.secondary_opts, action=action + + '_const', const=False, **kwargs) + else: + parser.add_option(self.opts, action=action + '_const', + const=self.flag_value, + **kwargs) + else: + kwargs['action'] = action + parser.add_option(self.opts, **kwargs) + + def get_help_record(self, ctx): + if self.hidden: + return + any_prefix_is_slash = [] + + def _write_opts(opts): + rv, any_slashes = join_options(opts) + if any_slashes: + any_prefix_is_slash[:] = [True] + if not self.is_flag and not self.count: + rv += ' ' + self.make_metavar() + return rv + + rv = [_write_opts(self.opts)] + if self.secondary_opts: + rv.append(_write_opts(self.secondary_opts)) + + help = self.help or '' + extra = [] + if self.show_envvar: + envvar = self.envvar + if envvar is None: + if self.allow_from_autoenv and \ + ctx.auto_envvar_prefix is not None: + envvar = '%s_%s' % (ctx.auto_envvar_prefix, self.name.upper()) + if envvar is not None: + extra.append('env var: %s' % ( + ', '.join('%s' % d for d in envvar) + if isinstance(envvar, (list, tuple)) + else envvar, )) + if self.default is not None and self.show_default: + if isinstance(self.show_default, string_types): + default_string = '({})'.format(self.show_default) + elif isinstance(self.default, (list, tuple)): + default_string = ', '.join('%s' % d for d in self.default) + elif inspect.isfunction(self.default): + default_string = "(dynamic)" + else: + default_string = self.default + extra.append('default: {}'.format(default_string)) + + if self.required: + extra.append('required') + if extra: + help = '%s[%s]' % (help and help + ' ' or '', '; '.join(extra)) + + return ((any_prefix_is_slash and '; ' or ' / ').join(rv), help) + + def get_default(self, ctx): + # If we're a non boolean flag out default is more complex because + # we need to look at all flags in the same group to figure out + # if we're the the default one in which case we return the flag + # value as default. + if self.is_flag and not self.is_bool_flag: + for param in ctx.command.params: + if param.name == self.name and param.default: + return param.flag_value + return None + return Parameter.get_default(self, ctx) + + def prompt_for_value(self, ctx): + """This is an alternative flow that can be activated in the full + value processing if a value does not exist. It will prompt the + user until a valid value exists and then returns the processed + value as result. + """ + # Calculate the default before prompting anything to be stable. + default = self.get_default(ctx) + + # If this is a prompt for a flag we need to handle this + # differently. + if self.is_bool_flag: + return confirm(self.prompt, default) + + return prompt(self.prompt, default=default, type=self.type, + hide_input=self.hide_input, show_choices=self.show_choices, + confirmation_prompt=self.confirmation_prompt, + value_proc=lambda x: self.process_value(ctx, x)) + + def resolve_envvar_value(self, ctx): + rv = Parameter.resolve_envvar_value(self, ctx) + if rv is not None: + return rv + if self.allow_from_autoenv and \ + ctx.auto_envvar_prefix is not None: + envvar = '%s_%s' % (ctx.auto_envvar_prefix, self.name.upper()) + return os.environ.get(envvar) + + def value_from_envvar(self, ctx): + rv = self.resolve_envvar_value(ctx) + if rv is None: + return None + value_depth = (self.nargs != 1) + bool(self.multiple) + if value_depth > 0 and rv is not None: + rv = self.type.split_envvar_value(rv) + if self.multiple and self.nargs != 1: + rv = batch(rv, self.nargs) + return rv + + def full_process_value(self, ctx, value): + if value is None and self.prompt is not None \ + and not ctx.resilient_parsing: + return self.prompt_for_value(ctx) + return Parameter.full_process_value(self, ctx, value) + + +class Argument(Parameter): + """Arguments are positional parameters to a command. They generally + provide fewer features than options but can have infinite ``nargs`` + and are required by default. + + All parameters are passed onwards to the parameter constructor. + """ + param_type_name = 'argument' + + def __init__(self, param_decls, required=None, **attrs): + if required is None: + if attrs.get('default') is not None: + required = False + else: + required = attrs.get('nargs', 1) > 0 + Parameter.__init__(self, param_decls, required=required, **attrs) + if self.default is not None and self.nargs < 0: + raise TypeError('nargs=-1 in combination with a default value ' + 'is not supported.') + + @property + def human_readable_name(self): + if self.metavar is not None: + return self.metavar + return self.name.upper() + + def make_metavar(self): + if self.metavar is not None: + return self.metavar + var = self.type.get_metavar(self) + if not var: + var = self.name.upper() + if not self.required: + var = '[%s]' % var + if self.nargs != 1: + var += '...' + return var + + def _parse_decls(self, decls, expose_value): + if not decls: + if not expose_value: + return None, [], [] + raise TypeError('Could not determine name for argument') + if len(decls) == 1: + name = arg = decls[0] + name = name.replace('-', '_').lower() + else: + raise TypeError('Arguments take exactly one ' + 'parameter declaration, got %d' % len(decls)) + return name, [arg], [] + + def get_usage_pieces(self, ctx): + return [self.make_metavar()] + + def get_error_hint(self, ctx): + return '"%s"' % self.make_metavar() + + def add_to_parser(self, parser, ctx): + parser.add_argument(dest=self.name, nargs=self.nargs, + obj=self) + + +# Circular dependency between decorators and core +from .decorators import command, group diff --git a/flask/venv/lib/python3.6/site-packages/click/decorators.py b/flask/venv/lib/python3.6/site-packages/click/decorators.py new file mode 100644 index 0000000..c57c530 --- /dev/null +++ b/flask/venv/lib/python3.6/site-packages/click/decorators.py @@ -0,0 +1,311 @@ +import sys +import inspect + +from functools import update_wrapper + +from ._compat import iteritems +from ._unicodefun import _check_for_unicode_literals +from .utils import echo +from .globals import get_current_context + + +def pass_context(f): + """Marks a callback as wanting to receive the current context + object as first argument. + """ + def new_func(*args, **kwargs): + return f(get_current_context(), *args, **kwargs) + return update_wrapper(new_func, f) + + +def pass_obj(f): + """Similar to :func:`pass_context`, but only pass the object on the + context onwards (:attr:`Context.obj`). This is useful if that object + represents the state of a nested system. + """ + def new_func(*args, **kwargs): + return f(get_current_context().obj, *args, **kwargs) + return update_wrapper(new_func, f) + + +def make_pass_decorator(object_type, ensure=False): + """Given an object type this creates a decorator that will work + similar to :func:`pass_obj` but instead of passing the object of the + current context, it will find the innermost context of type + :func:`object_type`. + + This generates a decorator that works roughly like this:: + + from functools import update_wrapper + + def decorator(f): + @pass_context + def new_func(ctx, *args, **kwargs): + obj = ctx.find_object(object_type) + return ctx.invoke(f, obj, *args, **kwargs) + return update_wrapper(new_func, f) + return decorator + + :param object_type: the type of the object to pass. + :param ensure: if set to `True`, a new object will be created and + remembered on the context if it's not there yet. + """ + def decorator(f): + def new_func(*args, **kwargs): + ctx = get_current_context() + if ensure: + obj = ctx.ensure_object(object_type) + else: + obj = ctx.find_object(object_type) + if obj is None: + raise RuntimeError('Managed to invoke callback without a ' + 'context object of type %r existing' + % object_type.__name__) + return ctx.invoke(f, obj, *args, **kwargs) + return update_wrapper(new_func, f) + return decorator + + +def _make_command(f, name, attrs, cls): + if isinstance(f, Command): + raise TypeError('Attempted to convert a callback into a ' + 'command twice.') + try: + params = f.__click_params__ + params.reverse() + del f.__click_params__ + except AttributeError: + params = [] + help = attrs.get('help') + if help is None: + help = inspect.getdoc(f) + if isinstance(help, bytes): + help = help.decode('utf-8') + else: + help = inspect.cleandoc(help) + attrs['help'] = help + _check_for_unicode_literals() + return cls(name=name or f.__name__.lower().replace('_', '-'), + callback=f, params=params, **attrs) + + +def command(name=None, cls=None, **attrs): + r"""Creates a new :class:`Command` and uses the decorated function as + callback. This will also automatically attach all decorated + :func:`option`\s and :func:`argument`\s as parameters to the command. + + The name of the command defaults to the name of the function. If you + want to change that, you can pass the intended name as the first + argument. + + All keyword arguments are forwarded to the underlying command class. + + Once decorated the function turns into a :class:`Command` instance + that can be invoked as a command line utility or be attached to a + command :class:`Group`. + + :param name: the name of the command. This defaults to the function + name with underscores replaced by dashes. + :param cls: the command class to instantiate. This defaults to + :class:`Command`. + """ + if cls is None: + cls = Command + def decorator(f): + cmd = _make_command(f, name, attrs, cls) + cmd.__doc__ = f.__doc__ + return cmd + return decorator + + +def group(name=None, **attrs): + """Creates a new :class:`Group` with a function as callback. This + works otherwise the same as :func:`command` just that the `cls` + parameter is set to :class:`Group`. + """ + attrs.setdefault('cls', Group) + return command(name, **attrs) + + +def _param_memo(f, param): + if isinstance(f, Command): + f.params.append(param) + else: + if not hasattr(f, '__click_params__'): + f.__click_params__ = [] + f.__click_params__.append(param) + + +def argument(*param_decls, **attrs): + """Attaches an argument to the command. All positional arguments are + passed as parameter declarations to :class:`Argument`; all keyword + arguments are forwarded unchanged (except ``cls``). + This is equivalent to creating an :class:`Argument` instance manually + and attaching it to the :attr:`Command.params` list. + + :param cls: the argument class to instantiate. This defaults to + :class:`Argument`. + """ + def decorator(f): + ArgumentClass = attrs.pop('cls', Argument) + _param_memo(f, ArgumentClass(param_decls, **attrs)) + return f + return decorator + + +def option(*param_decls, **attrs): + """Attaches an option to the command. All positional arguments are + passed as parameter declarations to :class:`Option`; all keyword + arguments are forwarded unchanged (except ``cls``). + This is equivalent to creating an :class:`Option` instance manually + and attaching it to the :attr:`Command.params` list. + + :param cls: the option class to instantiate. This defaults to + :class:`Option`. + """ + def decorator(f): + # Issue 926, copy attrs, so pre-defined options can re-use the same cls= + option_attrs = attrs.copy() + + if 'help' in option_attrs: + option_attrs['help'] = inspect.cleandoc(option_attrs['help']) + OptionClass = option_attrs.pop('cls', Option) + _param_memo(f, OptionClass(param_decls, **option_attrs)) + return f + return decorator + + +def confirmation_option(*param_decls, **attrs): + """Shortcut for confirmation prompts that can be ignored by passing + ``--yes`` as parameter. + + This is equivalent to decorating a function with :func:`option` with + the following parameters:: + + def callback(ctx, param, value): + if not value: + ctx.abort() + + @click.command() + @click.option('--yes', is_flag=True, callback=callback, + expose_value=False, prompt='Do you want to continue?') + def dropdb(): + pass + """ + def decorator(f): + def callback(ctx, param, value): + if not value: + ctx.abort() + attrs.setdefault('is_flag', True) + attrs.setdefault('callback', callback) + attrs.setdefault('expose_value', False) + attrs.setdefault('prompt', 'Do you want to continue?') + attrs.setdefault('help', 'Confirm the action without prompting.') + return option(*(param_decls or ('--yes',)), **attrs)(f) + return decorator + + +def password_option(*param_decls, **attrs): + """Shortcut for password prompts. + + This is equivalent to decorating a function with :func:`option` with + the following parameters:: + + @click.command() + @click.option('--password', prompt=True, confirmation_prompt=True, + hide_input=True) + def changeadmin(password): + pass + """ + def decorator(f): + attrs.setdefault('prompt', True) + attrs.setdefault('confirmation_prompt', True) + attrs.setdefault('hide_input', True) + return option(*(param_decls or ('--password',)), **attrs)(f) + return decorator + + +def version_option(version=None, *param_decls, **attrs): + """Adds a ``--version`` option which immediately ends the program + printing out the version number. This is implemented as an eager + option that prints the version and exits the program in the callback. + + :param version: the version number to show. If not provided Click + attempts an auto discovery via setuptools. + :param prog_name: the name of the program (defaults to autodetection) + :param message: custom message to show instead of the default + (``'%(prog)s, version %(version)s'``) + :param others: everything else is forwarded to :func:`option`. + """ + if version is None: + if hasattr(sys, '_getframe'): + module = sys._getframe(1).f_globals.get('__name__') + else: + module = '' + + def decorator(f): + prog_name = attrs.pop('prog_name', None) + message = attrs.pop('message', '%(prog)s, version %(version)s') + + def callback(ctx, param, value): + if not value or ctx.resilient_parsing: + return + prog = prog_name + if prog is None: + prog = ctx.find_root().info_name + ver = version + if ver is None: + try: + import pkg_resources + except ImportError: + pass + else: + for dist in pkg_resources.working_set: + scripts = dist.get_entry_map().get('console_scripts') or {} + for script_name, entry_point in iteritems(scripts): + if entry_point.module_name == module: + ver = dist.version + break + if ver is None: + raise RuntimeError('Could not determine version') + echo(message % { + 'prog': prog, + 'version': ver, + }, color=ctx.color) + ctx.exit() + + attrs.setdefault('is_flag', True) + attrs.setdefault('expose_value', False) + attrs.setdefault('is_eager', True) + attrs.setdefault('help', 'Show the version and exit.') + attrs['callback'] = callback + return option(*(param_decls or ('--version',)), **attrs)(f) + return decorator + + +def help_option(*param_decls, **attrs): + """Adds a ``--help`` option which immediately ends the program + printing out the help page. This is usually unnecessary to add as + this is added by default to all commands unless suppressed. + + Like :func:`version_option`, this is implemented as eager option that + prints in the callback and exits. + + All arguments are forwarded to :func:`option`. + """ + def decorator(f): + def callback(ctx, param, value): + if value and not ctx.resilient_parsing: + echo(ctx.get_help(), color=ctx.color) + ctx.exit() + attrs.setdefault('is_flag', True) + attrs.setdefault('expose_value', False) + attrs.setdefault('help', 'Show this message and exit.') + attrs.setdefault('is_eager', True) + attrs['callback'] = callback + return option(*(param_decls or ('--help',)), **attrs)(f) + return decorator + + +# Circular dependencies between core and decorators +from .core import Command, Group, Argument, Option diff --git a/flask/venv/lib/python3.6/site-packages/click/exceptions.py b/flask/venv/lib/python3.6/site-packages/click/exceptions.py new file mode 100644 index 0000000..6fa1765 --- /dev/null +++ b/flask/venv/lib/python3.6/site-packages/click/exceptions.py @@ -0,0 +1,235 @@ +from ._compat import PY2, filename_to_ui, get_text_stderr +from .utils import echo + + +def _join_param_hints(param_hint): + if isinstance(param_hint, (tuple, list)): + return ' / '.join('"%s"' % x for x in param_hint) + return param_hint + + +class ClickException(Exception): + """An exception that Click can handle and show to the user.""" + + #: The exit code for this exception + exit_code = 1 + + def __init__(self, message): + ctor_msg = message + if PY2: + if ctor_msg is not None: + ctor_msg = ctor_msg.encode('utf-8') + Exception.__init__(self, ctor_msg) + self.message = message + + def format_message(self): + return self.message + + def __str__(self): + return self.message + + if PY2: + __unicode__ = __str__ + + def __str__(self): + return self.message.encode('utf-8') + + def show(self, file=None): + if file is None: + file = get_text_stderr() + echo('Error: %s' % self.format_message(), file=file) + + +class UsageError(ClickException): + """An internal exception that signals a usage error. This typically + aborts any further handling. + + :param message: the error message to display. + :param ctx: optionally the context that caused this error. Click will + fill in the context automatically in some situations. + """ + exit_code = 2 + + def __init__(self, message, ctx=None): + ClickException.__init__(self, message) + self.ctx = ctx + self.cmd = self.ctx and self.ctx.command or None + + def show(self, file=None): + if file is None: + file = get_text_stderr() + color = None + hint = '' + if (self.cmd is not None and + self.cmd.get_help_option(self.ctx) is not None): + hint = ('Try "%s %s" for help.\n' + % (self.ctx.command_path, self.ctx.help_option_names[0])) + if self.ctx is not None: + color = self.ctx.color + echo(self.ctx.get_usage() + '\n%s' % hint, file=file, color=color) + echo('Error: %s' % self.format_message(), file=file, color=color) + + +class BadParameter(UsageError): + """An exception that formats out a standardized error message for a + bad parameter. This is useful when thrown from a callback or type as + Click will attach contextual information to it (for instance, which + parameter it is). + + .. versionadded:: 2.0 + + :param param: the parameter object that caused this error. This can + be left out, and Click will attach this info itself + if possible. + :param param_hint: a string that shows up as parameter name. This + can be used as alternative to `param` in cases + where custom validation should happen. If it is + a string it's used as such, if it's a list then + each item is quoted and separated. + """ + + def __init__(self, message, ctx=None, param=None, + param_hint=None): + UsageError.__init__(self, message, ctx) + self.param = param + self.param_hint = param_hint + + def format_message(self): + if self.param_hint is not None: + param_hint = self.param_hint + elif self.param is not None: + param_hint = self.param.get_error_hint(self.ctx) + else: + return 'Invalid value: %s' % self.message + param_hint = _join_param_hints(param_hint) + + return 'Invalid value for %s: %s' % (param_hint, self.message) + + +class MissingParameter(BadParameter): + """Raised if click required an option or argument but it was not + provided when invoking the script. + + .. versionadded:: 4.0 + + :param param_type: a string that indicates the type of the parameter. + The default is to inherit the parameter type from + the given `param`. Valid values are ``'parameter'``, + ``'option'`` or ``'argument'``. + """ + + def __init__(self, message=None, ctx=None, param=None, + param_hint=None, param_type=None): + BadParameter.__init__(self, message, ctx, param, param_hint) + self.param_type = param_type + + def format_message(self): + if self.param_hint is not None: + param_hint = self.param_hint + elif self.param is not None: + param_hint = self.param.get_error_hint(self.ctx) + else: + param_hint = None + param_hint = _join_param_hints(param_hint) + + param_type = self.param_type + if param_type is None and self.param is not None: + param_type = self.param.param_type_name + + msg = self.message + if self.param is not None: + msg_extra = self.param.type.get_missing_message(self.param) + if msg_extra: + if msg: + msg += '. ' + msg_extra + else: + msg = msg_extra + + return 'Missing %s%s%s%s' % ( + param_type, + param_hint and ' %s' % param_hint or '', + msg and '. ' or '.', + msg or '', + ) + + +class NoSuchOption(UsageError): + """Raised if click attempted to handle an option that does not + exist. + + .. versionadded:: 4.0 + """ + + def __init__(self, option_name, message=None, possibilities=None, + ctx=None): + if message is None: + message = 'no such option: %s' % option_name + UsageError.__init__(self, message, ctx) + self.option_name = option_name + self.possibilities = possibilities + + def format_message(self): + bits = [self.message] + if self.possibilities: + if len(self.possibilities) == 1: + bits.append('Did you mean %s?' % self.possibilities[0]) + else: + possibilities = sorted(self.possibilities) + bits.append('(Possible options: %s)' % ', '.join(possibilities)) + return ' '.join(bits) + + +class BadOptionUsage(UsageError): + """Raised if an option is generally supplied but the use of the option + was incorrect. This is for instance raised if the number of arguments + for an option is not correct. + + .. versionadded:: 4.0 + + :param option_name: the name of the option being used incorrectly. + """ + + def __init__(self, option_name, message, ctx=None): + UsageError.__init__(self, message, ctx) + self.option_name = option_name + + +class BadArgumentUsage(UsageError): + """Raised if an argument is generally supplied but the use of the argument + was incorrect. This is for instance raised if the number of values + for an argument is not correct. + + .. versionadded:: 6.0 + """ + + def __init__(self, message, ctx=None): + UsageError.__init__(self, message, ctx) + + +class FileError(ClickException): + """Raised if a file cannot be opened.""" + + def __init__(self, filename, hint=None): + ui_filename = filename_to_ui(filename) + if hint is None: + hint = 'unknown error' + ClickException.__init__(self, hint) + self.ui_filename = ui_filename + self.filename = filename + + def format_message(self): + return 'Could not open file %s: %s' % (self.ui_filename, self.message) + + +class Abort(RuntimeError): + """An internal signalling exception that signals Click to abort.""" + + +class Exit(RuntimeError): + """An exception that indicates that the application should exit with some + status code. + + :param code: the status code to exit with. + """ + def __init__(self, code=0): + self.exit_code = code diff --git a/flask/venv/lib/python3.6/site-packages/click/formatting.py b/flask/venv/lib/python3.6/site-packages/click/formatting.py new file mode 100644 index 0000000..a3d6a4d --- /dev/null +++ b/flask/venv/lib/python3.6/site-packages/click/formatting.py @@ -0,0 +1,256 @@ +from contextlib import contextmanager +from .termui import get_terminal_size +from .parser import split_opt +from ._compat import term_len + + +# Can force a width. This is used by the test system +FORCED_WIDTH = None + + +def measure_table(rows): + widths = {} + for row in rows: + for idx, col in enumerate(row): + widths[idx] = max(widths.get(idx, 0), term_len(col)) + return tuple(y for x, y in sorted(widths.items())) + + +def iter_rows(rows, col_count): + for row in rows: + row = tuple(row) + yield row + ('',) * (col_count - len(row)) + + +def wrap_text(text, width=78, initial_indent='', subsequent_indent='', + preserve_paragraphs=False): + """A helper function that intelligently wraps text. By default, it + assumes that it operates on a single paragraph of text but if the + `preserve_paragraphs` parameter is provided it will intelligently + handle paragraphs (defined by two empty lines). + + If paragraphs are handled, a paragraph can be prefixed with an empty + line containing the ``\\b`` character (``\\x08``) to indicate that + no rewrapping should happen in that block. + + :param text: the text that should be rewrapped. + :param width: the maximum width for the text. + :param initial_indent: the initial indent that should be placed on the + first line as a string. + :param subsequent_indent: the indent string that should be placed on + each consecutive line. + :param preserve_paragraphs: if this flag is set then the wrapping will + intelligently handle paragraphs. + """ + from ._textwrap import TextWrapper + text = text.expandtabs() + wrapper = TextWrapper(width, initial_indent=initial_indent, + subsequent_indent=subsequent_indent, + replace_whitespace=False) + if not preserve_paragraphs: + return wrapper.fill(text) + + p = [] + buf = [] + indent = None + + def _flush_par(): + if not buf: + return + if buf[0].strip() == '\b': + p.append((indent or 0, True, '\n'.join(buf[1:]))) + else: + p.append((indent or 0, False, ' '.join(buf))) + del buf[:] + + for line in text.splitlines(): + if not line: + _flush_par() + indent = None + else: + if indent is None: + orig_len = term_len(line) + line = line.lstrip() + indent = orig_len - term_len(line) + buf.append(line) + _flush_par() + + rv = [] + for indent, raw, text in p: + with wrapper.extra_indent(' ' * indent): + if raw: + rv.append(wrapper.indent_only(text)) + else: + rv.append(wrapper.fill(text)) + + return '\n\n'.join(rv) + + +class HelpFormatter(object): + """This class helps with formatting text-based help pages. It's + usually just needed for very special internal cases, but it's also + exposed so that developers can write their own fancy outputs. + + At present, it always writes into memory. + + :param indent_increment: the additional increment for each level. + :param width: the width for the text. This defaults to the terminal + width clamped to a maximum of 78. + """ + + def __init__(self, indent_increment=2, width=None, max_width=None): + self.indent_increment = indent_increment + if max_width is None: + max_width = 80 + if width is None: + width = FORCED_WIDTH + if width is None: + width = max(min(get_terminal_size()[0], max_width) - 2, 50) + self.width = width + self.current_indent = 0 + self.buffer = [] + + def write(self, string): + """Writes a unicode string into the internal buffer.""" + self.buffer.append(string) + + def indent(self): + """Increases the indentation.""" + self.current_indent += self.indent_increment + + def dedent(self): + """Decreases the indentation.""" + self.current_indent -= self.indent_increment + + def write_usage(self, prog, args='', prefix='Usage: '): + """Writes a usage line into the buffer. + + :param prog: the program name. + :param args: whitespace separated list of arguments. + :param prefix: the prefix for the first line. + """ + usage_prefix = '%*s%s ' % (self.current_indent, prefix, prog) + text_width = self.width - self.current_indent + + if text_width >= (term_len(usage_prefix) + 20): + # The arguments will fit to the right of the prefix. + indent = ' ' * term_len(usage_prefix) + self.write(wrap_text(args, text_width, + initial_indent=usage_prefix, + subsequent_indent=indent)) + else: + # The prefix is too long, put the arguments on the next line. + self.write(usage_prefix) + self.write('\n') + indent = ' ' * (max(self.current_indent, term_len(prefix)) + 4) + self.write(wrap_text(args, text_width, + initial_indent=indent, + subsequent_indent=indent)) + + self.write('\n') + + def write_heading(self, heading): + """Writes a heading into the buffer.""" + self.write('%*s%s:\n' % (self.current_indent, '', heading)) + + def write_paragraph(self): + """Writes a paragraph into the buffer.""" + if self.buffer: + self.write('\n') + + def write_text(self, text): + """Writes re-indented text into the buffer. This rewraps and + preserves paragraphs. + """ + text_width = max(self.width - self.current_indent, 11) + indent = ' ' * self.current_indent + self.write(wrap_text(text, text_width, + initial_indent=indent, + subsequent_indent=indent, + preserve_paragraphs=True)) + self.write('\n') + + def write_dl(self, rows, col_max=30, col_spacing=2): + """Writes a definition list into the buffer. This is how options + and commands are usually formatted. + + :param rows: a list of two item tuples for the terms and values. + :param col_max: the maximum width of the first column. + :param col_spacing: the number of spaces between the first and + second column. + """ + rows = list(rows) + widths = measure_table(rows) + if len(widths) != 2: + raise TypeError('Expected two columns for definition list') + + first_col = min(widths[0], col_max) + col_spacing + + for first, second in iter_rows(rows, len(widths)): + self.write('%*s%s' % (self.current_indent, '', first)) + if not second: + self.write('\n') + continue + if term_len(first) <= first_col - col_spacing: + self.write(' ' * (first_col - term_len(first))) + else: + self.write('\n') + self.write(' ' * (first_col + self.current_indent)) + + text_width = max(self.width - first_col - 2, 10) + lines = iter(wrap_text(second, text_width).splitlines()) + if lines: + self.write(next(lines) + '\n') + for line in lines: + self.write('%*s%s\n' % ( + first_col + self.current_indent, '', line)) + else: + self.write('\n') + + @contextmanager + def section(self, name): + """Helpful context manager that writes a paragraph, a heading, + and the indents. + + :param name: the section name that is written as heading. + """ + self.write_paragraph() + self.write_heading(name) + self.indent() + try: + yield + finally: + self.dedent() + + @contextmanager + def indentation(self): + """A context manager that increases the indentation.""" + self.indent() + try: + yield + finally: + self.dedent() + + def getvalue(self): + """Returns the buffer contents.""" + return ''.join(self.buffer) + + +def join_options(options): + """Given a list of option strings this joins them in the most appropriate + way and returns them in the form ``(formatted_string, + any_prefix_is_slash)`` where the second item in the tuple is a flag that + indicates if any of the option prefixes was a slash. + """ + rv = [] + any_prefix_is_slash = False + for opt in options: + prefix = split_opt(opt)[0] + if prefix == '/': + any_prefix_is_slash = True + rv.append((len(prefix), opt)) + + rv.sort(key=lambda x: x[0]) + + rv = ', '.join(x[1] for x in rv) + return rv, any_prefix_is_slash diff --git a/flask/venv/lib/python3.6/site-packages/click/globals.py b/flask/venv/lib/python3.6/site-packages/click/globals.py new file mode 100644 index 0000000..843b594 --- /dev/null +++ b/flask/venv/lib/python3.6/site-packages/click/globals.py @@ -0,0 +1,48 @@ +from threading import local + + +_local = local() + + +def get_current_context(silent=False): + """Returns the current click context. This can be used as a way to + access the current context object from anywhere. This is a more implicit + alternative to the :func:`pass_context` decorator. This function is + primarily useful for helpers such as :func:`echo` which might be + interested in changing its behavior based on the current context. + + To push the current context, :meth:`Context.scope` can be used. + + .. versionadded:: 5.0 + + :param silent: is set to `True` the return value is `None` if no context + is available. The default behavior is to raise a + :exc:`RuntimeError`. + """ + try: + return getattr(_local, 'stack')[-1] + except (AttributeError, IndexError): + if not silent: + raise RuntimeError('There is no active click context.') + + +def push_context(ctx): + """Pushes a new context to the current stack.""" + _local.__dict__.setdefault('stack', []).append(ctx) + + +def pop_context(): + """Removes the top level from the stack.""" + _local.stack.pop() + + +def resolve_color_default(color=None): + """"Internal helper to get the default value of the color flag. If a + value is passed it's returned unchanged, otherwise it's looked up from + the current context. + """ + if color is not None: + return color + ctx = get_current_context(silent=True) + if ctx is not None: + return ctx.color diff --git a/flask/venv/lib/python3.6/site-packages/click/parser.py b/flask/venv/lib/python3.6/site-packages/click/parser.py new file mode 100644 index 0000000..1c3ae9c --- /dev/null +++ b/flask/venv/lib/python3.6/site-packages/click/parser.py @@ -0,0 +1,427 @@ +# -*- coding: utf-8 -*- +""" +click.parser +~~~~~~~~~~~~ + +This module started out as largely a copy paste from the stdlib's +optparse module with the features removed that we do not need from +optparse because we implement them in Click on a higher level (for +instance type handling, help formatting and a lot more). + +The plan is to remove more and more from here over time. + +The reason this is a different module and not optparse from the stdlib +is that there are differences in 2.x and 3.x about the error messages +generated and optparse in the stdlib uses gettext for no good reason +and might cause us issues. +""" + +import re +from collections import deque +from .exceptions import UsageError, NoSuchOption, BadOptionUsage, \ + BadArgumentUsage + + +def _unpack_args(args, nargs_spec): + """Given an iterable of arguments and an iterable of nargs specifications, + it returns a tuple with all the unpacked arguments at the first index + and all remaining arguments as the second. + + The nargs specification is the number of arguments that should be consumed + or `-1` to indicate that this position should eat up all the remainders. + + Missing items are filled with `None`. + """ + args = deque(args) + nargs_spec = deque(nargs_spec) + rv = [] + spos = None + + def _fetch(c): + try: + if spos is None: + return c.popleft() + else: + return c.pop() + except IndexError: + return None + + while nargs_spec: + nargs = _fetch(nargs_spec) + if nargs == 1: + rv.append(_fetch(args)) + elif nargs > 1: + x = [_fetch(args) for _ in range(nargs)] + # If we're reversed, we're pulling in the arguments in reverse, + # so we need to turn them around. + if spos is not None: + x.reverse() + rv.append(tuple(x)) + elif nargs < 0: + if spos is not None: + raise TypeError('Cannot have two nargs < 0') + spos = len(rv) + rv.append(None) + + # spos is the position of the wildcard (star). If it's not `None`, + # we fill it with the remainder. + if spos is not None: + rv[spos] = tuple(args) + args = [] + rv[spos + 1:] = reversed(rv[spos + 1:]) + + return tuple(rv), list(args) + + +def _error_opt_args(nargs, opt): + if nargs == 1: + raise BadOptionUsage(opt, '%s option requires an argument' % opt) + raise BadOptionUsage(opt, '%s option requires %d arguments' % (opt, nargs)) + + +def split_opt(opt): + first = opt[:1] + if first.isalnum(): + return '', opt + if opt[1:2] == first: + return opt[:2], opt[2:] + return first, opt[1:] + + +def normalize_opt(opt, ctx): + if ctx is None or ctx.token_normalize_func is None: + return opt + prefix, opt = split_opt(opt) + return prefix + ctx.token_normalize_func(opt) + + +def split_arg_string(string): + """Given an argument string this attempts to split it into small parts.""" + rv = [] + for match in re.finditer(r"('([^'\\]*(?:\\.[^'\\]*)*)'" + r'|"([^"\\]*(?:\\.[^"\\]*)*)"' + r'|\S+)\s*', string, re.S): + arg = match.group().strip() + if arg[:1] == arg[-1:] and arg[:1] in '"\'': + arg = arg[1:-1].encode('ascii', 'backslashreplace') \ + .decode('unicode-escape') + try: + arg = type(string)(arg) + except UnicodeError: + pass + rv.append(arg) + return rv + + +class Option(object): + + def __init__(self, opts, dest, action=None, nargs=1, const=None, obj=None): + self._short_opts = [] + self._long_opts = [] + self.prefixes = set() + + for opt in opts: + prefix, value = split_opt(opt) + if not prefix: + raise ValueError('Invalid start character for option (%s)' + % opt) + self.prefixes.add(prefix[0]) + if len(prefix) == 1 and len(value) == 1: + self._short_opts.append(opt) + else: + self._long_opts.append(opt) + self.prefixes.add(prefix) + + if action is None: + action = 'store' + + self.dest = dest + self.action = action + self.nargs = nargs + self.const = const + self.obj = obj + + @property + def takes_value(self): + return self.action in ('store', 'append') + + def process(self, value, state): + if self.action == 'store': + state.opts[self.dest] = value + elif self.action == 'store_const': + state.opts[self.dest] = self.const + elif self.action == 'append': + state.opts.setdefault(self.dest, []).append(value) + elif self.action == 'append_const': + state.opts.setdefault(self.dest, []).append(self.const) + elif self.action == 'count': + state.opts[self.dest] = state.opts.get(self.dest, 0) + 1 + else: + raise ValueError('unknown action %r' % self.action) + state.order.append(self.obj) + + +class Argument(object): + + def __init__(self, dest, nargs=1, obj=None): + self.dest = dest + self.nargs = nargs + self.obj = obj + + def process(self, value, state): + if self.nargs > 1: + holes = sum(1 for x in value if x is None) + if holes == len(value): + value = None + elif holes != 0: + raise BadArgumentUsage('argument %s takes %d values' + % (self.dest, self.nargs)) + state.opts[self.dest] = value + state.order.append(self.obj) + + +class ParsingState(object): + + def __init__(self, rargs): + self.opts = {} + self.largs = [] + self.rargs = rargs + self.order = [] + + +class OptionParser(object): + """The option parser is an internal class that is ultimately used to + parse options and arguments. It's modelled after optparse and brings + a similar but vastly simplified API. It should generally not be used + directly as the high level Click classes wrap it for you. + + It's not nearly as extensible as optparse or argparse as it does not + implement features that are implemented on a higher level (such as + types or defaults). + + :param ctx: optionally the :class:`~click.Context` where this parser + should go with. + """ + + def __init__(self, ctx=None): + #: The :class:`~click.Context` for this parser. This might be + #: `None` for some advanced use cases. + self.ctx = ctx + #: This controls how the parser deals with interspersed arguments. + #: If this is set to `False`, the parser will stop on the first + #: non-option. Click uses this to implement nested subcommands + #: safely. + self.allow_interspersed_args = True + #: This tells the parser how to deal with unknown options. By + #: default it will error out (which is sensible), but there is a + #: second mode where it will ignore it and continue processing + #: after shifting all the unknown options into the resulting args. + self.ignore_unknown_options = False + if ctx is not None: + self.allow_interspersed_args = ctx.allow_interspersed_args + self.ignore_unknown_options = ctx.ignore_unknown_options + self._short_opt = {} + self._long_opt = {} + self._opt_prefixes = set(['-', '--']) + self._args = [] + + def add_option(self, opts, dest, action=None, nargs=1, const=None, + obj=None): + """Adds a new option named `dest` to the parser. The destination + is not inferred (unlike with optparse) and needs to be explicitly + provided. Action can be any of ``store``, ``store_const``, + ``append``, ``appnd_const`` or ``count``. + + The `obj` can be used to identify the option in the order list + that is returned from the parser. + """ + if obj is None: + obj = dest + opts = [normalize_opt(opt, self.ctx) for opt in opts] + option = Option(opts, dest, action=action, nargs=nargs, + const=const, obj=obj) + self._opt_prefixes.update(option.prefixes) + for opt in option._short_opts: + self._short_opt[opt] = option + for opt in option._long_opts: + self._long_opt[opt] = option + + def add_argument(self, dest, nargs=1, obj=None): + """Adds a positional argument named `dest` to the parser. + + The `obj` can be used to identify the option in the order list + that is returned from the parser. + """ + if obj is None: + obj = dest + self._args.append(Argument(dest=dest, nargs=nargs, obj=obj)) + + def parse_args(self, args): + """Parses positional arguments and returns ``(values, args, order)`` + for the parsed options and arguments as well as the leftover + arguments if there are any. The order is a list of objects as they + appear on the command line. If arguments appear multiple times they + will be memorized multiple times as well. + """ + state = ParsingState(args) + try: + self._process_args_for_options(state) + self._process_args_for_args(state) + except UsageError: + if self.ctx is None or not self.ctx.resilient_parsing: + raise + return state.opts, state.largs, state.order + + def _process_args_for_args(self, state): + pargs, args = _unpack_args(state.largs + state.rargs, + [x.nargs for x in self._args]) + + for idx, arg in enumerate(self._args): + arg.process(pargs[idx], state) + + state.largs = args + state.rargs = [] + + def _process_args_for_options(self, state): + while state.rargs: + arg = state.rargs.pop(0) + arglen = len(arg) + # Double dashes always handled explicitly regardless of what + # prefixes are valid. + if arg == '--': + return + elif arg[:1] in self._opt_prefixes and arglen > 1: + self._process_opts(arg, state) + elif self.allow_interspersed_args: + state.largs.append(arg) + else: + state.rargs.insert(0, arg) + return + + # Say this is the original argument list: + # [arg0, arg1, ..., arg(i-1), arg(i), arg(i+1), ..., arg(N-1)] + # ^ + # (we are about to process arg(i)). + # + # Then rargs is [arg(i), ..., arg(N-1)] and largs is a *subset* of + # [arg0, ..., arg(i-1)] (any options and their arguments will have + # been removed from largs). + # + # The while loop will usually consume 1 or more arguments per pass. + # If it consumes 1 (eg. arg is an option that takes no arguments), + # then after _process_arg() is done the situation is: + # + # largs = subset of [arg0, ..., arg(i)] + # rargs = [arg(i+1), ..., arg(N-1)] + # + # If allow_interspersed_args is false, largs will always be + # *empty* -- still a subset of [arg0, ..., arg(i-1)], but + # not a very interesting subset! + + def _match_long_opt(self, opt, explicit_value, state): + if opt not in self._long_opt: + possibilities = [word for word in self._long_opt + if word.startswith(opt)] + raise NoSuchOption(opt, possibilities=possibilities, ctx=self.ctx) + + option = self._long_opt[opt] + if option.takes_value: + # At this point it's safe to modify rargs by injecting the + # explicit value, because no exception is raised in this + # branch. This means that the inserted value will be fully + # consumed. + if explicit_value is not None: + state.rargs.insert(0, explicit_value) + + nargs = option.nargs + if len(state.rargs) < nargs: + _error_opt_args(nargs, opt) + elif nargs == 1: + value = state.rargs.pop(0) + else: + value = tuple(state.rargs[:nargs]) + del state.rargs[:nargs] + + elif explicit_value is not None: + raise BadOptionUsage(opt, '%s option does not take a value' % opt) + + else: + value = None + + option.process(value, state) + + def _match_short_opt(self, arg, state): + stop = False + i = 1 + prefix = arg[0] + unknown_options = [] + + for ch in arg[1:]: + opt = normalize_opt(prefix + ch, self.ctx) + option = self._short_opt.get(opt) + i += 1 + + if not option: + if self.ignore_unknown_options: + unknown_options.append(ch) + continue + raise NoSuchOption(opt, ctx=self.ctx) + if option.takes_value: + # Any characters left in arg? Pretend they're the + # next arg, and stop consuming characters of arg. + if i < len(arg): + state.rargs.insert(0, arg[i:]) + stop = True + + nargs = option.nargs + if len(state.rargs) < nargs: + _error_opt_args(nargs, opt) + elif nargs == 1: + value = state.rargs.pop(0) + else: + value = tuple(state.rargs[:nargs]) + del state.rargs[:nargs] + + else: + value = None + + option.process(value, state) + + if stop: + break + + # If we got any unknown options we re-combinate the string of the + # remaining options and re-attach the prefix, then report that + # to the state as new larg. This way there is basic combinatorics + # that can be achieved while still ignoring unknown arguments. + if self.ignore_unknown_options and unknown_options: + state.largs.append(prefix + ''.join(unknown_options)) + + def _process_opts(self, arg, state): + explicit_value = None + # Long option handling happens in two parts. The first part is + # supporting explicitly attached values. In any case, we will try + # to long match the option first. + if '=' in arg: + long_opt, explicit_value = arg.split('=', 1) + else: + long_opt = arg + norm_long_opt = normalize_opt(long_opt, self.ctx) + + # At this point we will match the (assumed) long option through + # the long option matching code. Note that this allows options + # like "-foo" to be matched as long options. + try: + self._match_long_opt(norm_long_opt, explicit_value, state) + except NoSuchOption: + # At this point the long option matching failed, and we need + # to try with short options. However there is a special rule + # which says, that if we have a two character options prefix + # (applies to "--foo" for instance), we do not dispatch to the + # short option code and will instead raise the no option + # error. + if arg[:2] not in self._opt_prefixes: + return self._match_short_opt(arg, state) + if not self.ignore_unknown_options: + raise + state.largs.append(arg) diff --git a/flask/venv/lib/python3.6/site-packages/click/termui.py b/flask/venv/lib/python3.6/site-packages/click/termui.py new file mode 100644 index 0000000..bf9a3aa --- /dev/null +++ b/flask/venv/lib/python3.6/site-packages/click/termui.py @@ -0,0 +1,606 @@ +import os +import sys +import struct +import inspect +import itertools + +from ._compat import raw_input, text_type, string_types, \ + isatty, strip_ansi, get_winterm_size, DEFAULT_COLUMNS, WIN +from .utils import echo +from .exceptions import Abort, UsageError +from .types import convert_type, Choice, Path +from .globals import resolve_color_default + + +# The prompt functions to use. The doc tools currently override these +# functions to customize how they work. +visible_prompt_func = raw_input + +_ansi_colors = { + 'black': 30, + 'red': 31, + 'green': 32, + 'yellow': 33, + 'blue': 34, + 'magenta': 35, + 'cyan': 36, + 'white': 37, + 'reset': 39, + 'bright_black': 90, + 'bright_red': 91, + 'bright_green': 92, + 'bright_yellow': 93, + 'bright_blue': 94, + 'bright_magenta': 95, + 'bright_cyan': 96, + 'bright_white': 97, +} +_ansi_reset_all = '\033[0m' + + +def hidden_prompt_func(prompt): + import getpass + return getpass.getpass(prompt) + + +def _build_prompt(text, suffix, show_default=False, default=None, show_choices=True, type=None): + prompt = text + if type is not None and show_choices and isinstance(type, Choice): + prompt += ' (' + ", ".join(map(str, type.choices)) + ')' + if default is not None and show_default: + prompt = '%s [%s]' % (prompt, default) + return prompt + suffix + + +def prompt(text, default=None, hide_input=False, confirmation_prompt=False, + type=None, value_proc=None, prompt_suffix=': ', show_default=True, + err=False, show_choices=True): + """Prompts a user for input. This is a convenience function that can + be used to prompt a user for input later. + + If the user aborts the input by sending a interrupt signal, this + function will catch it and raise a :exc:`Abort` exception. + + .. versionadded:: 7.0 + Added the show_choices parameter. + + .. versionadded:: 6.0 + Added unicode support for cmd.exe on Windows. + + .. versionadded:: 4.0 + Added the `err` parameter. + + :param text: the text to show for the prompt. + :param default: the default value to use if no input happens. If this + is not given it will prompt until it's aborted. + :param hide_input: if this is set to true then the input value will + be hidden. + :param confirmation_prompt: asks for confirmation for the value. + :param type: the type to use to check the value against. + :param value_proc: if this parameter is provided it's a function that + is invoked instead of the type conversion to + convert a value. + :param prompt_suffix: a suffix that should be added to the prompt. + :param show_default: shows or hides the default value in the prompt. + :param err: if set to true the file defaults to ``stderr`` instead of + ``stdout``, the same as with echo. + :param show_choices: Show or hide choices if the passed type is a Choice. + For example if type is a Choice of either day or week, + show_choices is true and text is "Group by" then the + prompt will be "Group by (day, week): ". + """ + result = None + + def prompt_func(text): + f = hide_input and hidden_prompt_func or visible_prompt_func + try: + # Write the prompt separately so that we get nice + # coloring through colorama on Windows + echo(text, nl=False, err=err) + return f('') + except (KeyboardInterrupt, EOFError): + # getpass doesn't print a newline if the user aborts input with ^C. + # Allegedly this behavior is inherited from getpass(3). + # A doc bug has been filed at https://bugs.python.org/issue24711 + if hide_input: + echo(None, err=err) + raise Abort() + + if value_proc is None: + value_proc = convert_type(type, default) + + prompt = _build_prompt(text, prompt_suffix, show_default, default, show_choices, type) + + while 1: + while 1: + value = prompt_func(prompt) + if value: + break + elif default is not None: + if isinstance(value_proc, Path): + # validate Path default value(exists, dir_okay etc.) + value = default + break + return default + try: + result = value_proc(value) + except UsageError as e: + echo('Error: %s' % e.message, err=err) + continue + if not confirmation_prompt: + return result + while 1: + value2 = prompt_func('Repeat for confirmation: ') + if value2: + break + if value == value2: + return result + echo('Error: the two entered values do not match', err=err) + + +def confirm(text, default=False, abort=False, prompt_suffix=': ', + show_default=True, err=False): + """Prompts for confirmation (yes/no question). + + If the user aborts the input by sending a interrupt signal this + function will catch it and raise a :exc:`Abort` exception. + + .. versionadded:: 4.0 + Added the `err` parameter. + + :param text: the question to ask. + :param default: the default for the prompt. + :param abort: if this is set to `True` a negative answer aborts the + exception by raising :exc:`Abort`. + :param prompt_suffix: a suffix that should be added to the prompt. + :param show_default: shows or hides the default value in the prompt. + :param err: if set to true the file defaults to ``stderr`` instead of + ``stdout``, the same as with echo. + """ + prompt = _build_prompt(text, prompt_suffix, show_default, + default and 'Y/n' or 'y/N') + while 1: + try: + # Write the prompt separately so that we get nice + # coloring through colorama on Windows + echo(prompt, nl=False, err=err) + value = visible_prompt_func('').lower().strip() + except (KeyboardInterrupt, EOFError): + raise Abort() + if value in ('y', 'yes'): + rv = True + elif value in ('n', 'no'): + rv = False + elif value == '': + rv = default + else: + echo('Error: invalid input', err=err) + continue + break + if abort and not rv: + raise Abort() + return rv + + +def get_terminal_size(): + """Returns the current size of the terminal as tuple in the form + ``(width, height)`` in columns and rows. + """ + # If shutil has get_terminal_size() (Python 3.3 and later) use that + if sys.version_info >= (3, 3): + import shutil + shutil_get_terminal_size = getattr(shutil, 'get_terminal_size', None) + if shutil_get_terminal_size: + sz = shutil_get_terminal_size() + return sz.columns, sz.lines + + # We provide a sensible default for get_winterm_size() when being invoked + # inside a subprocess. Without this, it would not provide a useful input. + if get_winterm_size is not None: + size = get_winterm_size() + if size == (0, 0): + return (79, 24) + else: + return size + + def ioctl_gwinsz(fd): + try: + import fcntl + import termios + cr = struct.unpack( + 'hh', fcntl.ioctl(fd, termios.TIOCGWINSZ, '1234')) + except Exception: + return + 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) + try: + cr = ioctl_gwinsz(fd) + finally: + os.close(fd) + except Exception: + pass + if not cr or not cr[0] or not cr[1]: + cr = (os.environ.get('LINES', 25), + os.environ.get('COLUMNS', DEFAULT_COLUMNS)) + return int(cr[1]), int(cr[0]) + + +def echo_via_pager(text_or_generator, color=None): + """This function takes a text and shows it via an environment specific + pager on stdout. + + .. versionchanged:: 3.0 + Added the `color` flag. + + :param text_or_generator: the text to page, or alternatively, a + generator emitting the text to page. + :param color: controls if the pager supports ANSI colors or not. The + default is autodetection. + """ + color = resolve_color_default(color) + + if inspect.isgeneratorfunction(text_or_generator): + i = text_or_generator() + elif isinstance(text_or_generator, string_types): + i = [text_or_generator] + else: + i = iter(text_or_generator) + + # convert every element of i to a text type if necessary + text_generator = (el if isinstance(el, string_types) else text_type(el) + for el in i) + + from ._termui_impl import pager + return pager(itertools.chain(text_generator, "\n"), color) + + +def progressbar(iterable=None, length=None, label=None, show_eta=True, + show_percent=None, show_pos=False, + item_show_func=None, fill_char='#', empty_char='-', + bar_template='%(label)s [%(bar)s] %(info)s', + info_sep=' ', width=36, file=None, color=None): + """This function creates an iterable context manager that can be used + to iterate over something while showing a progress bar. It will + either iterate over the `iterable` or `length` items (that are counted + up). While iteration happens, this function will print a rendered + progress bar to the given `file` (defaults to stdout) and will attempt + to calculate remaining time and more. By default, this progress bar + will not be rendered if the file is not a terminal. + + The context manager creates the progress bar. When the context + manager is entered the progress bar is already displayed. With every + iteration over the progress bar, the iterable passed to the bar is + advanced and the bar is updated. When the context manager exits, + a newline is printed and the progress bar is finalized on screen. + + No printing must happen or the progress bar will be unintentionally + destroyed. + + Example usage:: + + with progressbar(items) as bar: + for item in bar: + do_something_with(item) + + Alternatively, if no iterable is specified, one can manually update the + progress bar through the `update()` method instead of directly + iterating over the progress bar. The update method accepts the number + of steps to increment the bar with:: + + with progressbar(length=chunks.total_bytes) as bar: + for chunk in chunks: + process_chunk(chunk) + bar.update(chunks.bytes) + + .. versionadded:: 2.0 + + .. versionadded:: 4.0 + Added the `color` parameter. Added a `update` method to the + progressbar object. + + :param iterable: an iterable to iterate over. If not provided the length + is required. + :param length: the number of items to iterate over. By default the + progressbar will attempt to ask the iterator about its + length, which might or might not work. If an iterable is + also provided this parameter can be used to override the + length. If an iterable is not provided the progress bar + will iterate over a range of that length. + :param label: the label to show next to the progress bar. + :param show_eta: enables or disables the estimated time display. This is + automatically disabled if the length cannot be + determined. + :param show_percent: enables or disables the percentage display. The + default is `True` if the iterable has a length or + `False` if not. + :param show_pos: enables or disables the absolute position display. The + default is `False`. + :param item_show_func: a function called with the current item which + can return a string to show the current item + next to the progress bar. Note that the current + item can be `None`! + :param fill_char: the character to use to show the filled part of the + progress bar. + :param empty_char: the character to use to show the non-filled part of + the progress bar. + :param bar_template: the format string to use as template for the bar. + The parameters in it are ``label`` for the label, + ``bar`` for the progress bar and ``info`` for the + info section. + :param info_sep: the separator between multiple info items (eta etc.) + :param width: the width of the progress bar in characters, 0 means full + terminal width + :param file: the file to write to. If this is not a terminal then + only the label is printed. + :param color: controls if the terminal supports ANSI colors or not. The + default is autodetection. This is only needed if ANSI + codes are included anywhere in the progress bar output + which is not the case by default. + """ + from ._termui_impl import ProgressBar + color = resolve_color_default(color) + return ProgressBar(iterable=iterable, length=length, show_eta=show_eta, + show_percent=show_percent, show_pos=show_pos, + item_show_func=item_show_func, fill_char=fill_char, + empty_char=empty_char, bar_template=bar_template, + info_sep=info_sep, file=file, label=label, + width=width, color=color) + + +def clear(): + """Clears the terminal screen. This will have the effect of clearing + the whole visible space of the terminal and moving the cursor to the + top left. This does not do anything if not connected to a terminal. + + .. versionadded:: 2.0 + """ + if not isatty(sys.stdout): + return + # If we're on Windows and we don't have colorama available, then we + # clear the screen by shelling out. Otherwise we can use an escape + # sequence. + if WIN: + os.system('cls') + else: + sys.stdout.write('\033[2J\033[1;1H') + + +def style(text, fg=None, bg=None, bold=None, dim=None, underline=None, + blink=None, reverse=None, reset=True): + """Styles a text with ANSI styles and returns the new string. By + default the styling is self contained which means that at the end + of the string a reset code is issued. This can be prevented by + passing ``reset=False``. + + Examples:: + + click.echo(click.style('Hello World!', fg='green')) + click.echo(click.style('ATTENTION!', blink=True)) + click.echo(click.style('Some things', reverse=True, fg='cyan')) + + Supported color names: + + * ``black`` (might be a gray) + * ``red`` + * ``green`` + * ``yellow`` (might be an orange) + * ``blue`` + * ``magenta`` + * ``cyan`` + * ``white`` (might be light gray) + * ``bright_black`` + * ``bright_red`` + * ``bright_green`` + * ``bright_yellow`` + * ``bright_blue`` + * ``bright_magenta`` + * ``bright_cyan`` + * ``bright_white`` + * ``reset`` (reset the color code only) + + .. versionadded:: 2.0 + + .. versionadded:: 7.0 + Added support for bright colors. + + :param text: the string to style with ansi codes. + :param fg: if provided this will become the foreground color. + :param bg: if provided this will become the background color. + :param bold: if provided this will enable or disable bold mode. + :param dim: if provided this will enable or disable dim mode. This is + badly supported. + :param underline: if provided this will enable or disable underline. + :param blink: if provided this will enable or disable blinking. + :param reverse: if provided this will enable or disable inverse + rendering (foreground becomes background and the + other way round). + :param reset: by default a reset-all code is added at the end of the + string which means that styles do not carry over. This + can be disabled to compose styles. + """ + bits = [] + if fg: + try: + bits.append('\033[%dm' % (_ansi_colors[fg])) + except KeyError: + raise TypeError('Unknown color %r' % fg) + if bg: + try: + bits.append('\033[%dm' % (_ansi_colors[bg] + 10)) + except KeyError: + raise TypeError('Unknown color %r' % bg) + if bold is not None: + bits.append('\033[%dm' % (1 if bold else 22)) + if dim is not None: + bits.append('\033[%dm' % (2 if dim else 22)) + if underline is not None: + bits.append('\033[%dm' % (4 if underline else 24)) + if blink is not None: + bits.append('\033[%dm' % (5 if blink else 25)) + if reverse is not None: + bits.append('\033[%dm' % (7 if reverse else 27)) + bits.append(text) + if reset: + bits.append(_ansi_reset_all) + return ''.join(bits) + + +def unstyle(text): + """Removes ANSI styling information from a string. Usually it's not + necessary to use this function as Click's echo function will + automatically remove styling if necessary. + + .. versionadded:: 2.0 + + :param text: the text to remove style information from. + """ + return strip_ansi(text) + + +def secho(message=None, file=None, nl=True, err=False, color=None, **styles): + """This function combines :func:`echo` and :func:`style` into one + call. As such the following two calls are the same:: + + click.secho('Hello World!', fg='green') + click.echo(click.style('Hello World!', fg='green')) + + All keyword arguments are forwarded to the underlying functions + depending on which one they go with. + + .. versionadded:: 2.0 + """ + if message is not None: + message = style(message, **styles) + return echo(message, file=file, nl=nl, err=err, color=color) + + +def edit(text=None, editor=None, env=None, require_save=True, + extension='.txt', filename=None): + r"""Edits the given text in the defined editor. If an editor is given + (should be the full path to the executable but the regular operating + system search path is used for finding the executable) it overrides + the detected editor. Optionally, some environment variables can be + used. If the editor is closed without changes, `None` is returned. In + case a file is edited directly the return value is always `None` and + `require_save` and `extension` are ignored. + + If the editor cannot be opened a :exc:`UsageError` is raised. + + Note for Windows: to simplify cross-platform usage, the newlines are + automatically converted from POSIX to Windows and vice versa. As such, + the message here will have ``\n`` as newline markers. + + :param text: the text to edit. + :param editor: optionally the editor to use. Defaults to automatic + detection. + :param env: environment variables to forward to the editor. + :param require_save: if this is true, then not saving in the editor + will make the return value become `None`. + :param extension: the extension to tell the editor about. This defaults + to `.txt` but changing this might change syntax + highlighting. + :param filename: if provided it will edit this file instead of the + provided text contents. It will not use a temporary + file as an indirection in that case. + """ + from ._termui_impl import Editor + editor = Editor(editor=editor, env=env, require_save=require_save, + extension=extension) + if filename is None: + return editor.edit(text) + editor.edit_file(filename) + + +def launch(url, wait=False, locate=False): + """This function launches the given URL (or filename) in the default + viewer application for this file type. If this is an executable, it + might launch the executable in a new session. The return value is + the exit code of the launched application. Usually, ``0`` indicates + success. + + Examples:: + + click.launch('https://click.palletsprojects.com/') + click.launch('/my/downloaded/file', locate=True) + + .. versionadded:: 2.0 + + :param url: URL or filename of the thing to launch. + :param wait: waits for the program to stop. + :param locate: if this is set to `True` then instead of launching the + application associated with the URL it will attempt to + launch a file manager with the file located. This + might have weird effects if the URL does not point to + the filesystem. + """ + from ._termui_impl import open_url + return open_url(url, wait=wait, locate=locate) + + +# If this is provided, getchar() calls into this instead. This is used +# for unittesting purposes. +_getchar = None + + +def getchar(echo=False): + """Fetches a single character from the terminal and returns it. This + will always return a unicode character and under certain rare + circumstances this might return more than one character. The + situations which more than one character is returned is when for + whatever reason multiple characters end up in the terminal buffer or + standard input was not actually a terminal. + + Note that this will always read from the terminal, even if something + is piped into the standard input. + + Note for Windows: in rare cases when typing non-ASCII characters, this + function might wait for a second character and then return both at once. + This is because certain Unicode characters look like special-key markers. + + .. versionadded:: 2.0 + + :param echo: if set to `True`, the character read will also show up on + the terminal. The default is to not show it. + """ + f = _getchar + if f is None: + from ._termui_impl import getchar as f + return f(echo) + + +def raw_terminal(): + from ._termui_impl import raw_terminal as f + return f() + + +def pause(info='Press any key to continue ...', err=False): + """This command stops execution and waits for the user to press any + key to continue. This is similar to the Windows batch "pause" + command. If the program is not run through a terminal, this command + will instead do nothing. + + .. versionadded:: 2.0 + + .. versionadded:: 4.0 + Added the `err` parameter. + + :param info: the info string to print before pausing. + :param err: if set to message goes to ``stderr`` instead of + ``stdout``, the same as with echo. + """ + if not isatty(sys.stdin) or not isatty(sys.stdout): + return + try: + if info: + echo(info, nl=False, err=err) + try: + getchar() + except (KeyboardInterrupt, EOFError): + pass + finally: + if info: + echo(err=err) diff --git a/flask/venv/lib/python3.6/site-packages/click/testing.py b/flask/venv/lib/python3.6/site-packages/click/testing.py new file mode 100644 index 0000000..1b2924e --- /dev/null +++ b/flask/venv/lib/python3.6/site-packages/click/testing.py @@ -0,0 +1,374 @@ +import os +import sys +import shutil +import tempfile +import contextlib +import shlex + +from ._compat import iteritems, PY2, string_types + + +# If someone wants to vendor click, we want to ensure the +# correct package is discovered. Ideally we could use a +# relative import here but unfortunately Python does not +# support that. +clickpkg = sys.modules[__name__.rsplit('.', 1)[0]] + + +if PY2: + from cStringIO import StringIO +else: + import io + from ._compat import _find_binary_reader + + +class EchoingStdin(object): + + def __init__(self, input, output): + self._input = input + self._output = output + + def __getattr__(self, x): + return getattr(self._input, x) + + def _echo(self, rv): + self._output.write(rv) + return rv + + def read(self, n=-1): + return self._echo(self._input.read(n)) + + def readline(self, n=-1): + return self._echo(self._input.readline(n)) + + def readlines(self): + return [self._echo(x) for x in self._input.readlines()] + + def __iter__(self): + return iter(self._echo(x) for x in self._input) + + def __repr__(self): + return repr(self._input) + + +def make_input_stream(input, charset): + # Is already an input stream. + if hasattr(input, 'read'): + if PY2: + return input + rv = _find_binary_reader(input) + if rv is not None: + return rv + raise TypeError('Could not find binary reader for input stream.') + + if input is None: + input = b'' + elif not isinstance(input, bytes): + input = input.encode(charset) + if PY2: + return StringIO(input) + return io.BytesIO(input) + + +class Result(object): + """Holds the captured result of an invoked CLI script.""" + + def __init__(self, runner, stdout_bytes, stderr_bytes, exit_code, + exception, exc_info=None): + #: The runner that created the result + self.runner = runner + #: The standard output as bytes. + self.stdout_bytes = stdout_bytes + #: The standard error as bytes, or False(y) if not available + self.stderr_bytes = stderr_bytes + #: The exit code as integer. + self.exit_code = exit_code + #: The exception that happened if one did. + self.exception = exception + #: The traceback + self.exc_info = exc_info + + @property + def output(self): + """The (standard) output as unicode string.""" + return self.stdout + + @property + def stdout(self): + """The standard output as unicode string.""" + return self.stdout_bytes.decode(self.runner.charset, 'replace') \ + .replace('\r\n', '\n') + + @property + def stderr(self): + """The standard error as unicode string.""" + if not self.stderr_bytes: + raise ValueError("stderr not separately captured") + return self.stderr_bytes.decode(self.runner.charset, 'replace') \ + .replace('\r\n', '\n') + + + def __repr__(self): + return '<%s %s>' % ( + type(self).__name__, + self.exception and repr(self.exception) or 'okay', + ) + + +class CliRunner(object): + """The CLI runner provides functionality to invoke a Click command line + script for unittesting purposes in a isolated environment. This only + works in single-threaded systems without any concurrency as it changes the + global interpreter state. + + :param charset: the character set for the input and output data. This is + UTF-8 by default and should not be changed currently as + the reporting to Click only works in Python 2 properly. + :param env: a dictionary with environment variables for overriding. + :param echo_stdin: if this is set to `True`, then reading from stdin writes + to stdout. This is useful for showing examples in + some circumstances. Note that regular prompts + will automatically echo the input. + :param mix_stderr: if this is set to `False`, then stdout and stderr are + preserved as independent streams. This is useful for + Unix-philosophy apps that have predictable stdout and + noisy stderr, such that each may be measured + independently + """ + + def __init__(self, charset=None, env=None, echo_stdin=False, + mix_stderr=True): + if charset is None: + charset = 'utf-8' + self.charset = charset + self.env = env or {} + self.echo_stdin = echo_stdin + self.mix_stderr = mix_stderr + + def get_default_prog_name(self, cli): + """Given a command object it will return the default program name + for it. The default is the `name` attribute or ``"root"`` if not + set. + """ + return cli.name or 'root' + + def make_env(self, overrides=None): + """Returns the environment overrides for invoking a script.""" + rv = dict(self.env) + if overrides: + rv.update(overrides) + return rv + + @contextlib.contextmanager + def isolation(self, input=None, env=None, color=False): + """A context manager that sets up the isolation for invoking of a + command line tool. This sets up stdin with the given input data + and `os.environ` with the overrides from the given dictionary. + This also rebinds some internals in Click to be mocked (like the + prompt functionality). + + This is automatically done in the :meth:`invoke` method. + + .. versionadded:: 4.0 + The ``color`` parameter was added. + + :param input: the input stream to put into sys.stdin. + :param env: the environment overrides as dictionary. + :param color: whether the output should contain color codes. The + application can still override this explicitly. + """ + input = make_input_stream(input, self.charset) + + old_stdin = sys.stdin + old_stdout = sys.stdout + old_stderr = sys.stderr + old_forced_width = clickpkg.formatting.FORCED_WIDTH + clickpkg.formatting.FORCED_WIDTH = 80 + + env = self.make_env(env) + + if PY2: + bytes_output = StringIO() + if self.echo_stdin: + input = EchoingStdin(input, bytes_output) + sys.stdout = bytes_output + if not self.mix_stderr: + bytes_error = StringIO() + sys.stderr = bytes_error + else: + bytes_output = io.BytesIO() + if self.echo_stdin: + input = EchoingStdin(input, bytes_output) + input = io.TextIOWrapper(input, encoding=self.charset) + sys.stdout = io.TextIOWrapper( + bytes_output, encoding=self.charset) + if not self.mix_stderr: + bytes_error = io.BytesIO() + sys.stderr = io.TextIOWrapper( + bytes_error, encoding=self.charset) + + if self.mix_stderr: + sys.stderr = sys.stdout + + sys.stdin = input + + def visible_input(prompt=None): + sys.stdout.write(prompt or '') + val = input.readline().rstrip('\r\n') + sys.stdout.write(val + '\n') + sys.stdout.flush() + return val + + def hidden_input(prompt=None): + sys.stdout.write((prompt or '') + '\n') + sys.stdout.flush() + return input.readline().rstrip('\r\n') + + def _getchar(echo): + char = sys.stdin.read(1) + if echo: + sys.stdout.write(char) + sys.stdout.flush() + return char + + default_color = color + + def should_strip_ansi(stream=None, color=None): + if color is None: + return not default_color + return not color + + old_visible_prompt_func = clickpkg.termui.visible_prompt_func + old_hidden_prompt_func = clickpkg.termui.hidden_prompt_func + old__getchar_func = clickpkg.termui._getchar + old_should_strip_ansi = clickpkg.utils.should_strip_ansi + clickpkg.termui.visible_prompt_func = visible_input + clickpkg.termui.hidden_prompt_func = hidden_input + clickpkg.termui._getchar = _getchar + clickpkg.utils.should_strip_ansi = should_strip_ansi + + old_env = {} + try: + for key, value in iteritems(env): + old_env[key] = os.environ.get(key) + if value is None: + try: + del os.environ[key] + except Exception: + pass + else: + os.environ[key] = value + yield (bytes_output, not self.mix_stderr and bytes_error) + finally: + for key, value in iteritems(old_env): + if value is None: + try: + del os.environ[key] + except Exception: + pass + else: + os.environ[key] = value + sys.stdout = old_stdout + sys.stderr = old_stderr + sys.stdin = old_stdin + clickpkg.termui.visible_prompt_func = old_visible_prompt_func + clickpkg.termui.hidden_prompt_func = old_hidden_prompt_func + clickpkg.termui._getchar = old__getchar_func + clickpkg.utils.should_strip_ansi = old_should_strip_ansi + clickpkg.formatting.FORCED_WIDTH = old_forced_width + + def invoke(self, cli, args=None, input=None, env=None, + catch_exceptions=True, color=False, mix_stderr=False, **extra): + """Invokes a command in an isolated environment. The arguments are + forwarded directly to the command line script, the `extra` keyword + arguments are passed to the :meth:`~clickpkg.Command.main` function of + the command. + + This returns a :class:`Result` object. + + .. versionadded:: 3.0 + The ``catch_exceptions`` parameter was added. + + .. versionchanged:: 3.0 + The result object now has an `exc_info` attribute with the + traceback if available. + + .. versionadded:: 4.0 + The ``color`` parameter was added. + + :param cli: the command to invoke + :param args: the arguments to invoke. It may be given as an iterable + or a string. When given as string it will be interpreted + as a Unix shell command. More details at + :func:`shlex.split`. + :param input: the input data for `sys.stdin`. + :param env: the environment overrides. + :param catch_exceptions: Whether to catch any other exceptions than + ``SystemExit``. + :param extra: the keyword arguments to pass to :meth:`main`. + :param color: whether the output should contain color codes. The + application can still override this explicitly. + """ + exc_info = None + with self.isolation(input=input, env=env, color=color) as outstreams: + exception = None + exit_code = 0 + + if isinstance(args, string_types): + args = shlex.split(args) + + try: + prog_name = extra.pop("prog_name") + except KeyError: + prog_name = self.get_default_prog_name(cli) + + try: + cli.main(args=args or (), prog_name=prog_name, **extra) + except SystemExit as e: + exc_info = sys.exc_info() + exit_code = e.code + if exit_code is None: + exit_code = 0 + + if exit_code != 0: + exception = e + + if not isinstance(exit_code, int): + sys.stdout.write(str(exit_code)) + sys.stdout.write('\n') + exit_code = 1 + + except Exception as e: + if not catch_exceptions: + raise + exception = e + exit_code = 1 + exc_info = sys.exc_info() + finally: + sys.stdout.flush() + stdout = outstreams[0].getvalue() + stderr = outstreams[1] and outstreams[1].getvalue() + + return Result(runner=self, + stdout_bytes=stdout, + stderr_bytes=stderr, + exit_code=exit_code, + exception=exception, + exc_info=exc_info) + + @contextlib.contextmanager + def isolated_filesystem(self): + """A context manager that creates a temporary folder and changes + the current working directory to it for isolated filesystem tests. + """ + cwd = os.getcwd() + t = tempfile.mkdtemp() + os.chdir(t) + try: + yield t + finally: + os.chdir(cwd) + try: + shutil.rmtree(t) + except (OSError, IOError): + pass diff --git a/flask/venv/lib/python3.6/site-packages/click/types.py b/flask/venv/lib/python3.6/site-packages/click/types.py new file mode 100644 index 0000000..1f88032 --- /dev/null +++ b/flask/venv/lib/python3.6/site-packages/click/types.py @@ -0,0 +1,668 @@ +import os +import stat +from datetime import datetime + +from ._compat import open_stream, text_type, filename_to_ui, \ + get_filesystem_encoding, get_streerror, _get_argv_encoding, PY2 +from .exceptions import BadParameter +from .utils import safecall, LazyFile + + +class ParamType(object): + """Helper for converting values through types. The following is + necessary for a valid type: + + * it needs a name + * it needs to pass through None unchanged + * it needs to convert from a string + * it needs to convert its result type through unchanged + (eg: needs to be idempotent) + * it needs to be able to deal with param and context being `None`. + This can be the case when the object is used with prompt + inputs. + """ + is_composite = False + + #: the descriptive name of this type + name = None + + #: if a list of this type is expected and the value is pulled from a + #: string environment variable, this is what splits it up. `None` + #: means any whitespace. For all parameters the general rule is that + #: whitespace splits them up. The exception are paths and files which + #: are split by ``os.path.pathsep`` by default (":" on Unix and ";" on + #: Windows). + envvar_list_splitter = None + + def __call__(self, value, param=None, ctx=None): + if value is not None: + return self.convert(value, param, ctx) + + def get_metavar(self, param): + """Returns the metavar default for this param if it provides one.""" + + def get_missing_message(self, param): + """Optionally might return extra information about a missing + parameter. + + .. versionadded:: 2.0 + """ + + def convert(self, value, param, ctx): + """Converts the value. This is not invoked for values that are + `None` (the missing value). + """ + return value + + def split_envvar_value(self, rv): + """Given a value from an environment variable this splits it up + into small chunks depending on the defined envvar list splitter. + + If the splitter is set to `None`, which means that whitespace splits, + then leading and trailing whitespace is ignored. Otherwise, leading + and trailing splitters usually lead to empty items being included. + """ + return (rv or '').split(self.envvar_list_splitter) + + def fail(self, message, param=None, ctx=None): + """Helper method to fail with an invalid value message.""" + raise BadParameter(message, ctx=ctx, param=param) + + +class CompositeParamType(ParamType): + is_composite = True + + @property + def arity(self): + raise NotImplementedError() + + +class FuncParamType(ParamType): + + def __init__(self, func): + self.name = func.__name__ + self.func = func + + def convert(self, value, param, ctx): + try: + return self.func(value) + except ValueError: + try: + value = text_type(value) + except UnicodeError: + value = str(value).decode('utf-8', 'replace') + self.fail(value, param, ctx) + + +class UnprocessedParamType(ParamType): + name = 'text' + + def convert(self, value, param, ctx): + return value + + def __repr__(self): + return 'UNPROCESSED' + + +class StringParamType(ParamType): + name = 'text' + + def convert(self, value, param, ctx): + if isinstance(value, bytes): + enc = _get_argv_encoding() + try: + value = value.decode(enc) + except UnicodeError: + fs_enc = get_filesystem_encoding() + if fs_enc != enc: + try: + value = value.decode(fs_enc) + except UnicodeError: + value = value.decode('utf-8', 'replace') + return value + return value + + def __repr__(self): + return 'STRING' + + +class Choice(ParamType): + """The choice type allows a value to be checked against a fixed set + of supported values. All of these values have to be strings. + + You should only pass a list or tuple of choices. Other iterables + (like generators) may lead to surprising results. + + See :ref:`choice-opts` for an example. + + :param case_sensitive: Set to false to make choices case + insensitive. Defaults to true. + """ + + name = 'choice' + + def __init__(self, choices, case_sensitive=True): + self.choices = choices + self.case_sensitive = case_sensitive + + def get_metavar(self, param): + return '[%s]' % '|'.join(self.choices) + + def get_missing_message(self, param): + return 'Choose from:\n\t%s.' % ',\n\t'.join(self.choices) + + def convert(self, value, param, ctx): + # Exact match + if value in self.choices: + return value + + # Match through normalization and case sensitivity + # first do token_normalize_func, then lowercase + # preserve original `value` to produce an accurate message in + # `self.fail` + normed_value = value + normed_choices = self.choices + + if ctx is not None and \ + ctx.token_normalize_func is not None: + normed_value = ctx.token_normalize_func(value) + normed_choices = [ctx.token_normalize_func(choice) for choice in + self.choices] + + if not self.case_sensitive: + normed_value = normed_value.lower() + normed_choices = [choice.lower() for choice in normed_choices] + + if normed_value in normed_choices: + return normed_value + + self.fail('invalid choice: %s. (choose from %s)' % + (value, ', '.join(self.choices)), param, ctx) + + def __repr__(self): + return 'Choice(%r)' % list(self.choices) + + +class DateTime(ParamType): + """The DateTime type converts date strings into `datetime` objects. + + The format strings which are checked are configurable, but default to some + common (non-timezone aware) ISO 8601 formats. + + When specifying *DateTime* formats, you should only pass a list or a tuple. + Other iterables, like generators, may lead to surprising results. + + The format strings are processed using ``datetime.strptime``, and this + consequently defines the format strings which are allowed. + + Parsing is tried using each format, in order, and the first format which + parses successfully is used. + + :param formats: A list or tuple of date format strings, in the order in + which they should be tried. Defaults to + ``'%Y-%m-%d'``, ``'%Y-%m-%dT%H:%M:%S'``, + ``'%Y-%m-%d %H:%M:%S'``. + """ + name = 'datetime' + + def __init__(self, formats=None): + self.formats = formats or [ + '%Y-%m-%d', + '%Y-%m-%dT%H:%M:%S', + '%Y-%m-%d %H:%M:%S' + ] + + def get_metavar(self, param): + return '[{}]'.format('|'.join(self.formats)) + + def _try_to_convert_date(self, value, format): + try: + return datetime.strptime(value, format) + except ValueError: + return None + + def convert(self, value, param, ctx): + # Exact match + for format in self.formats: + dtime = self._try_to_convert_date(value, format) + if dtime: + return dtime + + self.fail( + 'invalid datetime format: {}. (choose from {})'.format( + value, ', '.join(self.formats))) + + def __repr__(self): + return 'DateTime' + + +class IntParamType(ParamType): + name = 'integer' + + def convert(self, value, param, ctx): + try: + return int(value) + except (ValueError, UnicodeError): + self.fail('%s is not a valid integer' % value, param, ctx) + + def __repr__(self): + return 'INT' + + +class IntRange(IntParamType): + """A parameter that works similar to :data:`click.INT` but restricts + the value to fit into a range. The default behavior is to fail if the + value falls outside the range, but it can also be silently clamped + between the two edges. + + See :ref:`ranges` for an example. + """ + name = 'integer range' + + def __init__(self, min=None, max=None, clamp=False): + self.min = min + self.max = max + self.clamp = clamp + + def convert(self, value, param, ctx): + rv = IntParamType.convert(self, value, param, ctx) + if self.clamp: + if self.min is not None and rv < self.min: + return self.min + if self.max is not None and rv > self.max: + return self.max + if self.min is not None and rv < self.min or \ + self.max is not None and rv > self.max: + if self.min is None: + self.fail('%s is bigger than the maximum valid value ' + '%s.' % (rv, self.max), param, ctx) + elif self.max is None: + self.fail('%s is smaller than the minimum valid value ' + '%s.' % (rv, self.min), param, ctx) + else: + self.fail('%s is not in the valid range of %s to %s.' + % (rv, self.min, self.max), param, ctx) + return rv + + def __repr__(self): + return 'IntRange(%r, %r)' % (self.min, self.max) + + +class FloatParamType(ParamType): + name = 'float' + + def convert(self, value, param, ctx): + try: + return float(value) + except (UnicodeError, ValueError): + self.fail('%s is not a valid floating point value' % + value, param, ctx) + + def __repr__(self): + return 'FLOAT' + + +class FloatRange(FloatParamType): + """A parameter that works similar to :data:`click.FLOAT` but restricts + the value to fit into a range. The default behavior is to fail if the + value falls outside the range, but it can also be silently clamped + between the two edges. + + See :ref:`ranges` for an example. + """ + name = 'float range' + + def __init__(self, min=None, max=None, clamp=False): + self.min = min + self.max = max + self.clamp = clamp + + def convert(self, value, param, ctx): + rv = FloatParamType.convert(self, value, param, ctx) + if self.clamp: + if self.min is not None and rv < self.min: + return self.min + if self.max is not None and rv > self.max: + return self.max + if self.min is not None and rv < self.min or \ + self.max is not None and rv > self.max: + if self.min is None: + self.fail('%s is bigger than the maximum valid value ' + '%s.' % (rv, self.max), param, ctx) + elif self.max is None: + self.fail('%s is smaller than the minimum valid value ' + '%s.' % (rv, self.min), param, ctx) + else: + self.fail('%s is not in the valid range of %s to %s.' + % (rv, self.min, self.max), param, ctx) + return rv + + def __repr__(self): + return 'FloatRange(%r, %r)' % (self.min, self.max) + + +class BoolParamType(ParamType): + name = 'boolean' + + def convert(self, value, param, ctx): + if isinstance(value, bool): + return bool(value) + value = value.lower() + if value in ('true', 't', '1', 'yes', 'y'): + return True + elif value in ('false', 'f', '0', 'no', 'n'): + return False + self.fail('%s is not a valid boolean' % value, param, ctx) + + def __repr__(self): + return 'BOOL' + + +class UUIDParameterType(ParamType): + name = 'uuid' + + def convert(self, value, param, ctx): + import uuid + try: + if PY2 and isinstance(value, text_type): + value = value.encode('ascii') + return uuid.UUID(value) + except (UnicodeError, ValueError): + self.fail('%s is not a valid UUID value' % value, param, ctx) + + def __repr__(self): + return 'UUID' + + +class File(ParamType): + """Declares a parameter to be a file for reading or writing. The file + is automatically closed once the context tears down (after the command + finished working). + + Files can be opened for reading or writing. The special value ``-`` + indicates stdin or stdout depending on the mode. + + By default, the file is opened for reading text data, but it can also be + opened in binary mode or for writing. The encoding parameter can be used + to force a specific encoding. + + The `lazy` flag controls if the file should be opened immediately or upon + first IO. The default is to be non-lazy for standard input and output + streams as well as files opened for reading, `lazy` otherwise. When opening a + file lazily for reading, it is still opened temporarily for validation, but + will not be held open until first IO. lazy is mainly useful when opening + for writing to avoid creating the file until it is needed. + + Starting with Click 2.0, files can also be opened atomically in which + case all writes go into a separate file in the same folder and upon + completion the file will be moved over to the original location. This + is useful if a file regularly read by other users is modified. + + See :ref:`file-args` for more information. + """ + name = 'filename' + envvar_list_splitter = os.path.pathsep + + def __init__(self, mode='r', encoding=None, errors='strict', lazy=None, + atomic=False): + self.mode = mode + self.encoding = encoding + self.errors = errors + self.lazy = lazy + self.atomic = atomic + + def resolve_lazy_flag(self, value): + if self.lazy is not None: + return self.lazy + if value == '-': + return False + elif 'w' in self.mode: + return True + return False + + def convert(self, value, param, ctx): + try: + if hasattr(value, 'read') or hasattr(value, 'write'): + return value + + lazy = self.resolve_lazy_flag(value) + + if lazy: + f = LazyFile(value, self.mode, self.encoding, self.errors, + atomic=self.atomic) + if ctx is not None: + ctx.call_on_close(f.close_intelligently) + return f + + f, should_close = open_stream(value, self.mode, + self.encoding, self.errors, + atomic=self.atomic) + # If a context is provided, we automatically close the file + # at the end of the context execution (or flush out). If a + # context does not exist, it's the caller's responsibility to + # properly close the file. This for instance happens when the + # type is used with prompts. + if ctx is not None: + if should_close: + ctx.call_on_close(safecall(f.close)) + else: + ctx.call_on_close(safecall(f.flush)) + return f + except (IOError, OSError) as e: + self.fail('Could not open file: %s: %s' % ( + filename_to_ui(value), + get_streerror(e), + ), param, ctx) + + +class Path(ParamType): + """The path type is similar to the :class:`File` type but it performs + different checks. First of all, instead of returning an open file + handle it returns just the filename. Secondly, it can perform various + basic checks about what the file or directory should be. + + .. versionchanged:: 6.0 + `allow_dash` was added. + + :param exists: if set to true, the file or directory needs to exist for + this value to be valid. If this is not required and a + file does indeed not exist, then all further checks are + silently skipped. + :param file_okay: controls if a file is a possible value. + :param dir_okay: controls if a directory is a possible value. + :param writable: if true, a writable check is performed. + :param readable: if true, a readable check is performed. + :param resolve_path: if this is true, then the path is fully resolved + before the value is passed onwards. This means + that it's absolute and symlinks are resolved. It + will not expand a tilde-prefix, as this is + supposed to be done by the shell only. + :param allow_dash: If this is set to `True`, a single dash to indicate + standard streams is permitted. + :param path_type: optionally a string type that should be used to + represent the path. The default is `None` which + means the return value will be either bytes or + unicode depending on what makes most sense given the + input data Click deals with. + """ + envvar_list_splitter = os.path.pathsep + + def __init__(self, exists=False, file_okay=True, dir_okay=True, + writable=False, readable=True, resolve_path=False, + allow_dash=False, path_type=None): + self.exists = exists + self.file_okay = file_okay + self.dir_okay = dir_okay + self.writable = writable + self.readable = readable + self.resolve_path = resolve_path + self.allow_dash = allow_dash + self.type = path_type + + if self.file_okay and not self.dir_okay: + self.name = 'file' + self.path_type = 'File' + elif self.dir_okay and not self.file_okay: + self.name = 'directory' + self.path_type = 'Directory' + else: + self.name = 'path' + self.path_type = 'Path' + + def coerce_path_result(self, rv): + if self.type is not None and not isinstance(rv, self.type): + if self.type is text_type: + rv = rv.decode(get_filesystem_encoding()) + else: + rv = rv.encode(get_filesystem_encoding()) + return rv + + def convert(self, value, param, ctx): + rv = value + + is_dash = self.file_okay and self.allow_dash and rv in (b'-', '-') + + if not is_dash: + if self.resolve_path: + rv = os.path.realpath(rv) + + try: + st = os.stat(rv) + except OSError: + if not self.exists: + return self.coerce_path_result(rv) + self.fail('%s "%s" does not exist.' % ( + self.path_type, + filename_to_ui(value) + ), param, ctx) + + if not self.file_okay and stat.S_ISREG(st.st_mode): + self.fail('%s "%s" is a file.' % ( + self.path_type, + filename_to_ui(value) + ), param, ctx) + if not self.dir_okay and stat.S_ISDIR(st.st_mode): + self.fail('%s "%s" is a directory.' % ( + self.path_type, + filename_to_ui(value) + ), param, ctx) + if self.writable and not os.access(value, os.W_OK): + self.fail('%s "%s" is not writable.' % ( + self.path_type, + filename_to_ui(value) + ), param, ctx) + if self.readable and not os.access(value, os.R_OK): + self.fail('%s "%s" is not readable.' % ( + self.path_type, + filename_to_ui(value) + ), param, ctx) + + return self.coerce_path_result(rv) + + +class Tuple(CompositeParamType): + """The default behavior of Click is to apply a type on a value directly. + This works well in most cases, except for when `nargs` is set to a fixed + count and different types should be used for different items. In this + case the :class:`Tuple` type can be used. This type can only be used + if `nargs` is set to a fixed number. + + For more information see :ref:`tuple-type`. + + This can be selected by using a Python tuple literal as a type. + + :param types: a list of types that should be used for the tuple items. + """ + + def __init__(self, types): + self.types = [convert_type(ty) for ty in types] + + @property + def name(self): + return "<" + " ".join(ty.name for ty in self.types) + ">" + + @property + def arity(self): + return len(self.types) + + def convert(self, value, param, ctx): + if len(value) != len(self.types): + raise TypeError('It would appear that nargs is set to conflict ' + 'with the composite type arity.') + return tuple(ty(x, param, ctx) for ty, x in zip(self.types, value)) + + +def convert_type(ty, default=None): + """Converts a callable or python ty into the most appropriate param + ty. + """ + guessed_type = False + if ty is None and default is not None: + if isinstance(default, tuple): + ty = tuple(map(type, default)) + else: + ty = type(default) + guessed_type = True + + if isinstance(ty, tuple): + return Tuple(ty) + if isinstance(ty, ParamType): + return ty + if ty is text_type or ty is str or ty is None: + return STRING + if ty is int: + return INT + # Booleans are only okay if not guessed. This is done because for + # flags the default value is actually a bit of a lie in that it + # indicates which of the flags is the one we want. See get_default() + # for more information. + if ty is bool and not guessed_type: + return BOOL + if ty is float: + return FLOAT + if guessed_type: + return STRING + + # Catch a common mistake + if __debug__: + try: + if issubclass(ty, ParamType): + raise AssertionError('Attempted to use an uninstantiated ' + 'parameter type (%s).' % ty) + except TypeError: + pass + return FuncParamType(ty) + + +#: A dummy parameter type that just does nothing. From a user's +#: perspective this appears to just be the same as `STRING` but internally +#: no string conversion takes place. This is necessary to achieve the +#: same bytes/unicode behavior on Python 2/3 in situations where you want +#: to not convert argument types. This is usually useful when working +#: with file paths as they can appear in bytes and unicode. +#: +#: For path related uses the :class:`Path` type is a better choice but +#: there are situations where an unprocessed type is useful which is why +#: it is is provided. +#: +#: .. versionadded:: 4.0 +UNPROCESSED = UnprocessedParamType() + +#: A unicode string parameter type which is the implicit default. This +#: can also be selected by using ``str`` as type. +STRING = StringParamType() + +#: An integer parameter. This can also be selected by using ``int`` as +#: type. +INT = IntParamType() + +#: A floating point value parameter. This can also be selected by using +#: ``float`` as type. +FLOAT = FloatParamType() + +#: A boolean parameter. This is the default for boolean flags. This can +#: also be selected by using ``bool`` as a type. +BOOL = BoolParamType() + +#: A UUID parameter. +UUID = UUIDParameterType() diff --git a/flask/venv/lib/python3.6/site-packages/click/utils.py b/flask/venv/lib/python3.6/site-packages/click/utils.py new file mode 100644 index 0000000..fc84369 --- /dev/null +++ b/flask/venv/lib/python3.6/site-packages/click/utils.py @@ -0,0 +1,440 @@ +import os +import sys + +from .globals import resolve_color_default + +from ._compat import text_type, open_stream, get_filesystem_encoding, \ + get_streerror, string_types, PY2, binary_streams, text_streams, \ + filename_to_ui, auto_wrap_for_ansi, strip_ansi, should_strip_ansi, \ + _default_text_stdout, _default_text_stderr, is_bytes, WIN + +if not PY2: + from ._compat import _find_binary_writer +elif WIN: + from ._winconsole import _get_windows_argv, \ + _hash_py_argv, _initial_argv_hash + + +echo_native_types = string_types + (bytes, bytearray) + + +def _posixify(name): + return '-'.join(name.split()).lower() + + +def safecall(func): + """Wraps a function so that it swallows exceptions.""" + def wrapper(*args, **kwargs): + try: + return func(*args, **kwargs) + except Exception: + pass + return wrapper + + +def make_str(value): + """Converts a value into a valid string.""" + if isinstance(value, bytes): + try: + return value.decode(get_filesystem_encoding()) + except UnicodeError: + return value.decode('utf-8', 'replace') + return text_type(value) + + +def make_default_short_help(help, max_length=45): + """Return a condensed version of help string.""" + words = help.split() + total_length = 0 + result = [] + done = False + + for word in words: + if word[-1:] == '.': + done = True + new_length = result and 1 + len(word) or len(word) + if total_length + new_length > max_length: + result.append('...') + done = True + else: + if result: + result.append(' ') + result.append(word) + if done: + break + total_length += new_length + + return ''.join(result) + + +class LazyFile(object): + """A lazy file works like a regular file but it does not fully open + the file but it does perform some basic checks early to see if the + filename parameter does make sense. This is useful for safely opening + files for writing. + """ + + def __init__(self, filename, mode='r', encoding=None, errors='strict', + atomic=False): + self.name = filename + self.mode = mode + self.encoding = encoding + self.errors = errors + self.atomic = atomic + + if filename == '-': + self._f, self.should_close = open_stream(filename, mode, + encoding, errors) + else: + if 'r' in mode: + # Open and close the file in case we're opening it for + # reading so that we can catch at least some errors in + # some cases early. + open(filename, mode).close() + self._f = None + self.should_close = True + + def __getattr__(self, name): + return getattr(self.open(), name) + + def __repr__(self): + if self._f is not None: + return repr(self._f) + return '' % (self.name, self.mode) + + def open(self): + """Opens the file if it's not yet open. This call might fail with + a :exc:`FileError`. Not handling this error will produce an error + that Click shows. + """ + if self._f is not None: + return self._f + try: + rv, self.should_close = open_stream(self.name, self.mode, + self.encoding, + self.errors, + atomic=self.atomic) + except (IOError, OSError) as e: + from .exceptions import FileError + raise FileError(self.name, hint=get_streerror(e)) + self._f = rv + return rv + + def close(self): + """Closes the underlying file, no matter what.""" + if self._f is not None: + self._f.close() + + def close_intelligently(self): + """This function only closes the file if it was opened by the lazy + file wrapper. For instance this will never close stdin. + """ + if self.should_close: + self.close() + + def __enter__(self): + return self + + def __exit__(self, exc_type, exc_value, tb): + self.close_intelligently() + + def __iter__(self): + self.open() + return iter(self._f) + + +class KeepOpenFile(object): + + def __init__(self, file): + self._file = file + + def __getattr__(self, name): + return getattr(self._file, name) + + def __enter__(self): + return self + + def __exit__(self, exc_type, exc_value, tb): + pass + + def __repr__(self): + return repr(self._file) + + def __iter__(self): + return iter(self._file) + + +def echo(message=None, file=None, nl=True, err=False, color=None): + """Prints a message plus a newline to the given file or stdout. On + first sight, this looks like the print function, but it has improved + support for handling Unicode and binary data that does not fail no + matter how badly configured the system is. + + Primarily it means that you can print binary data as well as Unicode + data on both 2.x and 3.x to the given file in the most appropriate way + possible. This is a very carefree function in that it will try its + best to not fail. As of Click 6.0 this includes support for unicode + output on the Windows console. + + In addition to that, if `colorama`_ is installed, the echo function will + also support clever handling of ANSI codes. Essentially it will then + do the following: + + - add transparent handling of ANSI color codes on Windows. + - hide ANSI codes automatically if the destination file is not a + terminal. + + .. _colorama: https://pypi.org/project/colorama/ + + .. versionchanged:: 6.0 + As of Click 6.0 the echo function will properly support unicode + output on the windows console. Not that click does not modify + the interpreter in any way which means that `sys.stdout` or the + print statement or function will still not provide unicode support. + + .. versionchanged:: 2.0 + Starting with version 2.0 of Click, the echo function will work + with colorama if it's installed. + + .. versionadded:: 3.0 + The `err` parameter was added. + + .. versionchanged:: 4.0 + Added the `color` flag. + + :param message: the message to print + :param file: the file to write to (defaults to ``stdout``) + :param err: if set to true the file defaults to ``stderr`` instead of + ``stdout``. This is faster and easier than calling + :func:`get_text_stderr` yourself. + :param nl: if set to `True` (the default) a newline is printed afterwards. + :param color: controls if the terminal supports ANSI colors or not. The + default is autodetection. + """ + if file is None: + if err: + file = _default_text_stderr() + else: + file = _default_text_stdout() + + # Convert non bytes/text into the native string type. + if message is not None and not isinstance(message, echo_native_types): + message = text_type(message) + + if nl: + message = message or u'' + if isinstance(message, text_type): + message += u'\n' + else: + message += b'\n' + + # If there is a message, and we're in Python 3, and the value looks + # like bytes, we manually need to find the binary stream and write the + # message in there. This is done separately so that most stream + # types will work as you would expect. Eg: you can write to StringIO + # for other cases. + if message and not PY2 and is_bytes(message): + binary_file = _find_binary_writer(file) + if binary_file is not None: + file.flush() + binary_file.write(message) + binary_file.flush() + return + + # ANSI-style support. If there is no message or we are dealing with + # bytes nothing is happening. If we are connected to a file we want + # to strip colors. If we are on windows we either wrap the stream + # to strip the color or we use the colorama support to translate the + # ansi codes to API calls. + if message and not is_bytes(message): + color = resolve_color_default(color) + if should_strip_ansi(file, color): + message = strip_ansi(message) + elif WIN: + if auto_wrap_for_ansi is not None: + file = auto_wrap_for_ansi(file) + elif not color: + message = strip_ansi(message) + + if message: + file.write(message) + file.flush() + + +def get_binary_stream(name): + """Returns a system stream for byte processing. This essentially + returns the stream from the sys module with the given name but it + solves some compatibility issues between different Python versions. + Primarily this function is necessary for getting binary streams on + Python 3. + + :param name: the name of the stream to open. Valid names are ``'stdin'``, + ``'stdout'`` and ``'stderr'`` + """ + opener = binary_streams.get(name) + if opener is None: + raise TypeError('Unknown standard stream %r' % name) + return opener() + + +def get_text_stream(name, encoding=None, errors='strict'): + """Returns a system stream for text processing. This usually returns + a wrapped stream around a binary stream returned from + :func:`get_binary_stream` but it also can take shortcuts on Python 3 + for already correctly configured streams. + + :param name: the name of the stream to open. Valid names are ``'stdin'``, + ``'stdout'`` and ``'stderr'`` + :param encoding: overrides the detected default encoding. + :param errors: overrides the default error mode. + """ + opener = text_streams.get(name) + if opener is None: + raise TypeError('Unknown standard stream %r' % name) + return opener(encoding, errors) + + +def open_file(filename, mode='r', encoding=None, errors='strict', + lazy=False, atomic=False): + """This is similar to how the :class:`File` works but for manual + usage. Files are opened non lazy by default. This can open regular + files as well as stdin/stdout if ``'-'`` is passed. + + If stdin/stdout is returned the stream is wrapped so that the context + manager will not close the stream accidentally. This makes it possible + to always use the function like this without having to worry to + accidentally close a standard stream:: + + with open_file(filename) as f: + ... + + .. versionadded:: 3.0 + + :param filename: the name of the file to open (or ``'-'`` for stdin/stdout). + :param mode: the mode in which to open the file. + :param encoding: the encoding to use. + :param errors: the error handling for this file. + :param lazy: can be flipped to true to open the file lazily. + :param atomic: in atomic mode writes go into a temporary file and it's + moved on close. + """ + if lazy: + return LazyFile(filename, mode, encoding, errors, atomic=atomic) + f, should_close = open_stream(filename, mode, encoding, errors, + atomic=atomic) + if not should_close: + f = KeepOpenFile(f) + return f + + +def get_os_args(): + """This returns the argument part of sys.argv in the most appropriate + form for processing. What this means is that this return value is in + a format that works for Click to process but does not necessarily + correspond well to what's actually standard for the interpreter. + + On most environments the return value is ``sys.argv[:1]`` unchanged. + However if you are on Windows and running Python 2 the return value + will actually be a list of unicode strings instead because the + default behavior on that platform otherwise will not be able to + carry all possible values that sys.argv can have. + + .. versionadded:: 6.0 + """ + # We can only extract the unicode argv if sys.argv has not been + # changed since the startup of the application. + if PY2 and WIN and _initial_argv_hash == _hash_py_argv(): + return _get_windows_argv() + return sys.argv[1:] + + +def format_filename(filename, shorten=False): + """Formats a filename for user display. The main purpose of this + function is to ensure that the filename can be displayed at all. This + will decode the filename to unicode if necessary in a way that it will + not fail. Optionally, it can shorten the filename to not include the + full path to the filename. + + :param filename: formats a filename for UI display. This will also convert + the filename into unicode without failing. + :param shorten: this optionally shortens the filename to strip of the + path that leads up to it. + """ + if shorten: + filename = os.path.basename(filename) + return filename_to_ui(filename) + + +def get_app_dir(app_name, roaming=True, force_posix=False): + r"""Returns the config folder for the application. The default behavior + is to return whatever is most appropriate for the operating system. + + To give you an idea, for an app called ``"Foo Bar"``, something like + the following folders could be returned: + + Mac OS X: + ``~/Library/Application Support/Foo Bar`` + Mac OS X (POSIX): + ``~/.foo-bar`` + Unix: + ``~/.config/foo-bar`` + Unix (POSIX): + ``~/.foo-bar`` + Win XP (roaming): + ``C:\Documents and Settings\\Local Settings\Application Data\Foo Bar`` + Win XP (not roaming): + ``C:\Documents and Settings\\Application Data\Foo Bar`` + Win 7 (roaming): + ``C:\Users\\AppData\Roaming\Foo Bar`` + Win 7 (not roaming): + ``C:\Users\\AppData\Local\Foo Bar`` + + .. versionadded:: 2.0 + + :param app_name: the application name. This should be properly capitalized + and can contain whitespace. + :param roaming: controls if the folder should be roaming or not on Windows. + Has no affect otherwise. + :param force_posix: if this is set to `True` then on any POSIX system the + folder will be stored in the home folder with a leading + dot instead of the XDG config home or darwin's + application support folder. + """ + if WIN: + key = roaming and 'APPDATA' or 'LOCALAPPDATA' + folder = os.environ.get(key) + if folder is None: + folder = os.path.expanduser('~') + return os.path.join(folder, app_name) + if force_posix: + return os.path.join(os.path.expanduser('~/.' + _posixify(app_name))) + if sys.platform == 'darwin': + return os.path.join(os.path.expanduser( + '~/Library/Application Support'), app_name) + return os.path.join( + os.environ.get('XDG_CONFIG_HOME', os.path.expanduser('~/.config')), + _posixify(app_name)) + + +class PacifyFlushWrapper(object): + """This wrapper is used to catch and suppress BrokenPipeErrors resulting + from ``.flush()`` being called on broken pipe during the shutdown/final-GC + of the Python interpreter. Notably ``.flush()`` is always called on + ``sys.stdout`` and ``sys.stderr``. So as to have minimal impact on any + other cleanup code, and the case where the underlying file is not a broken + pipe, all calls and attributes are proxied. + """ + + def __init__(self, wrapped): + self.wrapped = wrapped + + def flush(self): + try: + self.wrapped.flush() + except IOError as e: + import errno + if e.errno != errno.EPIPE: + raise + + def __getattr__(self, attr): + return getattr(self.wrapped, attr) diff --git a/flask/venv/lib/python3.6/site-packages/easy_install.py b/flask/venv/lib/python3.6/site-packages/easy_install.py new file mode 100644 index 0000000..d87e984 --- /dev/null +++ b/flask/venv/lib/python3.6/site-packages/easy_install.py @@ -0,0 +1,5 @@ +"""Run the EasyInstall command""" + +if __name__ == '__main__': + from setuptools.command.easy_install import main + main() diff --git a/flask/venv/lib/python3.6/site-packages/flask/__init__.py b/flask/venv/lib/python3.6/site-packages/flask/__init__.py new file mode 100644 index 0000000..ded1982 --- /dev/null +++ b/flask/venv/lib/python3.6/site-packages/flask/__init__.py @@ -0,0 +1,49 @@ +# -*- coding: utf-8 -*- +""" + flask + ~~~~~ + + A microframework based on Werkzeug. It's extensively documented + and follows best practice patterns. + + :copyright: © 2010 by the Pallets team. + :license: BSD, see LICENSE for more details. +""" + +__version__ = '1.0.2' + +# utilities we import from Werkzeug and Jinja2 that are unused +# in the module but are exported as public interface. +from werkzeug.exceptions import abort +from werkzeug.utils import redirect +from jinja2 import Markup, escape + +from .app import Flask, Request, Response +from .config import Config +from .helpers import url_for, flash, send_file, send_from_directory, \ + get_flashed_messages, get_template_attribute, make_response, safe_join, \ + stream_with_context +from .globals import current_app, g, request, session, _request_ctx_stack, \ + _app_ctx_stack +from .ctx import has_request_context, has_app_context, \ + after_this_request, copy_current_request_context +from .blueprints import Blueprint +from .templating import render_template, render_template_string + +# the signals +from .signals import signals_available, template_rendered, request_started, \ + request_finished, got_request_exception, request_tearing_down, \ + appcontext_tearing_down, appcontext_pushed, \ + appcontext_popped, message_flashed, before_render_template + +# We're not exposing the actual json module but a convenient wrapper around +# it. +from . import json + +# This was the only thing that Flask used to export at one point and it had +# a more generic name. +jsonify = json.jsonify + +# backwards compat, goes away in 1.0 +from .sessions import SecureCookieSession as Session +json_available = True diff --git a/flask/venv/lib/python3.6/site-packages/flask/__main__.py b/flask/venv/lib/python3.6/site-packages/flask/__main__.py new file mode 100644 index 0000000..4aee654 --- /dev/null +++ b/flask/venv/lib/python3.6/site-packages/flask/__main__.py @@ -0,0 +1,14 @@ +# -*- coding: utf-8 -*- +""" + flask.__main__ + ~~~~~~~~~~~~~~ + + Alias for flask.run for the command line. + + :copyright: © 2010 by the Pallets team. + :license: BSD, see LICENSE for more details. +""" + +if __name__ == '__main__': + from .cli import main + main(as_module=True) diff --git a/flask/venv/lib/python3.6/site-packages/flask/__pycache__/__init__.cpython-36.pyc b/flask/venv/lib/python3.6/site-packages/flask/__pycache__/__init__.cpython-36.pyc new file mode 100644 index 0000000000000000000000000000000000000000..42241f13076effb51a898b44cf925f9d3d9d81a0 GIT binary patch literal 1844 zcmZ8h%Wm676s4Y&C0VvCzY;si z@*2G+uhZ-D2ECEp*94I_=}mcy-jcWJZFz^@$@sdsEAP>JnY<|O%Lnv*`;0CqdnQDeYr>XkoCtehgVJt*^s>y(BLlWirCiFQ;JY%?u zbmt=4ksl}LDjbc?5&82y+3WRtWN=Q*n3JD8A-K`Ra8GtJuSWtrM4BIw=f~ge5Y0LH z;nj$G#W3eL9b>Hw`Q%K%c-f*475EvdWzlft@IBG9gH&uc`TwB6Ej_rcx zQNV_w;I?%ks#vm%Sg|^{t0Qh$X37I5xz^r@YrBrD;W81P;S8Fi!a-`dU6kIGGc^kg z&b=XLlQ@jPxlzy(b{d*7^JD1wnQ518%}xwGyh=4+zW^^BMe8%CpUpcz5doo$7>iPSBG+X#0M?jqbnxR3Avp^fkm;Sqp!)DHYn z7n>gr&uwM)nrO9)*Y0cpw1Ea6SMR-}4$%j~zkV0i`2=3v?unDWAFxefXp$K;S2V=kAKM~#RYdk~7U}p_uodgnl oCgUI#{A-+oCIH2Ju~^U5bIbWvz?}lgZ{|TO9Juvjxlqsj2a>@&J^%m! literal 0 HcmV?d00001 diff --git a/flask/venv/lib/python3.6/site-packages/flask/__pycache__/__main__.cpython-36.pyc b/flask/venv/lib/python3.6/site-packages/flask/__pycache__/__main__.cpython-36.pyc new file mode 100644 index 0000000000000000000000000000000000000000..685b0e6d4d93b1047749e7bd0cfe7414e5fca815 GIT binary patch literal 471 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 G%YOrupZXL4 literal 0 HcmV?d00001 diff --git a/flask/venv/lib/python3.6/site-packages/flask/__pycache__/blueprints.cpython-36.pyc b/flask/venv/lib/python3.6/site-packages/flask/__pycache__/blueprints.cpython-36.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a259514928731c81458d6f115b0985b931446588 GIT binary patch literal 20507 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 literal 0 HcmV?d00001 diff --git a/flask/venv/lib/python3.6/site-packages/flask/__pycache__/cli.cpython-36.pyc b/flask/venv/lib/python3.6/site-packages/flask/__pycache__/cli.cpython-36.pyc new file mode 100644 index 0000000000000000000000000000000000000000..0f24697683bcb9f3b2fcaefbf5b76af730719396 GIT binary patch literal 24884 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 literal 0 HcmV?d00001 diff --git a/flask/venv/lib/python3.6/site-packages/flask/__pycache__/globals.cpython-36.pyc b/flask/venv/lib/python3.6/site-packages/flask/__pycache__/globals.cpython-36.pyc new file mode 100644 index 0000000000000000000000000000000000000000..44557849ff2394ce52abce1eace0f969c05e4ed9 GIT binary patch literal 1771 zcmb_d&5qkP5SC>5PrLSR(x8W;2ezjgXk@!dTVPQXMK=pHK(JWU1_}rT1X>*1T2rDz zQr>m2?IG^V{FugEuli^0Q{t#I+x_STky~7Hj|JL><;)T^zeCUK?CQv_x~y+k$Lwh0435jU2qYlb=A5ckxZq+& zxw4vH_gi39&tRVBpa|uh=p~SyIT5o00T`^uEO9ijL#XkRlA^4r<4!8DtI9h$|ss8t9pKca5t~s{v_lo z%@;(JTBQt#m=g&vOHg_b?sSI+V`_$mawL1dBDe&*g2Y z?6DXoNRn+H$_DmR?24e!&ZYZ{d*d=^)sY`+PdB#iYghX>?v1nc@F=2`4T&EeFNhxIY=$;u!8E0xywHH{lT1zZZKc^W;ygi&Zjy%BO@7b`B z>6&U7uBjZ(1!o}DaQt+r=6X54WbCWrdi3Sje0-VbDtJFtm!e!LJ4F~RfF?D0SCYcFkgqHWAJU~s=uFIrqD^LoLcI7V4 z2M?-t9AlNnan-f=h7epy12yVjfn2?UauITKc}Y{7()^o9lN<}kW=5JwrP)I^jWEEY zgZjJ~K=Pqce_+HTBktI=GfQdbn@q5h!?#AIK0@JphwgFL@A!>Q8=p?gRzu(IyZ-=k CO!2k= literal 0 HcmV?d00001 diff --git a/flask/venv/lib/python3.6/site-packages/flask/__pycache__/helpers.cpython-36.pyc b/flask/venv/lib/python3.6/site-packages/flask/__pycache__/helpers.cpython-36.pyc new file mode 100644 index 0000000000000000000000000000000000000000..3035fef115729c416b9940268bc31b1784aa2e82 GIT binary patch literal 33079 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

^RZ6B zeTl=hOa~N}i7L_?-z`PE%s`$@QyW4Ev8A1>slRw#qm_<1{yGCV5cGF~f$>FdK(7}d zf|vdWRFGQmQ%NT6fDbHQBZ3^+#k2qBGvl1k3(olUTw? z4dtRyJvuh@oOyr19{oBmKjej`wer*aYu^1KE@9p{D}{%7f5aDmj7#N^W>m&lQhbko z9Pi)p@>O2`Jum-}mq|{ae}NYp9L!U=$)_{?mnu%@Gt4H13o3FLjLH#fXJ0`OWLG$h`VL*9%O_ zly`1#4v{1{U>N_R#~b-;>7A+Jk45riwKo!XUcggEwsM;(WYwPDPwvg*8{D_3iG%=T zz8#NhHdWr+mlAKkh(jj;^X(V$3l@~=8T(OqBQEi*;#OlAYf{=S_&!%9)*%+zm21eh zk^^$}Jm|Ch&N3zGCU`BCR^|fmw@pE){LM|6!~lw|cR{DkA8$ZPz7o?|u!30Z1IBqn zfPL$nfeyU^(0oPVmvzc;yhi^=QKf$5HJF8MfTw9_vrt~e6LvC07ND79wSpA z^yF_~XQMp8&*KK`mrDhY1fV#_KgJynx?~(82n#YsFuS(*Dxc>rT&`YOTU`(H`sNv3 zglGUqqH_wTtk_83+Z!Vs?i8pty8nly!&RD?nL`Q>)4u27jyZz+dAZA{y#J23rQ|wv z9iBH<%B@{qTgP8%Rk?UAJoNrEFA{e8F7Lj@OTY_BFwFE3#**ZE{F=7J2{7B@viI)b zePupMoTZzD@96YJ9y^slZu^wqX{*de#lU`i*=kU^KYGSY_eg*6)i#C#p&yNk4AXKw zDp)E*iV2`G(6{}qhU`YDWW@qM>(SD$S8Qu$%O#JAt)<+pfYEKL0B!b62c$fU+dLKrm}N|-+nS%gC%pC^Xo zC^(h-PobkS`*lV?^7fhcbqsm=ygQLPhTr6SG?UNg=Zc5&h5XC;Gx@J1j^*z!J~Fp} f<7AS>uOvR3Kbc?1m-F}MpPheb{ws;u{Ph0^$(`V9 literal 0 HcmV?d00001 diff --git a/flask/venv/lib/python3.6/site-packages/flask/__pycache__/logging.cpython-36.pyc b/flask/venv/lib/python3.6/site-packages/flask/__pycache__/logging.cpython-36.pyc new file mode 100644 index 0000000000000000000000000000000000000000..93272027e6f4fb7aaa370edd3251e7367620b677 GIT binary patch literal 2400 zcmZuz-EP}96ei_=#ZG^)Zr#;5U`1jewd1zy03is5Hc49`=n5oV0dIvxi|VFK>MQhWhm`Cl>jao0sl)U0o$nm_ZmVVg{bc_0pLK-( zK^LA9%)f`96fiKTl5;_ZzIi?6;_I^U`>QH(;m9o8uO&R@urN&oP{AvKB~OVWk7qUQHDkw*838qfV3r zK^O=2n~RTaJ6CJM88m`-w-RXCgVB zy~nv&P4HJKm&((}7LNs!hwzi1!Jv>>RcMSE{t_J^WsP-w7X2L*?1eEi{!S992%Szv zG8G|JoNyt)GpPgwV4T!ZfdE88RhYyb^28^U6vk}=PbdlXRCvrc2mnS@LR|Mm24TnO zlCHZ!63`+}Ldi)AKi8Er*^!EYfa`W_qXpE?l9YH!?1w=Lz`#n775 zz8dw$jNPA}Zhre+)EmdK9NgU;ZNd}8-NWuQoZcR$VZ?6t?v1=&?>NeREye}j(^+=? zQ?E6{q~;s4#R`m`=B0l0UKxJ6lI0Ez=V*-P=r?%3#;14AvDjAl7vuvknf11Qj>pyx zRO%dyj;=shm*o9t`dxmFU#-4CtPH%Zoc-}|#JwXD`Z}MGK219^%2`0d*krkInRp{= zcBmpJVH6c&TErk709j*A)_{vONt_8+Bgf^w4@rejB;vJ(}tR^U`M2Pms~snA=-qlI_cvFzF>E_|&Wybc2@*KygZ;+tl)EZY)a z!0y@opKh&F2{2E1TfQW>)=dO4)k~elTkDgAr4g(gJ?B!=02Y@JUUs={(3p3)IR=!` z*b?iSKd@Im%I6iBS9OZQEI`(2+HOoBO7`vWfxA zkUy(F{o(Ln_b{tNxTe&yiUGrrD6=7g$9d&vR~Ywc8mUDQw5@(gUuZXg8y~x*Fnn!! zaIL|`nnSY%5>l5MvTf@+Zd!E=EG4jRU(ITR0ZY8WAhQPpKUHuc4F*CJPw281H5mG< zCtMtz@ic%x3Q%`KSAJFtqGSj~Xxg{wjJeOPOVEn1v}_Zi+cOv`F0#gQYMi*>ylM6( gg8Eio9^3H03CYi4C|la`I*iRyvsJ%gV_22{1s|fguK)l5 literal 0 HcmV?d00001 diff --git a/flask/venv/lib/python3.6/site-packages/flask/__pycache__/sessions.cpython-36.pyc b/flask/venv/lib/python3.6/site-packages/flask/__pycache__/sessions.cpython-36.pyc new file mode 100644 index 0000000000000000000000000000000000000000..bafa85156fc11a5a884e016b0d73951aafaa7afd GIT binary patch literal 12247 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 Z1=Jzl6@3&}Ze0HTmF1N`E4*JW{vWL$Et>!U literal 0 HcmV?d00001 diff --git a/flask/venv/lib/python3.6/site-packages/flask/__pycache__/signals.cpython-36.pyc b/flask/venv/lib/python3.6/site-packages/flask/__pycache__/signals.cpython-36.pyc new file mode 100644 index 0000000000000000000000000000000000000000..4d2e5e1b1d90f1d2890173c97ff5d8c353154fd0 GIT binary patch literal 2432 zcmZuy&5qkP5SC=w)_T3a*`&D?;GvfVvi7=3TVN3cLGx2AP;7#3fVOG@f);68yRxK^ z^loefJ#_OXJ>@NmzCiD~_R_vWPyI+qjvbT+=^;5B4!`+kbbo8B^XKW!&%XtZ^Ov*I zHX%PoSHEN6PUvtqbms@$?|c>qjT`esDzN#tGY^eG%}D8#mmrQU_AUN}G^2t<;6owbB-(Eh}w9+P2aT zq#Y~mLfW;`9;7`h?L*qc?nArb2Nd8WRA1ZCD9pSB+atC zSKe_FW%*pjUEy~gU33DZn1I3rb6W`60ah&RJR6%$LQ(~2H}J*0_<_$ z1oxdAHn@qx@Wj-lRjsc;@kpz*eHA@l2PHO z@Ste$EPC(AHctIJ?B_DRVp{aCnCy?TgbS(qg9m*z(v!gj=U?V;j=%US8C;~PqW6y{ z$7tiU|EizI`O$C|C;VveU=j@mS4rOnvl^>F_40YqD&h03|^1X)l&>hoDISo zyup27?U%_CHp?Ulku*LM13f_BK<}V$hTWf<+#ubN#wOc$9p`lPfr^UE(iJjBQUGAW z$OsW35g4z?b*v|rTng{CoHE%Er&`Dn2!bu933!)XgSaB)aXKd1=mY&{8YYqiCgY?u z#?qx3AthLd- z$J{Q;mXQo!%fW=(a3xM-P3fnYDWmJSEq8IS!uwvW5+OjgnQ$3TUZATk28~L3NH1*kQ8=oKz2yvys4 zuLvF{Y&zuZ(PucJ(4BSU>TQ#kThbI5X}&?yU?#WBux$pDZ>F}Syl6*Rnu0K?RK$*!nnbYc+;8bT}cXhVnzvY3=coR)iGi@Y;rtftc zfggBxU7MDRJ!3jS>K#cqD5T(vJ3|2<>V>0PVX-5{>zPpc2yv4dio5l~2qaSztQ^!U z$RG)N9P#WrUECgL8s^Kx;!PxS9cSs{6PD+2UyC;ym#paTt!(5oYj|xb%X8edgYSf5 zV{v3EDlR`eyk$WT_o}i=m*pjFR~)qUuGqx45}dVMD_Ys`0uixjgaNJ2+6o#j!9jRR zaKZ|lYJt|^gf%#{0w=7&p*1*R4Gs?3$0CQX)6jqeYZe^31SebpXI*~<30i^^t}R(` r!WtY}f%AXVD1wLO=i`xKtuiF{J>T`*t{b@9?yi65cB|QOKmPp(GjE(b literal 0 HcmV?d00001 diff --git a/flask/venv/lib/python3.6/site-packages/flask/__pycache__/templating.cpython-36.pyc b/flask/venv/lib/python3.6/site-packages/flask/__pycache__/templating.cpython-36.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a54ec0b2ce3102f1ddecca139a21dc4584f57ce4 GIT binary patch literal 4981 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 EzcjJGtpET3 literal 0 HcmV?d00001 diff --git a/flask/venv/lib/python3.6/site-packages/flask/__pycache__/views.cpython-36.pyc b/flask/venv/lib/python3.6/site-packages/flask/__pycache__/views.cpython-36.pyc new file mode 100644 index 0000000000000000000000000000000000000000..35f458aecb26b8597e171f580455b9185dc00975 GIT binary patch literal 4789 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 PL6UQ8_M*GgTDtTjbFn{H literal 0 HcmV?d00001 diff --git a/flask/venv/lib/python3.6/site-packages/flask/__pycache__/wrappers.cpython-36.pyc b/flask/venv/lib/python3.6/site-packages/flask/__pycache__/wrappers.cpython-36.pyc new file mode 100644 index 0000000000000000000000000000000000000000..96d528e3715f213000efaa329c46cc10599722df GIT binary patch literal 6790 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 literal 0 HcmV?d00001 diff --git a/flask/venv/lib/python3.6/site-packages/flask/_compat.py b/flask/venv/lib/python3.6/site-packages/flask/_compat.py new file mode 100644 index 0000000..a3b5b9c --- /dev/null +++ b/flask/venv/lib/python3.6/site-packages/flask/_compat.py @@ -0,0 +1,99 @@ +# -*- coding: utf-8 -*- +""" + flask._compat + ~~~~~~~~~~~~~ + + Some py2/py3 compatibility support based on a stripped down + version of six so we don't have to depend on a specific version + of it. + + :copyright: © 2010 by the Pallets team. + :license: BSD, see LICENSE for more details. +""" + +import sys + +PY2 = sys.version_info[0] == 2 +_identity = lambda x: x + + +if not PY2: + text_type = str + string_types = (str,) + integer_types = (int,) + + iterkeys = lambda d: iter(d.keys()) + itervalues = lambda d: iter(d.values()) + iteritems = lambda d: iter(d.items()) + + from inspect import getfullargspec as getargspec + from io import StringIO + + def reraise(tp, value, tb=None): + if value.__traceback__ is not tb: + raise value.with_traceback(tb) + raise value + + implements_to_string = _identity + +else: + text_type = unicode + string_types = (str, unicode) + integer_types = (int, long) + + iterkeys = lambda d: d.iterkeys() + itervalues = lambda d: d.itervalues() + iteritems = lambda d: d.iteritems() + + from inspect import getargspec + from cStringIO import StringIO + + exec('def reraise(tp, value, tb=None):\n raise tp, value, tb') + + def implements_to_string(cls): + cls.__unicode__ = cls.__str__ + cls.__str__ = lambda x: x.__unicode__().encode('utf-8') + return cls + + +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) + return type.__new__(metaclass, 'temporary_class', (), {}) + + +# Certain versions of pypy have a bug where clearing the exception stack +# breaks the __exit__ function in a very peculiar way. The second level of +# exception blocks is necessary because pypy seems to forget to check if an +# exception happened until the next bytecode instruction? +# +# Relevant PyPy bugfix commit: +# https://bitbucket.org/pypy/pypy/commits/77ecf91c635a287e88e60d8ddb0f4e9df4003301 +# According to ronan on #pypy IRC, it is released in PyPy2 2.3 and later +# versions. +# +# Ubuntu 14.04 has PyPy 2.2.1, which does exhibit this bug. +BROKEN_PYPY_CTXMGR_EXIT = False +if hasattr(sys, 'pypy_version_info'): + class _Mgr(object): + def __enter__(self): + return self + def __exit__(self, *args): + if hasattr(sys, 'exc_clear'): + # Python 3 (PyPy3) doesn't have exc_clear + sys.exc_clear() + try: + try: + with _Mgr(): + raise AssertionError() + except: + raise + except TypeError: + BROKEN_PYPY_CTXMGR_EXIT = True + except AssertionError: + pass diff --git a/flask/venv/lib/python3.6/site-packages/flask/app.py b/flask/venv/lib/python3.6/site-packages/flask/app.py new file mode 100644 index 0000000..87c5900 --- /dev/null +++ b/flask/venv/lib/python3.6/site-packages/flask/app.py @@ -0,0 +1,2315 @@ +# -*- coding: utf-8 -*- +""" + flask.app + ~~~~~~~~~ + + This module implements the central WSGI application object. + + :copyright: © 2010 by the Pallets team. + :license: BSD, see LICENSE for more details. +""" + +import os +import sys +import warnings +from datetime import timedelta +from functools import update_wrapper +from itertools import chain +from threading import Lock + +from werkzeug.datastructures import Headers, ImmutableDict +from werkzeug.exceptions import BadRequest, BadRequestKeyError, HTTPException, \ + InternalServerError, MethodNotAllowed, default_exceptions +from werkzeug.routing import BuildError, Map, RequestRedirect, Rule + +from . import cli, json +from ._compat import integer_types, reraise, string_types, text_type +from .config import Config, ConfigAttribute +from .ctx import AppContext, RequestContext, _AppCtxGlobals +from .globals import _request_ctx_stack, g, request, session +from .helpers import ( + _PackageBoundObject, + _endpoint_from_view_func, find_package, get_env, get_debug_flag, + get_flashed_messages, locked_cached_property, url_for, get_load_dotenv +) +from .logging import create_logger +from .sessions import SecureCookieSessionInterface +from .signals import appcontext_tearing_down, got_request_exception, \ + request_finished, request_started, request_tearing_down +from .templating import DispatchingJinjaLoader, Environment, \ + _default_template_ctx_processor +from .wrappers import Request, Response + +# a singleton sentinel value for parameter defaults +_sentinel = object() + + +def _make_timedelta(value): + if not isinstance(value, timedelta): + return timedelta(seconds=value) + return value + + +def setupmethod(f): + """Wraps a method so that it performs a check in debug mode if the + first request was already handled. + """ + def wrapper_func(self, *args, **kwargs): + if self.debug and self._got_first_request: + raise AssertionError('A setup function was called after the ' + 'first request was handled. This usually indicates a bug ' + 'in the application where a module was not imported ' + 'and decorators or other functionality was called too late.\n' + 'To fix this make sure to import all your view modules, ' + 'database models and everything related at a central place ' + 'before the application starts serving requests.') + return f(self, *args, **kwargs) + return update_wrapper(wrapper_func, f) + + +class Flask(_PackageBoundObject): + """The flask object implements a WSGI application and acts as the central + object. It is passed the name of the module or package of the + application. Once it is created it will act as a central registry for + the view functions, the URL rules, template configuration and much more. + + The name of the package is used to resolve resources from inside the + package or the folder the module is contained in depending on if the + package parameter resolves to an actual python package (a folder with + an :file:`__init__.py` file inside) or a standard module (just a ``.py`` file). + + For more information about resource loading, see :func:`open_resource`. + + Usually you create a :class:`Flask` instance in your main module or + in the :file:`__init__.py` file of your package like this:: + + from flask import Flask + app = Flask(__name__) + + .. admonition:: About the First Parameter + + The idea of the first parameter is to give Flask an idea of what + belongs to your application. This name is used to find resources + on the filesystem, can be used by extensions to improve debugging + information and a lot more. + + So it's important what you provide there. If you are using a single + module, `__name__` is always the correct value. If you however are + using a package, it's usually recommended to hardcode the name of + your package there. + + For example if your application is defined in :file:`yourapplication/app.py` + you should create it with one of the two versions below:: + + app = Flask('yourapplication') + app = Flask(__name__.split('.')[0]) + + Why is that? The application will work even with `__name__`, thanks + to how resources are looked up. However it will make debugging more + painful. Certain extensions can make assumptions based on the + import name of your application. For example the Flask-SQLAlchemy + extension will look for the code in your application that triggered + an SQL query in debug mode. If the import name is not properly set + up, that debugging information is lost. (For example it would only + pick up SQL queries in `yourapplication.app` and not + `yourapplication.views.frontend`) + + .. versionadded:: 0.7 + The `static_url_path`, `static_folder`, and `template_folder` + parameters were added. + + .. versionadded:: 0.8 + The `instance_path` and `instance_relative_config` parameters were + added. + + .. versionadded:: 0.11 + The `root_path` parameter was added. + + .. versionadded:: 1.0 + The ``host_matching`` and ``static_host`` parameters were added. + + .. versionadded:: 1.0 + The ``subdomain_matching`` parameter was added. Subdomain + matching needs to be enabled manually now. Setting + :data:`SERVER_NAME` does not implicitly enable it. + + :param import_name: the name of the application package + :param static_url_path: can be used to specify a different path for the + static files on the web. Defaults to the name + of the `static_folder` folder. + :param static_folder: the folder with static files that should be served + at `static_url_path`. Defaults to the ``'static'`` + folder in the root path of the application. + :param static_host: the host to use when adding the static route. + Defaults to None. Required when using ``host_matching=True`` + with a ``static_folder`` configured. + :param host_matching: set ``url_map.host_matching`` attribute. + Defaults to False. + :param subdomain_matching: consider the subdomain relative to + :data:`SERVER_NAME` when matching routes. Defaults to False. + :param template_folder: the folder that contains the templates that should + be used by the application. Defaults to + ``'templates'`` folder in the root path of the + application. + :param instance_path: An alternative instance path for the application. + By default the folder ``'instance'`` next to the + package or module is assumed to be the instance + path. + :param instance_relative_config: if set to ``True`` relative filenames + for loading the config are assumed to + be relative to the instance path instead + of the application root. + :param root_path: Flask by default will automatically calculate the path + to the root of the application. In certain situations + this cannot be achieved (for instance if the package + is a Python 3 namespace package) and needs to be + manually defined. + """ + + #: The class that is used for request objects. See :class:`~flask.Request` + #: for more information. + request_class = Request + + #: The class that is used for response objects. See + #: :class:`~flask.Response` for more information. + response_class = Response + + #: The class that is used for the Jinja environment. + #: + #: .. versionadded:: 0.11 + jinja_environment = Environment + + #: The class that is used for the :data:`~flask.g` instance. + #: + #: Example use cases for a custom class: + #: + #: 1. Store arbitrary attributes on flask.g. + #: 2. Add a property for lazy per-request database connectors. + #: 3. Return None instead of AttributeError on unexpected attributes. + #: 4. Raise exception if an unexpected attr is set, a "controlled" flask.g. + #: + #: In Flask 0.9 this property was called `request_globals_class` but it + #: was changed in 0.10 to :attr:`app_ctx_globals_class` because the + #: flask.g object is now application context scoped. + #: + #: .. versionadded:: 0.10 + app_ctx_globals_class = _AppCtxGlobals + + #: The class that is used for the ``config`` attribute of this app. + #: Defaults to :class:`~flask.Config`. + #: + #: Example use cases for a custom class: + #: + #: 1. Default values for certain config options. + #: 2. Access to config values through attributes in addition to keys. + #: + #: .. versionadded:: 0.11 + config_class = Config + + #: The testing flag. Set this to ``True`` to enable the test mode of + #: Flask extensions (and in the future probably also Flask itself). + #: For example this might activate test helpers that have an + #: additional runtime cost which should not be enabled by default. + #: + #: If this is enabled and PROPAGATE_EXCEPTIONS is not changed from the + #: default it's implicitly enabled. + #: + #: This attribute can also be configured from the config with the + #: ``TESTING`` configuration key. Defaults to ``False``. + testing = ConfigAttribute('TESTING') + + #: If a secret key is set, cryptographic components can use this to + #: sign cookies and other things. Set this to a complex random value + #: when you want to use the secure cookie for instance. + #: + #: This attribute can also be configured from the config with the + #: :data:`SECRET_KEY` configuration key. Defaults to ``None``. + secret_key = ConfigAttribute('SECRET_KEY') + + #: The secure cookie uses this for the name of the session cookie. + #: + #: This attribute can also be configured from the config with the + #: ``SESSION_COOKIE_NAME`` configuration key. Defaults to ``'session'`` + session_cookie_name = ConfigAttribute('SESSION_COOKIE_NAME') + + #: A :class:`~datetime.timedelta` which is used to set the expiration + #: date of a permanent session. The default is 31 days which makes a + #: permanent session survive for roughly one month. + #: + #: This attribute can also be configured from the config with the + #: ``PERMANENT_SESSION_LIFETIME`` configuration key. Defaults to + #: ``timedelta(days=31)`` + permanent_session_lifetime = ConfigAttribute('PERMANENT_SESSION_LIFETIME', + get_converter=_make_timedelta) + + #: A :class:`~datetime.timedelta` which is used as default cache_timeout + #: for the :func:`send_file` functions. The default is 12 hours. + #: + #: This attribute can also be configured from the config with the + #: ``SEND_FILE_MAX_AGE_DEFAULT`` configuration key. This configuration + #: variable can also be set with an integer value used as seconds. + #: Defaults to ``timedelta(hours=12)`` + send_file_max_age_default = ConfigAttribute('SEND_FILE_MAX_AGE_DEFAULT', + get_converter=_make_timedelta) + + #: Enable this if you want to use the X-Sendfile feature. Keep in + #: mind that the server has to support this. This only affects files + #: sent with the :func:`send_file` method. + #: + #: .. versionadded:: 0.2 + #: + #: This attribute can also be configured from the config with the + #: ``USE_X_SENDFILE`` configuration key. Defaults to ``False``. + use_x_sendfile = ConfigAttribute('USE_X_SENDFILE') + + #: The JSON encoder class to use. Defaults to :class:`~flask.json.JSONEncoder`. + #: + #: .. versionadded:: 0.10 + json_encoder = json.JSONEncoder + + #: The JSON decoder class to use. Defaults to :class:`~flask.json.JSONDecoder`. + #: + #: .. versionadded:: 0.10 + json_decoder = json.JSONDecoder + + #: Options that are passed directly to the Jinja2 environment. + jinja_options = ImmutableDict( + extensions=['jinja2.ext.autoescape', 'jinja2.ext.with_'] + ) + + #: Default configuration parameters. + default_config = ImmutableDict({ + 'ENV': None, + 'DEBUG': None, + 'TESTING': False, + 'PROPAGATE_EXCEPTIONS': None, + 'PRESERVE_CONTEXT_ON_EXCEPTION': None, + 'SECRET_KEY': None, + 'PERMANENT_SESSION_LIFETIME': timedelta(days=31), + 'USE_X_SENDFILE': False, + 'SERVER_NAME': None, + 'APPLICATION_ROOT': '/', + 'SESSION_COOKIE_NAME': 'session', + 'SESSION_COOKIE_DOMAIN': None, + 'SESSION_COOKIE_PATH': None, + 'SESSION_COOKIE_HTTPONLY': True, + 'SESSION_COOKIE_SECURE': False, + 'SESSION_COOKIE_SAMESITE': None, + 'SESSION_REFRESH_EACH_REQUEST': True, + 'MAX_CONTENT_LENGTH': None, + 'SEND_FILE_MAX_AGE_DEFAULT': timedelta(hours=12), + 'TRAP_BAD_REQUEST_ERRORS': None, + 'TRAP_HTTP_EXCEPTIONS': False, + 'EXPLAIN_TEMPLATE_LOADING': False, + 'PREFERRED_URL_SCHEME': 'http', + 'JSON_AS_ASCII': True, + 'JSON_SORT_KEYS': True, + 'JSONIFY_PRETTYPRINT_REGULAR': False, + 'JSONIFY_MIMETYPE': 'application/json', + 'TEMPLATES_AUTO_RELOAD': None, + 'MAX_COOKIE_SIZE': 4093, + }) + + #: The rule object to use for URL rules created. This is used by + #: :meth:`add_url_rule`. Defaults to :class:`werkzeug.routing.Rule`. + #: + #: .. versionadded:: 0.7 + url_rule_class = Rule + + #: the test client that is used with when `test_client` is used. + #: + #: .. versionadded:: 0.7 + test_client_class = None + + #: The :class:`~click.testing.CliRunner` subclass, by default + #: :class:`~flask.testing.FlaskCliRunner` that is used by + #: :meth:`test_cli_runner`. Its ``__init__`` method should take a + #: Flask app object as the first argument. + #: + #: .. versionadded:: 1.0 + test_cli_runner_class = None + + #: the session interface to use. By default an instance of + #: :class:`~flask.sessions.SecureCookieSessionInterface` is used here. + #: + #: .. versionadded:: 0.8 + session_interface = SecureCookieSessionInterface() + + # TODO remove the next three attrs when Sphinx :inherited-members: works + # https://github.com/sphinx-doc/sphinx/issues/741 + + #: The name of the package or module that this app belongs to. Do not + #: change this once it is set by the constructor. + import_name = None + + #: Location of the template files to be added to the template lookup. + #: ``None`` if templates should not be added. + template_folder = None + + #: Absolute path to the package on the filesystem. Used to look up + #: resources contained in the package. + root_path = None + + def __init__( + self, + import_name, + static_url_path=None, + static_folder='static', + static_host=None, + host_matching=False, + subdomain_matching=False, + template_folder='templates', + instance_path=None, + instance_relative_config=False, + root_path=None + ): + _PackageBoundObject.__init__( + self, + import_name, + template_folder=template_folder, + root_path=root_path + ) + + if static_url_path is not None: + self.static_url_path = static_url_path + + if static_folder is not None: + self.static_folder = static_folder + + if instance_path is None: + instance_path = self.auto_find_instance_path() + elif not os.path.isabs(instance_path): + raise ValueError( + 'If an instance path is provided it must be absolute.' + ' A relative path was given instead.' + ) + + #: Holds the path to the instance folder. + #: + #: .. versionadded:: 0.8 + self.instance_path = instance_path + + #: The configuration dictionary as :class:`Config`. This behaves + #: exactly like a regular dictionary but supports additional methods + #: to load a config from files. + self.config = self.make_config(instance_relative_config) + + #: A dictionary of all view functions registered. The keys will + #: be function names which are also used to generate URLs and + #: the values are the function objects themselves. + #: To register a view function, use the :meth:`route` decorator. + self.view_functions = {} + + #: A dictionary of all registered error handlers. The key is ``None`` + #: for error handlers active on the application, otherwise the key is + #: the name of the blueprint. Each key points to another dictionary + #: where the key is the status code of the http exception. The + #: special key ``None`` points to a list of tuples where the first item + #: is the class for the instance check and the second the error handler + #: function. + #: + #: To register an error handler, use the :meth:`errorhandler` + #: decorator. + self.error_handler_spec = {} + + #: A list of functions that are called when :meth:`url_for` raises a + #: :exc:`~werkzeug.routing.BuildError`. Each function registered here + #: is called with `error`, `endpoint` and `values`. If a function + #: returns ``None`` or raises a :exc:`BuildError` the next function is + #: tried. + #: + #: .. versionadded:: 0.9 + self.url_build_error_handlers = [] + + #: A dictionary with lists of functions that will be called at the + #: beginning of each request. The key of the dictionary is the name of + #: the blueprint this function is active for, or ``None`` for all + #: requests. To register a function, use the :meth:`before_request` + #: decorator. + self.before_request_funcs = {} + + #: A list of functions that will be called at the beginning of the + #: first request to this instance. To register a function, use the + #: :meth:`before_first_request` decorator. + #: + #: .. versionadded:: 0.8 + self.before_first_request_funcs = [] + + #: A dictionary with lists of functions that should be called after + #: each request. The key of the dictionary is the name of the blueprint + #: this function is active for, ``None`` for all requests. This can for + #: example be used to close database connections. To register a function + #: here, use the :meth:`after_request` decorator. + self.after_request_funcs = {} + + #: A dictionary with lists of functions that are called after + #: each request, even if an exception has occurred. The key of the + #: dictionary is the name of the blueprint this function is active for, + #: ``None`` for all requests. These functions are not allowed to modify + #: the request, and their return values are ignored. If an exception + #: occurred while processing the request, it gets passed to each + #: teardown_request function. To register a function here, use the + #: :meth:`teardown_request` decorator. + #: + #: .. versionadded:: 0.7 + self.teardown_request_funcs = {} + + #: A list of functions that are called when the application context + #: is destroyed. Since the application context is also torn down + #: if the request ends this is the place to store code that disconnects + #: from databases. + #: + #: .. versionadded:: 0.9 + self.teardown_appcontext_funcs = [] + + #: A dictionary with lists of functions that are called before the + #: :attr:`before_request_funcs` functions. The key of the dictionary is + #: the name of the blueprint this function is active for, or ``None`` + #: for all requests. To register a function, use + #: :meth:`url_value_preprocessor`. + #: + #: .. versionadded:: 0.7 + self.url_value_preprocessors = {} + + #: A dictionary with lists of functions that can be used as URL value + #: preprocessors. The key ``None`` here is used for application wide + #: callbacks, otherwise the key is the name of the blueprint. + #: Each of these functions has the chance to modify the dictionary + #: of URL values before they are used as the keyword arguments of the + #: view function. For each function registered this one should also + #: provide a :meth:`url_defaults` function that adds the parameters + #: automatically again that were removed that way. + #: + #: .. versionadded:: 0.7 + self.url_default_functions = {} + + #: A dictionary with list of functions that are called without argument + #: to populate the template context. The key of the dictionary is the + #: name of the blueprint this function is active for, ``None`` for all + #: requests. Each returns a dictionary that the template context is + #: updated with. To register a function here, use the + #: :meth:`context_processor` decorator. + self.template_context_processors = { + None: [_default_template_ctx_processor] + } + + #: A list of shell context processor functions that should be run + #: when a shell context is created. + #: + #: .. versionadded:: 0.11 + self.shell_context_processors = [] + + #: all the attached blueprints in a dictionary by name. Blueprints + #: can be attached multiple times so this dictionary does not tell + #: you how often they got attached. + #: + #: .. versionadded:: 0.7 + self.blueprints = {} + self._blueprint_order = [] + + #: a place where extensions can store application specific state. For + #: example this is where an extension could store database engines and + #: similar things. For backwards compatibility extensions should register + #: themselves like this:: + #: + #: if not hasattr(app, 'extensions'): + #: app.extensions = {} + #: app.extensions['extensionname'] = SomeObject() + #: + #: The key must match the name of the extension module. For example in + #: case of a "Flask-Foo" extension in `flask_foo`, the key would be + #: ``'foo'``. + #: + #: .. versionadded:: 0.7 + self.extensions = {} + + #: The :class:`~werkzeug.routing.Map` for this instance. You can use + #: this to change the routing converters after the class was created + #: but before any routes are connected. Example:: + #: + #: from werkzeug.routing import BaseConverter + #: + #: class ListConverter(BaseConverter): + #: def to_python(self, value): + #: return value.split(',') + #: def to_url(self, values): + #: return ','.join(super(ListConverter, self).to_url(value) + #: for value in values) + #: + #: app = Flask(__name__) + #: app.url_map.converters['list'] = ListConverter + self.url_map = Map() + + self.url_map.host_matching = host_matching + self.subdomain_matching = subdomain_matching + + # tracks internally if the application already handled at least one + # request. + self._got_first_request = False + self._before_request_lock = Lock() + + # Add a static route using the provided static_url_path, static_host, + # and static_folder if there is a configured static_folder. + # Note we do this without checking if static_folder exists. + # For one, it might be created while the server is running (e.g. during + # development). Also, Google App Engine stores static files somewhere + if self.has_static_folder: + assert bool(static_host) == host_matching, 'Invalid static_host/host_matching combination' + self.add_url_rule( + self.static_url_path + '/', + endpoint='static', + host=static_host, + view_func=self.send_static_file + ) + + #: The click command line context for this application. Commands + #: registered here show up in the :command:`flask` command once the + #: application has been discovered. The default commands are + #: provided by Flask itself and can be overridden. + #: + #: This is an instance of a :class:`click.Group` object. + self.cli = cli.AppGroup(self.name) + + @locked_cached_property + def name(self): + """The name of the application. This is usually the import name + with the difference that it's guessed from the run file if the + import name is main. This name is used as a display name when + Flask needs the name of the application. It can be set and overridden + to change the value. + + .. versionadded:: 0.8 + """ + if self.import_name == '__main__': + fn = getattr(sys.modules['__main__'], '__file__', None) + if fn is None: + return '__main__' + return os.path.splitext(os.path.basename(fn))[0] + return self.import_name + + @property + def propagate_exceptions(self): + """Returns the value of the ``PROPAGATE_EXCEPTIONS`` configuration + value in case it's set, otherwise a sensible default is returned. + + .. versionadded:: 0.7 + """ + rv = self.config['PROPAGATE_EXCEPTIONS'] + if rv is not None: + return rv + return self.testing or self.debug + + @property + def preserve_context_on_exception(self): + """Returns the value of the ``PRESERVE_CONTEXT_ON_EXCEPTION`` + configuration value in case it's set, otherwise a sensible default + is returned. + + .. versionadded:: 0.7 + """ + rv = self.config['PRESERVE_CONTEXT_ON_EXCEPTION'] + if rv is not None: + return rv + return self.debug + + @locked_cached_property + def logger(self): + """The ``'flask.app'`` logger, a standard Python + :class:`~logging.Logger`. + + In debug mode, the logger's :attr:`~logging.Logger.level` will be set + to :data:`~logging.DEBUG`. + + If there are no handlers configured, a default handler will be added. + See :ref:`logging` for more information. + + .. versionchanged:: 1.0 + Behavior was simplified. The logger is always named + ``flask.app``. The level is only set during configuration, it + doesn't check ``app.debug`` each time. Only one format is used, + not different ones depending on ``app.debug``. No handlers are + removed, and a handler is only added if no handlers are already + configured. + + .. versionadded:: 0.3 + """ + return create_logger(self) + + @locked_cached_property + def jinja_env(self): + """The Jinja2 environment used to load templates.""" + return self.create_jinja_environment() + + @property + def got_first_request(self): + """This attribute is set to ``True`` if the application started + handling the first request. + + .. versionadded:: 0.8 + """ + return self._got_first_request + + def make_config(self, instance_relative=False): + """Used to create the config attribute by the Flask constructor. + The `instance_relative` parameter is passed in from the constructor + of Flask (there named `instance_relative_config`) and indicates if + the config should be relative to the instance path or the root path + of the application. + + .. versionadded:: 0.8 + """ + root_path = self.root_path + if instance_relative: + root_path = self.instance_path + defaults = dict(self.default_config) + defaults['ENV'] = get_env() + defaults['DEBUG'] = get_debug_flag() + return self.config_class(root_path, defaults) + + def auto_find_instance_path(self): + """Tries to locate the instance path if it was not provided to the + constructor of the application class. It will basically calculate + the path to a folder named ``instance`` next to your main file or + the package. + + .. versionadded:: 0.8 + """ + prefix, package_path = find_package(self.import_name) + if prefix is None: + return os.path.join(package_path, 'instance') + return os.path.join(prefix, 'var', self.name + '-instance') + + def open_instance_resource(self, resource, mode='rb'): + """Opens a resource from the application's instance folder + (:attr:`instance_path`). Otherwise works like + :meth:`open_resource`. Instance resources can also be opened for + writing. + + :param resource: the name of the resource. To access resources within + subfolders use forward slashes as separator. + :param mode: resource file opening mode, default is 'rb'. + """ + return open(os.path.join(self.instance_path, resource), mode) + + def _get_templates_auto_reload(self): + """Reload templates when they are changed. Used by + :meth:`create_jinja_environment`. + + This attribute can be configured with :data:`TEMPLATES_AUTO_RELOAD`. If + not set, it will be enabled in debug mode. + + .. versionadded:: 1.0 + This property was added but the underlying config and behavior + already existed. + """ + rv = self.config['TEMPLATES_AUTO_RELOAD'] + return rv if rv is not None else self.debug + + def _set_templates_auto_reload(self, value): + self.config['TEMPLATES_AUTO_RELOAD'] = value + + templates_auto_reload = property( + _get_templates_auto_reload, _set_templates_auto_reload + ) + del _get_templates_auto_reload, _set_templates_auto_reload + + def create_jinja_environment(self): + """Creates the Jinja2 environment based on :attr:`jinja_options` + and :meth:`select_jinja_autoescape`. Since 0.7 this also adds + the Jinja2 globals and filters after initialization. Override + this function to customize the behavior. + + .. versionadded:: 0.5 + .. versionchanged:: 0.11 + ``Environment.auto_reload`` set in accordance with + ``TEMPLATES_AUTO_RELOAD`` configuration option. + """ + options = dict(self.jinja_options) + + if 'autoescape' not in options: + options['autoescape'] = self.select_jinja_autoescape + + if 'auto_reload' not in options: + options['auto_reload'] = self.templates_auto_reload + + rv = self.jinja_environment(self, **options) + rv.globals.update( + url_for=url_for, + get_flashed_messages=get_flashed_messages, + config=self.config, + # request, session and g are normally added with the + # context processor for efficiency reasons but for imported + # templates we also want the proxies in there. + request=request, + session=session, + g=g + ) + rv.filters['tojson'] = json.tojson_filter + return rv + + def create_global_jinja_loader(self): + """Creates the loader for the Jinja2 environment. Can be used to + override just the loader and keeping the rest unchanged. It's + discouraged to override this function. Instead one should override + the :meth:`jinja_loader` function instead. + + The global loader dispatches between the loaders of the application + and the individual blueprints. + + .. versionadded:: 0.7 + """ + return DispatchingJinjaLoader(self) + + def select_jinja_autoescape(self, filename): + """Returns ``True`` if autoescaping should be active for the given + template name. If no template name is given, returns `True`. + + .. versionadded:: 0.5 + """ + if filename is None: + return True + return filename.endswith(('.html', '.htm', '.xml', '.xhtml')) + + def update_template_context(self, context): + """Update the template context with some commonly used variables. + This injects request, session, config and g into the template + context as well as everything template context processors want + to inject. Note that the as of Flask 0.6, the original values + in the context will not be overridden if a context processor + decides to return a value with the same key. + + :param context: the context as a dictionary that is updated in place + to add extra variables. + """ + funcs = self.template_context_processors[None] + reqctx = _request_ctx_stack.top + if reqctx is not None: + bp = reqctx.request.blueprint + if bp is not None and bp in self.template_context_processors: + funcs = chain(funcs, self.template_context_processors[bp]) + orig_ctx = context.copy() + for func in funcs: + context.update(func()) + # make sure the original values win. This makes it possible to + # easier add new variables in context processors without breaking + # existing views. + context.update(orig_ctx) + + def make_shell_context(self): + """Returns the shell context for an interactive shell for this + application. This runs all the registered shell context + processors. + + .. versionadded:: 0.11 + """ + rv = {'app': self, 'g': g} + for processor in self.shell_context_processors: + rv.update(processor()) + return rv + + #: What environment the app is running in. Flask and extensions may + #: enable behaviors based on the environment, such as enabling debug + #: mode. This maps to the :data:`ENV` config key. This is set by the + #: :envvar:`FLASK_ENV` environment variable and may not behave as + #: expected if set in code. + #: + #: **Do not enable development when deploying in production.** + #: + #: Default: ``'production'`` + env = ConfigAttribute('ENV') + + def _get_debug(self): + return self.config['DEBUG'] + + def _set_debug(self, value): + self.config['DEBUG'] = value + self.jinja_env.auto_reload = self.templates_auto_reload + + #: Whether debug mode is enabled. When using ``flask run`` to start + #: the development server, an interactive debugger will be shown for + #: unhandled exceptions, and the server will be reloaded when code + #: changes. This maps to the :data:`DEBUG` config key. This is + #: enabled when :attr:`env` is ``'development'`` and is overridden + #: by the ``FLASK_DEBUG`` environment variable. It may not behave as + #: expected if set in code. + #: + #: **Do not enable debug mode when deploying in production.** + #: + #: Default: ``True`` if :attr:`env` is ``'development'``, or + #: ``False`` otherwise. + debug = property(_get_debug, _set_debug) + del _get_debug, _set_debug + + def run(self, host=None, port=None, debug=None, + load_dotenv=True, **options): + """Runs the application on a local development server. + + Do not use ``run()`` in a production setting. It is not intended to + meet security and performance requirements for a production server. + Instead, see :ref:`deployment` for WSGI server recommendations. + + If the :attr:`debug` flag is set the server will automatically reload + for code changes and show a debugger in case an exception happened. + + If you want to run the application in debug mode, but disable the + code execution on the interactive debugger, you can pass + ``use_evalex=False`` as parameter. This will keep the debugger's + traceback screen active, but disable code execution. + + It is not recommended to use this function for development with + automatic reloading as this is badly supported. Instead you should + be using the :command:`flask` command line script's ``run`` support. + + .. admonition:: Keep in Mind + + Flask will suppress any server error with a generic error page + unless it is in debug mode. As such to enable just the + interactive debugger without the code reloading, you have to + invoke :meth:`run` with ``debug=True`` and ``use_reloader=False``. + Setting ``use_debugger`` to ``True`` without being in debug mode + won't catch any exceptions because there won't be any to + catch. + + :param host: the hostname to listen on. Set this to ``'0.0.0.0'`` to + have the server available externally as well. Defaults to + ``'127.0.0.1'`` or the host in the ``SERVER_NAME`` config variable + if present. + :param port: the port of the webserver. Defaults to ``5000`` or the + port defined in the ``SERVER_NAME`` config variable if present. + :param debug: if given, enable or disable debug mode. See + :attr:`debug`. + :param load_dotenv: Load the nearest :file:`.env` and :file:`.flaskenv` + files to set environment variables. Will also change the working + directory to the directory containing the first file found. + :param options: the options to be forwarded to the underlying Werkzeug + server. See :func:`werkzeug.serving.run_simple` for more + information. + + .. versionchanged:: 1.0 + If installed, python-dotenv will be used to load environment + variables from :file:`.env` and :file:`.flaskenv` files. + + If set, the :envvar:`FLASK_ENV` and :envvar:`FLASK_DEBUG` + environment variables will override :attr:`env` and + :attr:`debug`. + + Threaded mode is enabled by default. + + .. versionchanged:: 0.10 + The default port is now picked from the ``SERVER_NAME`` + variable. + """ + # Change this into a no-op if the server is invoked from the + # command line. Have a look at cli.py for more information. + if os.environ.get('FLASK_RUN_FROM_CLI') == 'true': + from .debughelpers import explain_ignored_app_run + explain_ignored_app_run() + return + + if get_load_dotenv(load_dotenv): + cli.load_dotenv() + + # if set, let env vars override previous values + if 'FLASK_ENV' in os.environ: + self.env = get_env() + self.debug = get_debug_flag() + elif 'FLASK_DEBUG' in os.environ: + self.debug = get_debug_flag() + + # debug passed to method overrides all other sources + if debug is not None: + self.debug = bool(debug) + + _host = '127.0.0.1' + _port = 5000 + server_name = self.config.get('SERVER_NAME') + sn_host, sn_port = None, None + + if server_name: + sn_host, _, sn_port = server_name.partition(':') + + host = host or sn_host or _host + port = int(port or sn_port or _port) + + options.setdefault('use_reloader', self.debug) + options.setdefault('use_debugger', self.debug) + options.setdefault('threaded', True) + + cli.show_server_banner(self.env, self.debug, self.name, False) + + from werkzeug.serving import run_simple + + try: + run_simple(host, port, self, **options) + finally: + # reset the first request information if the development server + # reset normally. This makes it possible to restart the server + # without reloader and that stuff from an interactive shell. + self._got_first_request = False + + def test_client(self, use_cookies=True, **kwargs): + """Creates a test client for this application. For information + about unit testing head over to :ref:`testing`. + + Note that if you are testing for assertions or exceptions in your + application code, you must set ``app.testing = True`` in order for the + exceptions to propagate to the test client. Otherwise, the exception + will be handled by the application (not visible to the test client) and + the only indication of an AssertionError or other exception will be a + 500 status code response to the test client. See the :attr:`testing` + attribute. For example:: + + app.testing = True + client = app.test_client() + + The test client can be used in a ``with`` block to defer the closing down + of the context until the end of the ``with`` block. This is useful if + you want to access the context locals for testing:: + + with app.test_client() as c: + rv = c.get('/?vodka=42') + assert request.args['vodka'] == '42' + + Additionally, you may pass optional keyword arguments that will then + be passed to the application's :attr:`test_client_class` constructor. + For example:: + + from flask.testing import FlaskClient + + class CustomClient(FlaskClient): + def __init__(self, *args, **kwargs): + self._authentication = kwargs.pop("authentication") + super(CustomClient,self).__init__( *args, **kwargs) + + app.test_client_class = CustomClient + client = app.test_client(authentication='Basic ....') + + See :class:`~flask.testing.FlaskClient` for more information. + + .. versionchanged:: 0.4 + added support for ``with`` block usage for the client. + + .. versionadded:: 0.7 + The `use_cookies` parameter was added as well as the ability + to override the client to be used by setting the + :attr:`test_client_class` attribute. + + .. versionchanged:: 0.11 + Added `**kwargs` to support passing additional keyword arguments to + the constructor of :attr:`test_client_class`. + """ + cls = self.test_client_class + if cls is None: + from flask.testing import FlaskClient as cls + return cls(self, self.response_class, use_cookies=use_cookies, **kwargs) + + def test_cli_runner(self, **kwargs): + """Create a CLI runner for testing CLI commands. + See :ref:`testing-cli`. + + Returns an instance of :attr:`test_cli_runner_class`, by default + :class:`~flask.testing.FlaskCliRunner`. The Flask app object is + passed as the first argument. + + .. versionadded:: 1.0 + """ + cls = self.test_cli_runner_class + + if cls is None: + from flask.testing import FlaskCliRunner as cls + + return cls(self, **kwargs) + + def open_session(self, request): + """Creates or opens a new session. Default implementation stores all + session data in a signed cookie. This requires that the + :attr:`secret_key` is set. Instead of overriding this method + we recommend replacing the :class:`session_interface`. + + .. deprecated: 1.0 + Will be removed in 1.1. Use ``session_interface.open_session`` + instead. + + :param request: an instance of :attr:`request_class`. + """ + + warnings.warn(DeprecationWarning( + '"open_session" is deprecated and will be removed in 1.1. Use' + ' "session_interface.open_session" instead.' + )) + return self.session_interface.open_session(self, request) + + def save_session(self, session, response): + """Saves the session if it needs updates. For the default + implementation, check :meth:`open_session`. Instead of overriding this + method we recommend replacing the :class:`session_interface`. + + .. deprecated: 1.0 + Will be removed in 1.1. Use ``session_interface.save_session`` + instead. + + :param session: the session to be saved (a + :class:`~werkzeug.contrib.securecookie.SecureCookie` + object) + :param response: an instance of :attr:`response_class` + """ + + warnings.warn(DeprecationWarning( + '"save_session" is deprecated and will be removed in 1.1. Use' + ' "session_interface.save_session" instead.' + )) + return self.session_interface.save_session(self, session, response) + + def make_null_session(self): + """Creates a new instance of a missing session. Instead of overriding + this method we recommend replacing the :class:`session_interface`. + + .. deprecated: 1.0 + Will be removed in 1.1. Use ``session_interface.make_null_session`` + instead. + + .. versionadded:: 0.7 + """ + + warnings.warn(DeprecationWarning( + '"make_null_session" is deprecated and will be removed in 1.1. Use' + ' "session_interface.make_null_session" instead.' + )) + return self.session_interface.make_null_session(self) + + @setupmethod + def register_blueprint(self, blueprint, **options): + """Register a :class:`~flask.Blueprint` on the application. Keyword + arguments passed to this method will override the defaults set on the + blueprint. + + Calls the blueprint's :meth:`~flask.Blueprint.register` method after + recording the blueprint in the application's :attr:`blueprints`. + + :param blueprint: The blueprint to register. + :param url_prefix: Blueprint routes will be prefixed with this. + :param subdomain: Blueprint routes will match on this subdomain. + :param url_defaults: Blueprint routes will use these default values for + view arguments. + :param options: Additional keyword arguments are passed to + :class:`~flask.blueprints.BlueprintSetupState`. They can be + accessed in :meth:`~flask.Blueprint.record` callbacks. + + .. versionadded:: 0.7 + """ + first_registration = False + + if blueprint.name in self.blueprints: + assert self.blueprints[blueprint.name] is blueprint, ( + 'A name collision occurred between blueprints %r and %r. Both' + ' share the same name "%s". Blueprints that are created on the' + ' fly need unique names.' % ( + blueprint, self.blueprints[blueprint.name], blueprint.name + ) + ) + else: + self.blueprints[blueprint.name] = blueprint + self._blueprint_order.append(blueprint) + first_registration = True + + blueprint.register(self, options, first_registration) + + def iter_blueprints(self): + """Iterates over all blueprints by the order they were registered. + + .. versionadded:: 0.11 + """ + return iter(self._blueprint_order) + + @setupmethod + def add_url_rule(self, rule, endpoint=None, view_func=None, + provide_automatic_options=None, **options): + """Connects a URL rule. Works exactly like the :meth:`route` + decorator. If a view_func is provided it will be registered with the + endpoint. + + Basically this example:: + + @app.route('/') + def index(): + pass + + Is equivalent to the following:: + + def index(): + pass + app.add_url_rule('/', 'index', index) + + If the view_func is not provided you will need to connect the endpoint + to a view function like so:: + + app.view_functions['index'] = index + + Internally :meth:`route` invokes :meth:`add_url_rule` so if you want + to customize the behavior via subclassing you only need to change + this method. + + For more information refer to :ref:`url-route-registrations`. + + .. versionchanged:: 0.2 + `view_func` parameter added. + + .. versionchanged:: 0.6 + ``OPTIONS`` is added automatically as method. + + :param rule: the URL rule as string + :param endpoint: the endpoint for the registered URL rule. Flask + itself assumes the name of the view function as + endpoint + :param view_func: the function to call when serving a request to the + provided endpoint + :param provide_automatic_options: controls whether the ``OPTIONS`` + method should be added automatically. This can also be controlled + by setting the ``view_func.provide_automatic_options = False`` + before adding the rule. + :param options: the options to be forwarded to the underlying + :class:`~werkzeug.routing.Rule` object. A change + to Werkzeug is handling of method options. methods + is a list of methods this rule should be limited + to (``GET``, ``POST`` etc.). By default a rule + just listens for ``GET`` (and implicitly ``HEAD``). + Starting with Flask 0.6, ``OPTIONS`` is implicitly + added and handled by the standard request handling. + """ + if endpoint is None: + endpoint = _endpoint_from_view_func(view_func) + options['endpoint'] = endpoint + methods = options.pop('methods', None) + + # if the methods are not given and the view_func object knows its + # methods we can use that instead. If neither exists, we go with + # a tuple of only ``GET`` as default. + if methods is None: + methods = getattr(view_func, 'methods', None) or ('GET',) + if isinstance(methods, string_types): + raise TypeError('Allowed methods have to be iterables of strings, ' + 'for example: @app.route(..., methods=["POST"])') + methods = set(item.upper() for item in methods) + + # Methods that should always be added + required_methods = set(getattr(view_func, 'required_methods', ())) + + # starting with Flask 0.8 the view_func object can disable and + # force-enable the automatic options handling. + if provide_automatic_options is None: + provide_automatic_options = getattr(view_func, + 'provide_automatic_options', None) + + if provide_automatic_options is None: + if 'OPTIONS' not in methods: + provide_automatic_options = True + required_methods.add('OPTIONS') + else: + provide_automatic_options = False + + # Add the required methods now. + methods |= required_methods + + rule = self.url_rule_class(rule, methods=methods, **options) + rule.provide_automatic_options = provide_automatic_options + + self.url_map.add(rule) + if view_func is not None: + old_func = self.view_functions.get(endpoint) + if old_func is not None and old_func != view_func: + raise AssertionError('View function mapping is overwriting an ' + 'existing endpoint function: %s' % endpoint) + self.view_functions[endpoint] = view_func + + def route(self, rule, **options): + """A decorator that is used to register a view function for a + given URL rule. This does the same thing as :meth:`add_url_rule` + but is intended for decorator usage:: + + @app.route('/') + def index(): + return 'Hello World' + + For more information refer to :ref:`url-route-registrations`. + + :param rule: the URL rule as string + :param endpoint: the endpoint for the registered URL rule. Flask + itself assumes the name of the view function as + endpoint + :param options: the options to be forwarded to the underlying + :class:`~werkzeug.routing.Rule` object. A change + to Werkzeug is handling of method options. methods + is a list of methods this rule should be limited + to (``GET``, ``POST`` etc.). By default a rule + just listens for ``GET`` (and implicitly ``HEAD``). + Starting with Flask 0.6, ``OPTIONS`` is implicitly + added and handled by the standard request handling. + """ + def decorator(f): + endpoint = options.pop('endpoint', None) + self.add_url_rule(rule, endpoint, f, **options) + return f + return decorator + + @setupmethod + def endpoint(self, endpoint): + """A decorator to register a function as an endpoint. + Example:: + + @app.endpoint('example.endpoint') + def example(): + return "example" + + :param endpoint: the name of the endpoint + """ + def decorator(f): + self.view_functions[endpoint] = f + return f + return decorator + + @staticmethod + def _get_exc_class_and_code(exc_class_or_code): + """Ensure that we register only exceptions as handler keys""" + if isinstance(exc_class_or_code, integer_types): + exc_class = default_exceptions[exc_class_or_code] + else: + exc_class = exc_class_or_code + + assert issubclass(exc_class, Exception) + + if issubclass(exc_class, HTTPException): + return exc_class, exc_class.code + else: + return exc_class, None + + @setupmethod + def errorhandler(self, code_or_exception): + """Register a function to handle errors by code or exception class. + + A decorator that is used to register a function given an + error code. Example:: + + @app.errorhandler(404) + def page_not_found(error): + return 'This page does not exist', 404 + + You can also register handlers for arbitrary exceptions:: + + @app.errorhandler(DatabaseError) + def special_exception_handler(error): + return 'Database connection failed', 500 + + .. versionadded:: 0.7 + Use :meth:`register_error_handler` instead of modifying + :attr:`error_handler_spec` directly, for application wide error + handlers. + + .. versionadded:: 0.7 + One can now additionally also register custom exception types + that do not necessarily have to be a subclass of the + :class:`~werkzeug.exceptions.HTTPException` class. + + :param code_or_exception: the code as integer for the handler, or + an arbitrary exception + """ + def decorator(f): + self._register_error_handler(None, code_or_exception, f) + return f + return decorator + + @setupmethod + def register_error_handler(self, code_or_exception, f): + """Alternative error attach function to the :meth:`errorhandler` + decorator that is more straightforward to use for non decorator + usage. + + .. versionadded:: 0.7 + """ + self._register_error_handler(None, code_or_exception, f) + + @setupmethod + def _register_error_handler(self, key, code_or_exception, f): + """ + :type key: None|str + :type code_or_exception: int|T<=Exception + :type f: callable + """ + if isinstance(code_or_exception, HTTPException): # old broken behavior + raise ValueError( + 'Tried to register a handler for an exception instance {0!r}.' + ' Handlers can only be registered for exception classes or' + ' HTTP error codes.'.format(code_or_exception) + ) + + try: + exc_class, code = self._get_exc_class_and_code(code_or_exception) + except KeyError: + raise KeyError( + "'{0}' is not a recognized HTTP error code. Use a subclass of" + " HTTPException with that code instead.".format(code_or_exception) + ) + + handlers = self.error_handler_spec.setdefault(key, {}).setdefault(code, {}) + handlers[exc_class] = f + + @setupmethod + def template_filter(self, name=None): + """A decorator that is used to register custom template filter. + You can specify a name for the filter, otherwise the function + name will be used. Example:: + + @app.template_filter() + def reverse(s): + return s[::-1] + + :param name: the optional name of the filter, otherwise the + function name will be used. + """ + def decorator(f): + self.add_template_filter(f, name=name) + return f + return decorator + + @setupmethod + def add_template_filter(self, f, name=None): + """Register a custom template filter. Works exactly like the + :meth:`template_filter` decorator. + + :param name: the optional name of the filter, otherwise the + function name will be used. + """ + self.jinja_env.filters[name or f.__name__] = f + + @setupmethod + def template_test(self, name=None): + """A decorator that is used to register custom template test. + You can specify a name for the test, otherwise the function + name will be used. Example:: + + @app.template_test() + def is_prime(n): + if n == 2: + return True + for i in range(2, int(math.ceil(math.sqrt(n))) + 1): + if n % i == 0: + return False + return True + + .. versionadded:: 0.10 + + :param name: the optional name of the test, otherwise the + function name will be used. + """ + def decorator(f): + self.add_template_test(f, name=name) + return f + return decorator + + @setupmethod + def add_template_test(self, f, name=None): + """Register a custom template test. Works exactly like the + :meth:`template_test` decorator. + + .. versionadded:: 0.10 + + :param name: the optional name of the test, otherwise the + function name will be used. + """ + self.jinja_env.tests[name or f.__name__] = f + + @setupmethod + def template_global(self, name=None): + """A decorator that is used to register a custom template global function. + You can specify a name for the global function, otherwise the function + name will be used. Example:: + + @app.template_global() + def double(n): + return 2 * n + + .. versionadded:: 0.10 + + :param name: the optional name of the global function, otherwise the + function name will be used. + """ + def decorator(f): + self.add_template_global(f, name=name) + return f + return decorator + + @setupmethod + def add_template_global(self, f, name=None): + """Register a custom template global function. Works exactly like the + :meth:`template_global` decorator. + + .. versionadded:: 0.10 + + :param name: the optional name of the global function, otherwise the + function name will be used. + """ + self.jinja_env.globals[name or f.__name__] = f + + @setupmethod + def before_request(self, f): + """Registers a function to run before each request. + + For example, this can be used to open a database connection, or to load + the logged in user from the session. + + The function will be called without any arguments. If it returns a + non-None value, the value is handled as if it was the return value from + the view, and further request handling is stopped. + """ + self.before_request_funcs.setdefault(None, []).append(f) + return f + + @setupmethod + def before_first_request(self, f): + """Registers a function to be run before the first request to this + instance of the application. + + The function will be called without any arguments and its return + value is ignored. + + .. versionadded:: 0.8 + """ + self.before_first_request_funcs.append(f) + return f + + @setupmethod + def after_request(self, f): + """Register a function to be run after each request. + + Your function must take one parameter, an instance of + :attr:`response_class` and return a new response object or the + same (see :meth:`process_response`). + + As of Flask 0.7 this function might not be executed at the end of the + request in case an unhandled exception occurred. + """ + self.after_request_funcs.setdefault(None, []).append(f) + return f + + @setupmethod + def teardown_request(self, f): + """Register a function to be run at the end of each request, + regardless of whether there was an exception or not. These functions + are executed when the request context is popped, even if not an + actual request was performed. + + Example:: + + ctx = app.test_request_context() + ctx.push() + ... + ctx.pop() + + When ``ctx.pop()`` is executed in the above example, the teardown + functions are called just before the request context moves from the + stack of active contexts. This becomes relevant if you are using + such constructs in tests. + + Generally teardown functions must take every necessary step to avoid + that they will fail. If they do execute code that might fail they + will have to surround the execution of these code by try/except + statements and log occurring errors. + + When a teardown function was called because of an exception it will + be passed an error object. + + The return values of teardown functions are ignored. + + .. admonition:: Debug Note + + In debug mode Flask will not tear down a request on an exception + immediately. Instead it will keep it alive so that the interactive + debugger can still access it. This behavior can be controlled + by the ``PRESERVE_CONTEXT_ON_EXCEPTION`` configuration variable. + """ + self.teardown_request_funcs.setdefault(None, []).append(f) + return f + + @setupmethod + def teardown_appcontext(self, f): + """Registers a function to be called when the application context + ends. These functions are typically also called when the request + context is popped. + + Example:: + + ctx = app.app_context() + ctx.push() + ... + ctx.pop() + + When ``ctx.pop()`` is executed in the above example, the teardown + functions are called just before the app context moves from the + stack of active contexts. This becomes relevant if you are using + such constructs in tests. + + Since a request context typically also manages an application + context it would also be called when you pop a request context. + + When a teardown function was called because of an unhandled exception + it will be passed an error object. If an :meth:`errorhandler` is + registered, it will handle the exception and the teardown will not + receive it. + + The return values of teardown functions are ignored. + + .. versionadded:: 0.9 + """ + self.teardown_appcontext_funcs.append(f) + return f + + @setupmethod + def context_processor(self, f): + """Registers a template context processor function.""" + self.template_context_processors[None].append(f) + return f + + @setupmethod + def shell_context_processor(self, f): + """Registers a shell context processor function. + + .. versionadded:: 0.11 + """ + self.shell_context_processors.append(f) + return f + + @setupmethod + def url_value_preprocessor(self, f): + """Register a URL value preprocessor function for all view + functions in the application. These functions will be called before the + :meth:`before_request` functions. + + The function can modify the values captured from the matched url before + they are passed to the view. For example, this can be used to pop a + common language code value and place it in ``g`` rather than pass it to + every view. + + The function is passed the endpoint name and values dict. The return + value is ignored. + """ + self.url_value_preprocessors.setdefault(None, []).append(f) + return f + + @setupmethod + def url_defaults(self, f): + """Callback function for URL defaults for all view functions of the + application. It's called with the endpoint and values and should + update the values passed in place. + """ + self.url_default_functions.setdefault(None, []).append(f) + return f + + def _find_error_handler(self, e): + """Return a registered error handler for an exception in this order: + blueprint handler for a specific code, app handler for a specific code, + blueprint handler for an exception class, app handler for an exception + class, or ``None`` if a suitable handler is not found. + """ + exc_class, code = self._get_exc_class_and_code(type(e)) + + for name, c in ( + (request.blueprint, code), (None, code), + (request.blueprint, None), (None, None) + ): + handler_map = self.error_handler_spec.setdefault(name, {}).get(c) + + if not handler_map: + continue + + for cls in exc_class.__mro__: + handler = handler_map.get(cls) + + if handler is not None: + return handler + + def handle_http_exception(self, e): + """Handles an HTTP exception. By default this will invoke the + registered error handlers and fall back to returning the + exception as response. + + .. versionadded:: 0.3 + """ + # Proxy exceptions don't have error codes. We want to always return + # those unchanged as errors + if e.code is None: + return e + + handler = self._find_error_handler(e) + if handler is None: + return e + return handler(e) + + def trap_http_exception(self, e): + """Checks if an HTTP exception should be trapped or not. By default + this will return ``False`` for all exceptions except for a bad request + key error if ``TRAP_BAD_REQUEST_ERRORS`` is set to ``True``. It + also returns ``True`` if ``TRAP_HTTP_EXCEPTIONS`` is set to ``True``. + + This is called for all HTTP exceptions raised by a view function. + If it returns ``True`` for any exception the error handler for this + exception is not called and it shows up as regular exception in the + traceback. This is helpful for debugging implicitly raised HTTP + exceptions. + + .. versionchanged:: 1.0 + Bad request errors are not trapped by default in debug mode. + + .. versionadded:: 0.8 + """ + if self.config['TRAP_HTTP_EXCEPTIONS']: + return True + + trap_bad_request = self.config['TRAP_BAD_REQUEST_ERRORS'] + + # if unset, trap key errors in debug mode + if ( + trap_bad_request is None and self.debug + and isinstance(e, BadRequestKeyError) + ): + return True + + if trap_bad_request: + return isinstance(e, BadRequest) + + return False + + def handle_user_exception(self, e): + """This method is called whenever an exception occurs that should be + handled. A special case are + :class:`~werkzeug.exception.HTTPException`\s which are forwarded by + this function to the :meth:`handle_http_exception` method. This + function will either return a response value or reraise the + exception with the same traceback. + + .. versionchanged:: 1.0 + Key errors raised from request data like ``form`` show the the bad + key in debug mode rather than a generic bad request message. + + .. versionadded:: 0.7 + """ + exc_type, exc_value, tb = sys.exc_info() + assert exc_value is e + # ensure not to trash sys.exc_info() at that point in case someone + # wants the traceback preserved in handle_http_exception. Of course + # we cannot prevent users from trashing it themselves in a custom + # trap_http_exception method so that's their fault then. + + # MultiDict passes the key to the exception, but that's ignored + # when generating the response message. Set an informative + # description for key errors in debug mode or when trapping errors. + if ( + (self.debug or self.config['TRAP_BAD_REQUEST_ERRORS']) + and isinstance(e, BadRequestKeyError) + # only set it if it's still the default description + and e.description is BadRequestKeyError.description + ): + e.description = "KeyError: '{0}'".format(*e.args) + + if isinstance(e, HTTPException) and not self.trap_http_exception(e): + return self.handle_http_exception(e) + + handler = self._find_error_handler(e) + + if handler is None: + reraise(exc_type, exc_value, tb) + return handler(e) + + def handle_exception(self, e): + """Default exception handling that kicks in when an exception + occurs that is not caught. In debug mode the exception will + be re-raised immediately, otherwise it is logged and the handler + for a 500 internal server error is used. If no such handler + exists, a default 500 internal server error message is displayed. + + .. versionadded:: 0.3 + """ + exc_type, exc_value, tb = sys.exc_info() + + got_request_exception.send(self, exception=e) + handler = self._find_error_handler(InternalServerError()) + + if self.propagate_exceptions: + # if we want to repropagate the exception, we can attempt to + # raise it with the whole traceback in case we can do that + # (the function was actually called from the except part) + # otherwise, we just raise the error again + if exc_value is e: + reraise(exc_type, exc_value, tb) + else: + raise e + + self.log_exception((exc_type, exc_value, tb)) + if handler is None: + return InternalServerError() + return self.finalize_request(handler(e), from_error_handler=True) + + def log_exception(self, exc_info): + """Logs an exception. This is called by :meth:`handle_exception` + if debugging is disabled and right before the handler is called. + The default implementation logs the exception as error on the + :attr:`logger`. + + .. versionadded:: 0.8 + """ + self.logger.error('Exception on %s [%s]' % ( + request.path, + request.method + ), exc_info=exc_info) + + def raise_routing_exception(self, request): + """Exceptions that are recording during routing are reraised with + this method. During debug we are not reraising redirect requests + for non ``GET``, ``HEAD``, or ``OPTIONS`` requests and we're raising + a different error instead to help debug situations. + + :internal: + """ + if not self.debug \ + or not isinstance(request.routing_exception, RequestRedirect) \ + or request.method in ('GET', 'HEAD', 'OPTIONS'): + raise request.routing_exception + + from .debughelpers import FormDataRoutingRedirect + raise FormDataRoutingRedirect(request) + + def dispatch_request(self): + """Does the request dispatching. Matches the URL and returns the + return value of the view or error handler. This does not have to + be a response object. In order to convert the return value to a + proper response object, call :func:`make_response`. + + .. versionchanged:: 0.7 + This no longer does the exception handling, this code was + moved to the new :meth:`full_dispatch_request`. + """ + req = _request_ctx_stack.top.request + if req.routing_exception is not None: + self.raise_routing_exception(req) + rule = req.url_rule + # if we provide automatic options for this URL and the + # request came with the OPTIONS method, reply automatically + if getattr(rule, 'provide_automatic_options', False) \ + and req.method == 'OPTIONS': + return self.make_default_options_response() + # otherwise dispatch to the handler for that endpoint + return self.view_functions[rule.endpoint](**req.view_args) + + def full_dispatch_request(self): + """Dispatches the request and on top of that performs request + pre and postprocessing as well as HTTP exception catching and + error handling. + + .. versionadded:: 0.7 + """ + self.try_trigger_before_first_request_functions() + try: + request_started.send(self) + rv = self.preprocess_request() + if rv is None: + rv = self.dispatch_request() + except Exception as e: + rv = self.handle_user_exception(e) + return self.finalize_request(rv) + + def finalize_request(self, rv, from_error_handler=False): + """Given the return value from a view function this finalizes + the request by converting it into a response and invoking the + postprocessing functions. This is invoked for both normal + request dispatching as well as error handlers. + + Because this means that it might be called as a result of a + failure a special safe mode is available which can be enabled + with the `from_error_handler` flag. If enabled, failures in + response processing will be logged and otherwise ignored. + + :internal: + """ + response = self.make_response(rv) + try: + response = self.process_response(response) + request_finished.send(self, response=response) + except Exception: + if not from_error_handler: + raise + self.logger.exception('Request finalizing failed with an ' + 'error while handling an error') + return response + + def try_trigger_before_first_request_functions(self): + """Called before each request and will ensure that it triggers + the :attr:`before_first_request_funcs` and only exactly once per + application instance (which means process usually). + + :internal: + """ + if self._got_first_request: + return + with self._before_request_lock: + if self._got_first_request: + return + for func in self.before_first_request_funcs: + func() + self._got_first_request = True + + def make_default_options_response(self): + """This method is called to create the default ``OPTIONS`` response. + This can be changed through subclassing to change the default + behavior of ``OPTIONS`` responses. + + .. versionadded:: 0.7 + """ + adapter = _request_ctx_stack.top.url_adapter + if hasattr(adapter, 'allowed_methods'): + methods = adapter.allowed_methods() + else: + # fallback for Werkzeug < 0.7 + methods = [] + try: + adapter.match(method='--') + except MethodNotAllowed as e: + methods = e.valid_methods + except HTTPException as e: + pass + rv = self.response_class() + rv.allow.update(methods) + return rv + + def should_ignore_error(self, error): + """This is called to figure out if an error should be ignored + or not as far as the teardown system is concerned. If this + function returns ``True`` then the teardown handlers will not be + passed the error. + + .. versionadded:: 0.10 + """ + return False + + def make_response(self, rv): + """Convert the return value from a view function to an instance of + :attr:`response_class`. + + :param rv: the return value from the view function. The view function + must return a response. Returning ``None``, or the view ending + without returning, is not allowed. The following types are allowed + for ``view_rv``: + + ``str`` (``unicode`` in Python 2) + A response object is created with the string encoded to UTF-8 + as the body. + + ``bytes`` (``str`` in Python 2) + A response object is created with the bytes as the body. + + ``tuple`` + Either ``(body, status, headers)``, ``(body, status)``, or + ``(body, headers)``, where ``body`` is any of the other types + allowed here, ``status`` is a string or an integer, and + ``headers`` is a dictionary or a list of ``(key, value)`` + tuples. If ``body`` is a :attr:`response_class` instance, + ``status`` overwrites the exiting value and ``headers`` are + extended. + + :attr:`response_class` + The object is returned unchanged. + + other :class:`~werkzeug.wrappers.Response` class + The object is coerced to :attr:`response_class`. + + :func:`callable` + The function is called as a WSGI application. The result is + used to create a response object. + + .. versionchanged:: 0.9 + Previously a tuple was interpreted as the arguments for the + response object. + """ + + status = headers = None + + # unpack tuple returns + if isinstance(rv, tuple): + len_rv = len(rv) + + # a 3-tuple is unpacked directly + if len_rv == 3: + rv, status, headers = rv + # decide if a 2-tuple has status or headers + elif len_rv == 2: + if isinstance(rv[1], (Headers, dict, tuple, list)): + rv, headers = rv + else: + rv, status = rv + # other sized tuples are not allowed + else: + raise TypeError( + 'The view function did not return a valid response tuple.' + ' The tuple must have the form (body, status, headers),' + ' (body, status), or (body, headers).' + ) + + # the body must not be None + if rv is None: + raise TypeError( + 'The view function did not return a valid response. The' + ' function either returned None or ended without a return' + ' statement.' + ) + + # make sure the body is an instance of the response class + if not isinstance(rv, self.response_class): + if isinstance(rv, (text_type, bytes, bytearray)): + # let the response class set the status and headers instead of + # waiting to do it manually, so that the class can handle any + # special logic + rv = self.response_class(rv, status=status, headers=headers) + status = headers = None + else: + # evaluate a WSGI callable, or coerce a different response + # class to the correct type + try: + rv = self.response_class.force_type(rv, request.environ) + except TypeError as e: + new_error = TypeError( + '{e}\nThe view function did not return a valid' + ' response. The return type must be a string, tuple,' + ' Response instance, or WSGI callable, but it was a' + ' {rv.__class__.__name__}.'.format(e=e, rv=rv) + ) + reraise(TypeError, new_error, sys.exc_info()[2]) + + # prefer the status if it was provided + if status is not None: + if isinstance(status, (text_type, bytes, bytearray)): + rv.status = status + else: + rv.status_code = status + + # extend existing headers with provided headers + if headers: + rv.headers.extend(headers) + + return rv + + def create_url_adapter(self, request): + """Creates a URL adapter for the given request. The URL adapter + is created at a point where the request context is not yet set + up so the request is passed explicitly. + + .. versionadded:: 0.6 + + .. versionchanged:: 0.9 + This can now also be called without a request object when the + URL adapter is created for the application context. + + .. versionchanged:: 1.0 + :data:`SERVER_NAME` no longer implicitly enables subdomain + matching. Use :attr:`subdomain_matching` instead. + """ + if request is not None: + # If subdomain matching is disabled (the default), use the + # default subdomain in all cases. This should be the default + # in Werkzeug but it currently does not have that feature. + subdomain = ((self.url_map.default_subdomain or None) + if not self.subdomain_matching else None) + return self.url_map.bind_to_environ( + request.environ, + server_name=self.config['SERVER_NAME'], + subdomain=subdomain) + # We need at the very least the server name to be set for this + # to work. + if self.config['SERVER_NAME'] is not None: + return self.url_map.bind( + self.config['SERVER_NAME'], + script_name=self.config['APPLICATION_ROOT'], + url_scheme=self.config['PREFERRED_URL_SCHEME']) + + def inject_url_defaults(self, endpoint, values): + """Injects the URL defaults for the given endpoint directly into + the values dictionary passed. This is used internally and + automatically called on URL building. + + .. versionadded:: 0.7 + """ + funcs = self.url_default_functions.get(None, ()) + if '.' in endpoint: + bp = endpoint.rsplit('.', 1)[0] + funcs = chain(funcs, self.url_default_functions.get(bp, ())) + for func in funcs: + func(endpoint, values) + + def handle_url_build_error(self, error, endpoint, values): + """Handle :class:`~werkzeug.routing.BuildError` on :meth:`url_for`. + """ + exc_type, exc_value, tb = sys.exc_info() + for handler in self.url_build_error_handlers: + try: + rv = handler(error, endpoint, values) + if rv is not None: + return rv + except BuildError as e: + # make error available outside except block (py3) + error = e + + # At this point we want to reraise the exception. If the error is + # still the same one we can reraise it with the original traceback, + # otherwise we raise it from here. + if error is exc_value: + reraise(exc_type, exc_value, tb) + raise error + + def preprocess_request(self): + """Called before the request is dispatched. Calls + :attr:`url_value_preprocessors` registered with the app and the + current blueprint (if any). Then calls :attr:`before_request_funcs` + registered with the app and the blueprint. + + If any :meth:`before_request` handler returns a non-None value, the + value is handled as if it was the return value from the view, and + further request handling is stopped. + """ + + bp = _request_ctx_stack.top.request.blueprint + + funcs = self.url_value_preprocessors.get(None, ()) + if bp is not None and bp in self.url_value_preprocessors: + funcs = chain(funcs, self.url_value_preprocessors[bp]) + for func in funcs: + func(request.endpoint, request.view_args) + + funcs = self.before_request_funcs.get(None, ()) + if bp is not None and bp in self.before_request_funcs: + funcs = chain(funcs, self.before_request_funcs[bp]) + for func in funcs: + rv = func() + if rv is not None: + return rv + + def process_response(self, response): + """Can be overridden in order to modify the response object + before it's sent to the WSGI server. By default this will + call all the :meth:`after_request` decorated functions. + + .. versionchanged:: 0.5 + As of Flask 0.5 the functions registered for after request + execution are called in reverse order of registration. + + :param response: a :attr:`response_class` object. + :return: a new response object or the same, has to be an + instance of :attr:`response_class`. + """ + ctx = _request_ctx_stack.top + bp = ctx.request.blueprint + funcs = ctx._after_request_functions + if bp is not None and bp in self.after_request_funcs: + funcs = chain(funcs, reversed(self.after_request_funcs[bp])) + if None in self.after_request_funcs: + funcs = chain(funcs, reversed(self.after_request_funcs[None])) + for handler in funcs: + response = handler(response) + if not self.session_interface.is_null_session(ctx.session): + self.session_interface.save_session(self, ctx.session, response) + return response + + def do_teardown_request(self, exc=_sentinel): + """Called after the request is dispatched and the response is + returned, right before the request context is popped. + + This calls all functions decorated with + :meth:`teardown_request`, and :meth:`Blueprint.teardown_request` + if a blueprint handled the request. Finally, the + :data:`request_tearing_down` signal is sent. + + This is called by + :meth:`RequestContext.pop() `, + which may be delayed during testing to maintain access to + resources. + + :param exc: An unhandled exception raised while dispatching the + request. Detected from the current exception information if + not passed. Passed to each teardown function. + + .. versionchanged:: 0.9 + Added the ``exc`` argument. + """ + if exc is _sentinel: + exc = sys.exc_info()[1] + funcs = reversed(self.teardown_request_funcs.get(None, ())) + bp = _request_ctx_stack.top.request.blueprint + if bp is not None and bp in self.teardown_request_funcs: + funcs = chain(funcs, reversed(self.teardown_request_funcs[bp])) + for func in funcs: + func(exc) + request_tearing_down.send(self, exc=exc) + + def do_teardown_appcontext(self, exc=_sentinel): + """Called right before the application context is popped. + + When handling a request, the application context is popped + after the request context. See :meth:`do_teardown_request`. + + This calls all functions decorated with + :meth:`teardown_appcontext`. Then the + :data:`appcontext_tearing_down` signal is sent. + + This is called by + :meth:`AppContext.pop() `. + + .. versionadded:: 0.9 + """ + if exc is _sentinel: + exc = sys.exc_info()[1] + for func in reversed(self.teardown_appcontext_funcs): + func(exc) + appcontext_tearing_down.send(self, exc=exc) + + def app_context(self): + """Create an :class:`~flask.ctx.AppContext`. Use as a ``with`` + block to push the context, which will make :data:`current_app` + point at this application. + + An application context is automatically pushed by + :meth:`RequestContext.push() ` + when handling a request, and when running a CLI command. Use + this to manually create a context outside of these situations. + + :: + + with app.app_context(): + init_db() + + See :doc:`/appcontext`. + + .. versionadded:: 0.9 + """ + return AppContext(self) + + def request_context(self, environ): + """Create a :class:`~flask.ctx.RequestContext` representing a + WSGI environment. Use a ``with`` block to push the context, + which will make :data:`request` point at this request. + + See :doc:`/reqcontext`. + + Typically you should not call this from your own code. A request + context is automatically pushed by the :meth:`wsgi_app` when + handling a request. Use :meth:`test_request_context` to create + an environment and context instead of this method. + + :param environ: a WSGI environment + """ + return RequestContext(self, environ) + + def test_request_context(self, *args, **kwargs): + """Create a :class:`~flask.ctx.RequestContext` for a WSGI + environment created from the given values. This is mostly useful + during testing, where you may want to run a function that uses + request data without dispatching a full request. + + See :doc:`/reqcontext`. + + Use a ``with`` block to push the context, which will make + :data:`request` point at the request for the created + environment. :: + + with test_request_context(...): + generate_report() + + When using the shell, it may be easier to push and pop the + context manually to avoid indentation. :: + + ctx = app.test_request_context(...) + ctx.push() + ... + ctx.pop() + + Takes the same arguments as Werkzeug's + :class:`~werkzeug.test.EnvironBuilder`, with some defaults from + the application. See the linked Werkzeug docs for most of the + available arguments. Flask-specific behavior is listed here. + + :param path: URL path being requested. + :param base_url: Base URL where the app is being served, which + ``path`` is relative to. If not given, built from + :data:`PREFERRED_URL_SCHEME`, ``subdomain``, + :data:`SERVER_NAME`, and :data:`APPLICATION_ROOT`. + :param subdomain: Subdomain name to append to + :data:`SERVER_NAME`. + :param url_scheme: Scheme to use instead of + :data:`PREFERRED_URL_SCHEME`. + :param data: The request body, either as a string or a dict of + form keys and values. + :param json: If given, this is serialized as JSON and passed as + ``data``. Also defaults ``content_type`` to + ``application/json``. + :param args: other positional arguments passed to + :class:`~werkzeug.test.EnvironBuilder`. + :param kwargs: other keyword arguments passed to + :class:`~werkzeug.test.EnvironBuilder`. + """ + from flask.testing import make_test_environ_builder + + builder = make_test_environ_builder(self, *args, **kwargs) + + try: + return self.request_context(builder.get_environ()) + finally: + builder.close() + + def wsgi_app(self, environ, start_response): + """The actual WSGI application. This is not implemented in + :meth:`__call__` so that middlewares can be applied without + losing a reference to the app object. Instead of doing this:: + + app = MyMiddleware(app) + + It's a better idea to do this instead:: + + app.wsgi_app = MyMiddleware(app.wsgi_app) + + Then you still have the original application object around and + can continue to call methods on it. + + .. versionchanged:: 0.7 + Teardown events for the request and app contexts are called + even if an unhandled error occurs. Other events may not be + called depending on when an error occurs during dispatch. + See :ref:`callbacks-and-errors`. + + :param environ: A WSGI environment. + :param start_response: A callable accepting a status code, + a list of headers, and an optional exception context to + start the response. + """ + ctx = self.request_context(environ) + error = None + try: + try: + ctx.push() + response = self.full_dispatch_request() + except Exception as e: + error = e + response = self.handle_exception(e) + except: + error = sys.exc_info()[1] + raise + return response(environ, start_response) + finally: + if self.should_ignore_error(error): + error = None + ctx.auto_pop(error) + + def __call__(self, environ, start_response): + """The WSGI server calls the Flask application object as the + WSGI application. This calls :meth:`wsgi_app` which can be + wrapped to applying middleware.""" + return self.wsgi_app(environ, start_response) + + def __repr__(self): + return '<%s %r>' % ( + self.__class__.__name__, + self.name, + ) diff --git a/flask/venv/lib/python3.6/site-packages/flask/blueprints.py b/flask/venv/lib/python3.6/site-packages/flask/blueprints.py new file mode 100644 index 0000000..5ce5561 --- /dev/null +++ b/flask/venv/lib/python3.6/site-packages/flask/blueprints.py @@ -0,0 +1,448 @@ +# -*- coding: utf-8 -*- +""" + flask.blueprints + ~~~~~~~~~~~~~~~~ + + Blueprints are the recommended way to implement larger or more + pluggable applications in Flask 0.7 and later. + + :copyright: © 2010 by the Pallets team. + :license: BSD, see LICENSE for more details. +""" +from functools import update_wrapper +from werkzeug.urls import url_join + +from .helpers import _PackageBoundObject, _endpoint_from_view_func + + +class BlueprintSetupState(object): + """Temporary holder object for registering a blueprint with the + application. An instance of this class is created by the + :meth:`~flask.Blueprint.make_setup_state` method and later passed + to all register callback functions. + """ + + def __init__(self, blueprint, app, options, first_registration): + #: a reference to the current application + self.app = app + + #: a reference to the blueprint that created this setup state. + self.blueprint = blueprint + + #: a dictionary with all options that were passed to the + #: :meth:`~flask.Flask.register_blueprint` method. + self.options = options + + #: as blueprints can be registered multiple times with the + #: application and not everything wants to be registered + #: multiple times on it, this attribute can be used to figure + #: out if the blueprint was registered in the past already. + self.first_registration = first_registration + + subdomain = self.options.get('subdomain') + if subdomain is None: + subdomain = self.blueprint.subdomain + + #: The subdomain that the blueprint should be active for, ``None`` + #: otherwise. + self.subdomain = subdomain + + url_prefix = self.options.get('url_prefix') + if url_prefix is None: + url_prefix = self.blueprint.url_prefix + #: The prefix that should be used for all URLs defined on the + #: blueprint. + self.url_prefix = url_prefix + + #: A dictionary with URL defaults that is added to each and every + #: URL that was defined with the blueprint. + self.url_defaults = dict(self.blueprint.url_values_defaults) + self.url_defaults.update(self.options.get('url_defaults', ())) + + def add_url_rule(self, rule, endpoint=None, view_func=None, **options): + """A helper method to register a rule (and optionally a view function) + to the application. The endpoint is automatically prefixed with the + blueprint's name. + """ + if self.url_prefix is not None: + if rule: + rule = '/'.join(( + self.url_prefix.rstrip('/'), rule.lstrip('/'))) + else: + rule = self.url_prefix + options.setdefault('subdomain', self.subdomain) + if endpoint is None: + endpoint = _endpoint_from_view_func(view_func) + defaults = self.url_defaults + if 'defaults' in options: + defaults = dict(defaults, **options.pop('defaults')) + self.app.add_url_rule(rule, '%s.%s' % (self.blueprint.name, endpoint), + view_func, defaults=defaults, **options) + + +class Blueprint(_PackageBoundObject): + """Represents a blueprint. A blueprint is an object that records + functions that will be called with the + :class:`~flask.blueprints.BlueprintSetupState` later to register functions + or other things on the main application. See :ref:`blueprints` for more + information. + + .. versionadded:: 0.7 + """ + + warn_on_modifications = False + _got_registered_once = False + + #: Blueprint local JSON decoder class to use. + #: Set to ``None`` to use the app's :class:`~flask.app.Flask.json_encoder`. + json_encoder = None + #: Blueprint local JSON decoder class to use. + #: Set to ``None`` to use the app's :class:`~flask.app.Flask.json_decoder`. + json_decoder = None + + # TODO remove the next three attrs when Sphinx :inherited-members: works + # https://github.com/sphinx-doc/sphinx/issues/741 + + #: The name of the package or module that this app belongs to. Do not + #: change this once it is set by the constructor. + import_name = None + + #: Location of the template files to be added to the template lookup. + #: ``None`` if templates should not be added. + template_folder = None + + #: Absolute path to the package on the filesystem. Used to look up + #: resources contained in the package. + root_path = None + + def __init__(self, name, import_name, static_folder=None, + static_url_path=None, template_folder=None, + url_prefix=None, subdomain=None, url_defaults=None, + root_path=None): + _PackageBoundObject.__init__(self, import_name, template_folder, + root_path=root_path) + self.name = name + self.url_prefix = url_prefix + self.subdomain = subdomain + self.static_folder = static_folder + self.static_url_path = static_url_path + self.deferred_functions = [] + if url_defaults is None: + url_defaults = {} + self.url_values_defaults = url_defaults + + def record(self, func): + """Registers a function that is called when the blueprint is + registered on the application. This function is called with the + state as argument as returned by the :meth:`make_setup_state` + method. + """ + if self._got_registered_once and self.warn_on_modifications: + from warnings import warn + warn(Warning('The blueprint was already registered once ' + 'but is getting modified now. These changes ' + 'will not show up.')) + self.deferred_functions.append(func) + + def record_once(self, func): + """Works like :meth:`record` but wraps the function in another + function that will ensure the function is only called once. If the + blueprint is registered a second time on the application, the + function passed is not called. + """ + def wrapper(state): + if state.first_registration: + func(state) + return self.record(update_wrapper(wrapper, func)) + + def make_setup_state(self, app, options, first_registration=False): + """Creates an instance of :meth:`~flask.blueprints.BlueprintSetupState` + object that is later passed to the register callback functions. + Subclasses can override this to return a subclass of the setup state. + """ + return BlueprintSetupState(self, app, options, first_registration) + + def register(self, app, options, first_registration=False): + """Called by :meth:`Flask.register_blueprint` to register all views + and callbacks registered on the blueprint with the application. Creates + a :class:`.BlueprintSetupState` and calls each :meth:`record` callback + with it. + + :param app: The application this blueprint is being registered with. + :param options: Keyword arguments forwarded from + :meth:`~Flask.register_blueprint`. + :param first_registration: Whether this is the first time this + blueprint has been registered on the application. + """ + self._got_registered_once = True + state = self.make_setup_state(app, options, first_registration) + + if self.has_static_folder: + state.add_url_rule( + self.static_url_path + '/', + view_func=self.send_static_file, endpoint='static' + ) + + for deferred in self.deferred_functions: + deferred(state) + + def route(self, rule, **options): + """Like :meth:`Flask.route` but for a blueprint. The endpoint for the + :func:`url_for` function is prefixed with the name of the blueprint. + """ + def decorator(f): + endpoint = options.pop("endpoint", f.__name__) + self.add_url_rule(rule, endpoint, f, **options) + return f + return decorator + + def add_url_rule(self, rule, endpoint=None, view_func=None, **options): + """Like :meth:`Flask.add_url_rule` but for a blueprint. The endpoint for + the :func:`url_for` function is prefixed with the name of the blueprint. + """ + if endpoint: + assert '.' not in endpoint, "Blueprint endpoints should not contain dots" + if view_func and hasattr(view_func, '__name__'): + assert '.' not in view_func.__name__, "Blueprint view function name should not contain dots" + self.record(lambda s: + s.add_url_rule(rule, endpoint, view_func, **options)) + + def endpoint(self, endpoint): + """Like :meth:`Flask.endpoint` but for a blueprint. This does not + prefix the endpoint with the blueprint name, this has to be done + explicitly by the user of this method. If the endpoint is prefixed + with a `.` it will be registered to the current blueprint, otherwise + it's an application independent endpoint. + """ + def decorator(f): + def register_endpoint(state): + state.app.view_functions[endpoint] = f + self.record_once(register_endpoint) + return f + return decorator + + def app_template_filter(self, name=None): + """Register a custom template filter, available application wide. Like + :meth:`Flask.template_filter` but for a blueprint. + + :param name: the optional name of the filter, otherwise the + function name will be used. + """ + def decorator(f): + self.add_app_template_filter(f, name=name) + return f + return decorator + + def add_app_template_filter(self, f, name=None): + """Register a custom template filter, available application wide. Like + :meth:`Flask.add_template_filter` but for a blueprint. Works exactly + like the :meth:`app_template_filter` decorator. + + :param name: the optional name of the filter, otherwise the + function name will be used. + """ + def register_template(state): + state.app.jinja_env.filters[name or f.__name__] = f + self.record_once(register_template) + + def app_template_test(self, name=None): + """Register a custom template test, available application wide. Like + :meth:`Flask.template_test` but for a blueprint. + + .. versionadded:: 0.10 + + :param name: the optional name of the test, otherwise the + function name will be used. + """ + def decorator(f): + self.add_app_template_test(f, name=name) + return f + return decorator + + def add_app_template_test(self, f, name=None): + """Register a custom template test, available application wide. Like + :meth:`Flask.add_template_test` but for a blueprint. Works exactly + like the :meth:`app_template_test` decorator. + + .. versionadded:: 0.10 + + :param name: the optional name of the test, otherwise the + function name will be used. + """ + def register_template(state): + state.app.jinja_env.tests[name or f.__name__] = f + self.record_once(register_template) + + def app_template_global(self, name=None): + """Register a custom template global, available application wide. Like + :meth:`Flask.template_global` but for a blueprint. + + .. versionadded:: 0.10 + + :param name: the optional name of the global, otherwise the + function name will be used. + """ + def decorator(f): + self.add_app_template_global(f, name=name) + return f + return decorator + + def add_app_template_global(self, f, name=None): + """Register a custom template global, available application wide. Like + :meth:`Flask.add_template_global` but for a blueprint. Works exactly + like the :meth:`app_template_global` decorator. + + .. versionadded:: 0.10 + + :param name: the optional name of the global, otherwise the + function name will be used. + """ + def register_template(state): + state.app.jinja_env.globals[name or f.__name__] = f + self.record_once(register_template) + + def before_request(self, f): + """Like :meth:`Flask.before_request` but for a blueprint. This function + is only executed before each request that is handled by a function of + that blueprint. + """ + self.record_once(lambda s: s.app.before_request_funcs + .setdefault(self.name, []).append(f)) + return f + + def before_app_request(self, f): + """Like :meth:`Flask.before_request`. Such a function is executed + before each request, even if outside of a blueprint. + """ + self.record_once(lambda s: s.app.before_request_funcs + .setdefault(None, []).append(f)) + return f + + def before_app_first_request(self, f): + """Like :meth:`Flask.before_first_request`. Such a function is + executed before the first request to the application. + """ + self.record_once(lambda s: s.app.before_first_request_funcs.append(f)) + return f + + def after_request(self, f): + """Like :meth:`Flask.after_request` but for a blueprint. This function + is only executed after each request that is handled by a function of + that blueprint. + """ + self.record_once(lambda s: s.app.after_request_funcs + .setdefault(self.name, []).append(f)) + return f + + def after_app_request(self, f): + """Like :meth:`Flask.after_request` but for a blueprint. Such a function + is executed after each request, even if outside of the blueprint. + """ + self.record_once(lambda s: s.app.after_request_funcs + .setdefault(None, []).append(f)) + return f + + def teardown_request(self, f): + """Like :meth:`Flask.teardown_request` but for a blueprint. This + function is only executed when tearing down requests handled by a + function of that blueprint. Teardown request functions are executed + when the request context is popped, even when no actual request was + performed. + """ + self.record_once(lambda s: s.app.teardown_request_funcs + .setdefault(self.name, []).append(f)) + return f + + def teardown_app_request(self, f): + """Like :meth:`Flask.teardown_request` but for a blueprint. Such a + function is executed when tearing down each request, even if outside of + the blueprint. + """ + self.record_once(lambda s: s.app.teardown_request_funcs + .setdefault(None, []).append(f)) + return f + + def context_processor(self, f): + """Like :meth:`Flask.context_processor` but for a blueprint. This + function is only executed for requests handled by a blueprint. + """ + self.record_once(lambda s: s.app.template_context_processors + .setdefault(self.name, []).append(f)) + return f + + def app_context_processor(self, f): + """Like :meth:`Flask.context_processor` but for a blueprint. Such a + function is executed each request, even if outside of the blueprint. + """ + self.record_once(lambda s: s.app.template_context_processors + .setdefault(None, []).append(f)) + return f + + def app_errorhandler(self, code): + """Like :meth:`Flask.errorhandler` but for a blueprint. This + handler is used for all requests, even if outside of the blueprint. + """ + def decorator(f): + self.record_once(lambda s: s.app.errorhandler(code)(f)) + return f + return decorator + + def url_value_preprocessor(self, f): + """Registers a function as URL value preprocessor for this + blueprint. It's called before the view functions are called and + can modify the url values provided. + """ + self.record_once(lambda s: s.app.url_value_preprocessors + .setdefault(self.name, []).append(f)) + return f + + def url_defaults(self, f): + """Callback function for URL defaults for this blueprint. It's called + with the endpoint and values and should update the values passed + in place. + """ + self.record_once(lambda s: s.app.url_default_functions + .setdefault(self.name, []).append(f)) + return f + + def app_url_value_preprocessor(self, f): + """Same as :meth:`url_value_preprocessor` but application wide. + """ + self.record_once(lambda s: s.app.url_value_preprocessors + .setdefault(None, []).append(f)) + return f + + def app_url_defaults(self, f): + """Same as :meth:`url_defaults` but application wide. + """ + self.record_once(lambda s: s.app.url_default_functions + .setdefault(None, []).append(f)) + return f + + def errorhandler(self, code_or_exception): + """Registers an error handler that becomes active for this blueprint + only. Please be aware that routing does not happen local to a + blueprint so an error handler for 404 usually is not handled by + a blueprint unless it is caused inside a view function. Another + special case is the 500 internal server error which is always looked + up from the application. + + Otherwise works as the :meth:`~flask.Flask.errorhandler` decorator + of the :class:`~flask.Flask` object. + """ + def decorator(f): + self.record_once(lambda s: s.app._register_error_handler( + self.name, code_or_exception, f)) + return f + return decorator + + def register_error_handler(self, code_or_exception, f): + """Non-decorator version of the :meth:`errorhandler` error attach + function, akin to the :meth:`~flask.Flask.register_error_handler` + application-wide function of the :class:`~flask.Flask` object but + for error handlers limited to this blueprint. + + .. versionadded:: 0.11 + """ + self.record_once(lambda s: s.app._register_error_handler( + self.name, code_or_exception, f)) diff --git a/flask/venv/lib/python3.6/site-packages/flask/cli.py b/flask/venv/lib/python3.6/site-packages/flask/cli.py new file mode 100644 index 0000000..efc1733 --- /dev/null +++ b/flask/venv/lib/python3.6/site-packages/flask/cli.py @@ -0,0 +1,898 @@ +# -*- coding: utf-8 -*- +""" + flask.cli + ~~~~~~~~~ + + A simple command line application to run flask apps. + + :copyright: © 2010 by the Pallets team. + :license: BSD, see LICENSE for more details. +""" + +from __future__ import print_function + +import ast +import inspect +import os +import re +import ssl +import sys +import traceback +from functools import update_wrapper +from operator import attrgetter +from threading import Lock, Thread + +import click +from werkzeug.utils import import_string + +from . import __version__ +from ._compat import getargspec, iteritems, reraise, text_type +from .globals import current_app +from .helpers import get_debug_flag, get_env, get_load_dotenv + +try: + import dotenv +except ImportError: + dotenv = None + + +class NoAppException(click.UsageError): + """Raised if an application cannot be found or loaded.""" + + +def find_best_app(script_info, module): + """Given a module instance this tries to find the best possible + application in the module or raises an exception. + """ + from . import Flask + + # Search for the most common names first. + for attr_name in ('app', 'application'): + app = getattr(module, attr_name, None) + + if isinstance(app, Flask): + return app + + # Otherwise find the only object that is a Flask instance. + matches = [ + v for k, v in iteritems(module.__dict__) if isinstance(v, Flask) + ] + + if len(matches) == 1: + return matches[0] + elif len(matches) > 1: + raise NoAppException( + 'Detected multiple Flask applications in module "{module}". Use ' + '"FLASK_APP={module}:name" to specify the correct ' + 'one.'.format(module=module.__name__) + ) + + # Search for app factory functions. + for attr_name in ('create_app', 'make_app'): + app_factory = getattr(module, attr_name, None) + + if inspect.isfunction(app_factory): + try: + app = call_factory(script_info, app_factory) + + if isinstance(app, Flask): + return app + except TypeError: + if not _called_with_wrong_args(app_factory): + raise + raise NoAppException( + 'Detected factory "{factory}" in module "{module}", but ' + 'could not call it without arguments. Use ' + '"FLASK_APP=\'{module}:{factory}(args)\'" to specify ' + 'arguments.'.format( + factory=attr_name, module=module.__name__ + ) + ) + + raise NoAppException( + 'Failed to find Flask application or factory in module "{module}". ' + 'Use "FLASK_APP={module}:name to specify one.'.format( + module=module.__name__ + ) + ) + + +def call_factory(script_info, app_factory, arguments=()): + """Takes an app factory, a ``script_info` object and optionally a tuple + of arguments. Checks for the existence of a script_info argument and calls + the app_factory depending on that and the arguments provided. + """ + args_spec = getargspec(app_factory) + arg_names = args_spec.args + arg_defaults = args_spec.defaults + + if 'script_info' in arg_names: + return app_factory(*arguments, script_info=script_info) + elif arguments: + return app_factory(*arguments) + elif not arguments and len(arg_names) == 1 and arg_defaults is None: + return app_factory(script_info) + + return app_factory() + + +def _called_with_wrong_args(factory): + """Check whether calling a function raised a ``TypeError`` because + the call failed or because something in the factory raised the + error. + + :param factory: the factory function that was called + :return: true if the call failed + """ + tb = sys.exc_info()[2] + + try: + while tb is not None: + if tb.tb_frame.f_code is factory.__code__: + # in the factory, it was called successfully + return False + + tb = tb.tb_next + + # didn't reach the factory + return True + finally: + del tb + + +def find_app_by_string(script_info, module, app_name): + """Checks if the given string is a variable name or a function. If it is a + function, it checks for specified arguments and whether it takes a + ``script_info`` argument and calls the function with the appropriate + arguments. + """ + from flask import Flask + match = re.match(r'^ *([^ ()]+) *(?:\((.*?) *,? *\))? *$', app_name) + + if not match: + raise NoAppException( + '"{name}" is not a valid variable name or function ' + 'expression.'.format(name=app_name) + ) + + name, args = match.groups() + + try: + attr = getattr(module, name) + except AttributeError as e: + raise NoAppException(e.args[0]) + + if inspect.isfunction(attr): + if args: + try: + args = ast.literal_eval('({args},)'.format(args=args)) + except (ValueError, SyntaxError)as e: + raise NoAppException( + 'Could not parse the arguments in ' + '"{app_name}".'.format(e=e, app_name=app_name) + ) + else: + args = () + + try: + app = call_factory(script_info, attr, args) + except TypeError as e: + if not _called_with_wrong_args(attr): + raise + + raise NoAppException( + '{e}\nThe factory "{app_name}" in module "{module}" could not ' + 'be called with the specified arguments.'.format( + e=e, app_name=app_name, module=module.__name__ + ) + ) + else: + app = attr + + if isinstance(app, Flask): + return app + + raise NoAppException( + 'A valid Flask application was not obtained from ' + '"{module}:{app_name}".'.format( + module=module.__name__, app_name=app_name + ) + ) + + +def prepare_import(path): + """Given a filename this will try to calculate the python path, add it + to the search path and return the actual module name that is expected. + """ + path = os.path.realpath(path) + + if os.path.splitext(path)[1] == '.py': + path = os.path.splitext(path)[0] + + if os.path.basename(path) == '__init__': + path = os.path.dirname(path) + + module_name = [] + + # move up until outside package structure (no __init__.py) + while True: + path, name = os.path.split(path) + module_name.append(name) + + if not os.path.exists(os.path.join(path, '__init__.py')): + break + + if sys.path[0] != path: + sys.path.insert(0, path) + + return '.'.join(module_name[::-1]) + + +def locate_app(script_info, module_name, app_name, raise_if_not_found=True): + __traceback_hide__ = True + + try: + __import__(module_name) + except ImportError: + # Reraise the ImportError if it occurred within the imported module. + # Determine this by checking whether the trace has a depth > 1. + if sys.exc_info()[-1].tb_next: + raise NoAppException( + 'While importing "{name}", an ImportError was raised:' + '\n\n{tb}'.format(name=module_name, tb=traceback.format_exc()) + ) + elif raise_if_not_found: + raise NoAppException( + 'Could not import "{name}".'.format(name=module_name) + ) + else: + return + + module = sys.modules[module_name] + + if app_name is None: + return find_best_app(script_info, module) + else: + return find_app_by_string(script_info, module, app_name) + + +def get_version(ctx, param, value): + if not value or ctx.resilient_parsing: + return + message = 'Flask %(version)s\nPython %(python_version)s' + click.echo(message % { + 'version': __version__, + 'python_version': sys.version, + }, color=ctx.color) + ctx.exit() + + +version_option = click.Option( + ['--version'], + help='Show the flask version', + expose_value=False, + callback=get_version, + is_flag=True, + is_eager=True +) + + +class DispatchingApp(object): + """Special application that dispatches to a Flask application which + is imported by name in a background thread. If an error happens + it is recorded and shown as part of the WSGI handling which in case + of the Werkzeug debugger means that it shows up in the browser. + """ + + def __init__(self, loader, use_eager_loading=False): + self.loader = loader + self._app = None + self._lock = Lock() + self._bg_loading_exc_info = None + if use_eager_loading: + self._load_unlocked() + else: + self._load_in_background() + + def _load_in_background(self): + def _load_app(): + __traceback_hide__ = True + with self._lock: + try: + self._load_unlocked() + except Exception: + self._bg_loading_exc_info = sys.exc_info() + t = Thread(target=_load_app, args=()) + t.start() + + def _flush_bg_loading_exception(self): + __traceback_hide__ = True + exc_info = self._bg_loading_exc_info + if exc_info is not None: + self._bg_loading_exc_info = None + reraise(*exc_info) + + def _load_unlocked(self): + __traceback_hide__ = True + self._app = rv = self.loader() + self._bg_loading_exc_info = None + return rv + + def __call__(self, environ, start_response): + __traceback_hide__ = True + if self._app is not None: + return self._app(environ, start_response) + self._flush_bg_loading_exception() + with self._lock: + if self._app is not None: + rv = self._app + else: + rv = self._load_unlocked() + return rv(environ, start_response) + + +class ScriptInfo(object): + """Help object to deal with Flask applications. This is usually not + necessary to interface with as it's used internally in the dispatching + to click. In future versions of Flask this object will most likely play + a bigger role. Typically it's created automatically by the + :class:`FlaskGroup` but you can also manually create it and pass it + onwards as click object. + """ + + def __init__(self, app_import_path=None, create_app=None): + #: Optionally the import path for the Flask application. + self.app_import_path = app_import_path or os.environ.get('FLASK_APP') + #: Optionally a function that is passed the script info to create + #: the instance of the application. + self.create_app = create_app + #: A dictionary with arbitrary data that can be associated with + #: this script info. + self.data = {} + self._loaded_app = None + + def load_app(self): + """Loads the Flask app (if not yet loaded) and returns it. Calling + this multiple times will just result in the already loaded app to + be returned. + """ + __traceback_hide__ = True + + if self._loaded_app is not None: + return self._loaded_app + + app = None + + if self.create_app is not None: + app = call_factory(self, self.create_app) + else: + if self.app_import_path: + path, name = (self.app_import_path.split(':', 1) + [None])[:2] + import_name = prepare_import(path) + app = locate_app(self, import_name, name) + else: + for path in ('wsgi.py', 'app.py'): + import_name = prepare_import(path) + app = locate_app(self, import_name, None, + raise_if_not_found=False) + + if app: + break + + if not app: + raise NoAppException( + 'Could not locate a Flask application. You did not provide ' + 'the "FLASK_APP" environment variable, and a "wsgi.py" or ' + '"app.py" module was not found in the current directory.' + ) + + debug = get_debug_flag() + + # Update the app's debug flag through the descriptor so that other + # values repopulate as well. + if debug is not None: + app.debug = debug + + self._loaded_app = app + return app + + +pass_script_info = click.make_pass_decorator(ScriptInfo, ensure=True) + + +def with_appcontext(f): + """Wraps a callback so that it's guaranteed to be executed with the + script's application context. If callbacks are registered directly + to the ``app.cli`` object then they are wrapped with this function + by default unless it's disabled. + """ + @click.pass_context + def decorator(__ctx, *args, **kwargs): + with __ctx.ensure_object(ScriptInfo).load_app().app_context(): + return __ctx.invoke(f, *args, **kwargs) + return update_wrapper(decorator, f) + + +class AppGroup(click.Group): + """This works similar to a regular click :class:`~click.Group` but it + changes the behavior of the :meth:`command` decorator so that it + automatically wraps the functions in :func:`with_appcontext`. + + Not to be confused with :class:`FlaskGroup`. + """ + + def command(self, *args, **kwargs): + """This works exactly like the method of the same name on a regular + :class:`click.Group` but it wraps callbacks in :func:`with_appcontext` + unless it's disabled by passing ``with_appcontext=False``. + """ + wrap_for_ctx = kwargs.pop('with_appcontext', True) + def decorator(f): + if wrap_for_ctx: + f = with_appcontext(f) + return click.Group.command(self, *args, **kwargs)(f) + return decorator + + def group(self, *args, **kwargs): + """This works exactly like the method of the same name on a regular + :class:`click.Group` but it defaults the group class to + :class:`AppGroup`. + """ + kwargs.setdefault('cls', AppGroup) + return click.Group.group(self, *args, **kwargs) + + +class FlaskGroup(AppGroup): + """Special subclass of the :class:`AppGroup` group that supports + loading more commands from the configured Flask app. Normally a + developer does not have to interface with this class but there are + some very advanced use cases for which it makes sense to create an + instance of this. + + For information as of why this is useful see :ref:`custom-scripts`. + + :param add_default_commands: if this is True then the default run and + shell commands wil be added. + :param add_version_option: adds the ``--version`` option. + :param create_app: an optional callback that is passed the script info and + returns the loaded app. + :param load_dotenv: Load the nearest :file:`.env` and :file:`.flaskenv` + files to set environment variables. Will also change the working + directory to the directory containing the first file found. + + .. versionchanged:: 1.0 + If installed, python-dotenv will be used to load environment variables + from :file:`.env` and :file:`.flaskenv` files. + """ + + def __init__(self, add_default_commands=True, create_app=None, + add_version_option=True, load_dotenv=True, **extra): + params = list(extra.pop('params', None) or ()) + + if add_version_option: + params.append(version_option) + + AppGroup.__init__(self, params=params, **extra) + self.create_app = create_app + self.load_dotenv = load_dotenv + + if add_default_commands: + self.add_command(run_command) + self.add_command(shell_command) + self.add_command(routes_command) + + self._loaded_plugin_commands = False + + def _load_plugin_commands(self): + if self._loaded_plugin_commands: + return + try: + import pkg_resources + except ImportError: + self._loaded_plugin_commands = True + return + + for ep in pkg_resources.iter_entry_points('flask.commands'): + self.add_command(ep.load(), ep.name) + self._loaded_plugin_commands = True + + def get_command(self, ctx, name): + self._load_plugin_commands() + + # We load built-in commands first as these should always be the + # same no matter what the app does. If the app does want to + # override this it needs to make a custom instance of this group + # and not attach the default commands. + # + # This also means that the script stays functional in case the + # application completely fails. + rv = AppGroup.get_command(self, ctx, name) + if rv is not None: + return rv + + info = ctx.ensure_object(ScriptInfo) + try: + rv = info.load_app().cli.get_command(ctx, name) + if rv is not None: + return rv + except NoAppException: + pass + + def list_commands(self, ctx): + self._load_plugin_commands() + + # The commands available is the list of both the application (if + # available) plus the builtin commands. + rv = set(click.Group.list_commands(self, ctx)) + info = ctx.ensure_object(ScriptInfo) + try: + rv.update(info.load_app().cli.list_commands(ctx)) + except Exception: + # Here we intentionally swallow all exceptions as we don't + # want the help page to break if the app does not exist. + # If someone attempts to use the command we try to create + # the app again and this will give us the error. + # However, we will not do so silently because that would confuse + # users. + traceback.print_exc() + return sorted(rv) + + def main(self, *args, **kwargs): + # Set a global flag that indicates that we were invoked from the + # command line interface. This is detected by Flask.run to make the + # call into a no-op. This is necessary to avoid ugly errors when the + # script that is loaded here also attempts to start a server. + os.environ['FLASK_RUN_FROM_CLI'] = 'true' + + if get_load_dotenv(self.load_dotenv): + load_dotenv() + + obj = kwargs.get('obj') + + if obj is None: + obj = ScriptInfo(create_app=self.create_app) + + kwargs['obj'] = obj + kwargs.setdefault('auto_envvar_prefix', 'FLASK') + return super(FlaskGroup, self).main(*args, **kwargs) + + +def _path_is_ancestor(path, other): + """Take ``other`` and remove the length of ``path`` from it. Then join it + to ``path``. If it is the original value, ``path`` is an ancestor of + ``other``.""" + return os.path.join(path, other[len(path):].lstrip(os.sep)) == other + + +def load_dotenv(path=None): + """Load "dotenv" files in order of precedence to set environment variables. + + If an env var is already set it is not overwritten, so earlier files in the + list are preferred over later files. + + Changes the current working directory to the location of the first file + found, with the assumption that it is in the top level project directory + and will be where the Python path should import local packages from. + + This is a no-op if `python-dotenv`_ is not installed. + + .. _python-dotenv: https://github.com/theskumar/python-dotenv#readme + + :param path: Load the file at this location instead of searching. + :return: ``True`` if a file was loaded. + + .. versionadded:: 1.0 + """ + if dotenv is None: + if path or os.path.exists('.env') or os.path.exists('.flaskenv'): + click.secho( + ' * Tip: There are .env files present.' + ' Do "pip install python-dotenv" to use them.', + fg='yellow') + return + + if path is not None: + return dotenv.load_dotenv(path) + + new_dir = None + + for name in ('.env', '.flaskenv'): + path = dotenv.find_dotenv(name, usecwd=True) + + if not path: + continue + + if new_dir is None: + new_dir = os.path.dirname(path) + + dotenv.load_dotenv(path) + + if new_dir and os.getcwd() != new_dir: + os.chdir(new_dir) + + return new_dir is not None # at least one file was located and loaded + + +def show_server_banner(env, debug, app_import_path, eager_loading): + """Show extra startup messages the first time the server is run, + ignoring the reloader. + """ + if os.environ.get('WERKZEUG_RUN_MAIN') == 'true': + return + + if app_import_path is not None: + message = ' * Serving Flask app "{0}"'.format(app_import_path) + + if not eager_loading: + message += ' (lazy loading)' + + click.echo(message) + + click.echo(' * Environment: {0}'.format(env)) + + if env == 'production': + click.secho( + ' WARNING: Do not use the development server in a production' + ' environment.', fg='red') + click.secho(' Use a production WSGI server instead.', dim=True) + + if debug is not None: + click.echo(' * Debug mode: {0}'.format('on' if debug else 'off')) + + +class CertParamType(click.ParamType): + """Click option type for the ``--cert`` option. Allows either an + existing file, the string ``'adhoc'``, or an import for a + :class:`~ssl.SSLContext` object. + """ + + name = 'path' + + def __init__(self): + self.path_type = click.Path( + exists=True, dir_okay=False, resolve_path=True) + + def convert(self, value, param, ctx): + try: + return self.path_type(value, param, ctx) + except click.BadParameter: + value = click.STRING(value, param, ctx).lower() + + if value == 'adhoc': + try: + import OpenSSL + except ImportError: + raise click.BadParameter( + 'Using ad-hoc certificates requires pyOpenSSL.', + ctx, param) + + return value + + obj = import_string(value, silent=True) + + if sys.version_info < (2, 7): + if obj: + return obj + else: + if isinstance(obj, ssl.SSLContext): + return obj + + raise + + +def _validate_key(ctx, param, value): + """The ``--key`` option must be specified when ``--cert`` is a file. + Modifies the ``cert`` param to be a ``(cert, key)`` pair if needed. + """ + cert = ctx.params.get('cert') + is_adhoc = cert == 'adhoc' + + if sys.version_info < (2, 7): + is_context = cert and not isinstance(cert, (text_type, bytes)) + else: + is_context = isinstance(cert, ssl.SSLContext) + + if value is not None: + if is_adhoc: + raise click.BadParameter( + 'When "--cert" is "adhoc", "--key" is not used.', + ctx, param) + + if is_context: + raise click.BadParameter( + 'When "--cert" is an SSLContext object, "--key is not used.', + ctx, param) + + if not cert: + raise click.BadParameter( + '"--cert" must also be specified.', + ctx, param) + + ctx.params['cert'] = cert, value + + else: + if cert and not (is_adhoc or is_context): + raise click.BadParameter( + 'Required when using "--cert".', + ctx, param) + + return value + + +@click.command('run', short_help='Runs a development server.') +@click.option('--host', '-h', default='127.0.0.1', + help='The interface to bind to.') +@click.option('--port', '-p', default=5000, + help='The port to bind to.') +@click.option('--cert', type=CertParamType(), + help='Specify a certificate file to use HTTPS.') +@click.option('--key', + type=click.Path(exists=True, dir_okay=False, resolve_path=True), + callback=_validate_key, expose_value=False, + help='The key file to use when specifying a certificate.') +@click.option('--reload/--no-reload', default=None, + help='Enable or disable the reloader. By default the reloader ' + 'is active if debug is enabled.') +@click.option('--debugger/--no-debugger', default=None, + help='Enable or disable the debugger. By default the debugger ' + 'is active if debug is enabled.') +@click.option('--eager-loading/--lazy-loader', default=None, + help='Enable or disable eager loading. By default eager ' + 'loading is enabled if the reloader is disabled.') +@click.option('--with-threads/--without-threads', default=True, + help='Enable or disable multithreading.') +@pass_script_info +def run_command(info, host, port, reload, debugger, eager_loading, + with_threads, cert): + """Run a local development server. + + This server is for development purposes only. It does not provide + the stability, security, or performance of production WSGI servers. + + The reloader and debugger are enabled by default if + FLASK_ENV=development or FLASK_DEBUG=1. + """ + debug = get_debug_flag() + + if reload is None: + reload = debug + + if debugger is None: + debugger = debug + + if eager_loading is None: + eager_loading = not reload + + show_server_banner(get_env(), debug, info.app_import_path, eager_loading) + app = DispatchingApp(info.load_app, use_eager_loading=eager_loading) + + from werkzeug.serving import run_simple + run_simple(host, port, app, use_reloader=reload, use_debugger=debugger, + threaded=with_threads, ssl_context=cert) + + +@click.command('shell', short_help='Runs a shell in the app context.') +@with_appcontext +def shell_command(): + """Runs an interactive Python shell in the context of a given + Flask application. The application will populate the default + namespace of this shell according to it's configuration. + + This is useful for executing small snippets of management code + without having to manually configure the application. + """ + import code + from flask.globals import _app_ctx_stack + app = _app_ctx_stack.top.app + banner = 'Python %s on %s\nApp: %s [%s]\nInstance: %s' % ( + sys.version, + sys.platform, + app.import_name, + app.env, + app.instance_path, + ) + ctx = {} + + # Support the regular Python interpreter startup script if someone + # is using it. + startup = os.environ.get('PYTHONSTARTUP') + if startup and os.path.isfile(startup): + with open(startup, 'r') as f: + eval(compile(f.read(), startup, 'exec'), ctx) + + ctx.update(app.make_shell_context()) + + code.interact(banner=banner, local=ctx) + + +@click.command('routes', short_help='Show the routes for the app.') +@click.option( + '--sort', '-s', + type=click.Choice(('endpoint', 'methods', 'rule', 'match')), + default='endpoint', + help=( + 'Method to sort routes by. "match" is the order that Flask will match ' + 'routes when dispatching a request.' + ) +) +@click.option( + '--all-methods', + is_flag=True, + help="Show HEAD and OPTIONS methods." +) +@with_appcontext +def routes_command(sort, all_methods): + """Show all registered routes with endpoints and methods.""" + + rules = list(current_app.url_map.iter_rules()) + if not rules: + click.echo('No routes were registered.') + return + + ignored_methods = set(() if all_methods else ('HEAD', 'OPTIONS')) + + if sort in ('endpoint', 'rule'): + rules = sorted(rules, key=attrgetter(sort)) + elif sort == 'methods': + rules = sorted(rules, key=lambda rule: sorted(rule.methods)) + + rule_methods = [ + ', '.join(sorted(rule.methods - ignored_methods)) for rule in rules + ] + + headers = ('Endpoint', 'Methods', 'Rule') + widths = ( + max(len(rule.endpoint) for rule in rules), + max(len(methods) for methods in rule_methods), + max(len(rule.rule) for rule in rules), + ) + widths = [max(len(h), w) for h, w in zip(headers, widths)] + row = '{{0:<{0}}} {{1:<{1}}} {{2:<{2}}}'.format(*widths) + + click.echo(row.format(*headers).strip()) + click.echo(row.format(*('-' * width for width in widths))) + + for rule, methods in zip(rules, rule_methods): + click.echo(row.format(rule.endpoint, methods, rule.rule).rstrip()) + + +cli = FlaskGroup(help="""\ +A general utility script for Flask applications. + +Provides commands from Flask, extensions, and the application. Loads the +application defined in the FLASK_APP environment variable, or from a wsgi.py +file. Setting the FLASK_ENV environment variable to 'development' will enable +debug mode. + +\b + {prefix}{cmd} FLASK_APP=hello.py + {prefix}{cmd} FLASK_ENV=development + {prefix}flask run +""".format( + cmd='export' if os.name == 'posix' else 'set', + prefix='$ ' if os.name == 'posix' else '> ' +)) + + +def main(as_module=False): + args = sys.argv[1:] + + if as_module: + this_module = 'flask' + + if sys.version_info < (2, 7): + this_module += '.cli' + + name = 'python -m ' + this_module + + # Python rewrites "python -m flask" to the path to the file in argv. + # Restore the original command so that the reloader works. + sys.argv = ['-m', this_module] + args + else: + name = None + + cli.main(args=args, prog_name=name) + + +if __name__ == '__main__': + main(as_module=True) diff --git a/flask/venv/lib/python3.6/site-packages/flask/config.py b/flask/venv/lib/python3.6/site-packages/flask/config.py new file mode 100644 index 0000000..d6074ba --- /dev/null +++ b/flask/venv/lib/python3.6/site-packages/flask/config.py @@ -0,0 +1,265 @@ +# -*- coding: utf-8 -*- +""" + flask.config + ~~~~~~~~~~~~ + + Implements the configuration related objects. + + :copyright: © 2010 by the Pallets team. + :license: BSD, see LICENSE for more details. +""" + +import os +import types +import errno + +from werkzeug.utils import import_string +from ._compat import string_types, iteritems +from . import json + + +class ConfigAttribute(object): + """Makes an attribute forward to the config""" + + def __init__(self, name, get_converter=None): + self.__name__ = name + self.get_converter = get_converter + + def __get__(self, obj, type=None): + if obj is None: + return self + rv = obj.config[self.__name__] + if self.get_converter is not None: + rv = self.get_converter(rv) + return rv + + def __set__(self, obj, value): + obj.config[self.__name__] = value + + +class Config(dict): + """Works exactly like a dict but provides ways to fill it from files + or special dictionaries. There are two common patterns to populate the + config. + + Either you can fill the config from a config file:: + + app.config.from_pyfile('yourconfig.cfg') + + Or alternatively you can define the configuration options in the + module that calls :meth:`from_object` or provide an import path to + a module that should be loaded. It is also possible to tell it to + use the same module and with that provide the configuration values + just before the call:: + + DEBUG = True + SECRET_KEY = 'development key' + app.config.from_object(__name__) + + In both cases (loading from any Python file or loading from modules), + only uppercase keys are added to the config. This makes it possible to use + lowercase values in the config file for temporary values that are not added + to the config or to define the config keys in the same file that implements + the application. + + Probably the most interesting way to load configurations is from an + environment variable pointing to a file:: + + app.config.from_envvar('YOURAPPLICATION_SETTINGS') + + In this case before launching the application you have to set this + environment variable to the file you want to use. On Linux and OS X + use the export statement:: + + export YOURAPPLICATION_SETTINGS='/path/to/config/file' + + On windows use `set` instead. + + :param root_path: path to which files are read relative from. When the + config object is created by the application, this is + the application's :attr:`~flask.Flask.root_path`. + :param defaults: an optional dictionary of default values + """ + + def __init__(self, root_path, defaults=None): + dict.__init__(self, defaults or {}) + self.root_path = root_path + + def from_envvar(self, variable_name, silent=False): + """Loads a configuration from an environment variable pointing to + a configuration file. This is basically just a shortcut with nicer + error messages for this line of code:: + + app.config.from_pyfile(os.environ['YOURAPPLICATION_SETTINGS']) + + :param variable_name: name of the environment variable + :param silent: set to ``True`` if you want silent failure for missing + files. + :return: bool. ``True`` if able to load config, ``False`` otherwise. + """ + rv = os.environ.get(variable_name) + if not rv: + if silent: + return False + raise RuntimeError('The environment variable %r is not set ' + 'and as such configuration could not be ' + 'loaded. Set this variable and make it ' + 'point to a configuration file' % + variable_name) + return self.from_pyfile(rv, silent=silent) + + def from_pyfile(self, filename, silent=False): + """Updates the values in the config from a Python file. This function + behaves as if the file was imported as module with the + :meth:`from_object` function. + + :param filename: the filename of the config. This can either be an + absolute filename or a filename relative to the + root path. + :param silent: set to ``True`` if you want silent failure for missing + files. + + .. versionadded:: 0.7 + `silent` parameter. + """ + filename = os.path.join(self.root_path, filename) + d = types.ModuleType('config') + d.__file__ = filename + try: + with open(filename, mode='rb') as config_file: + exec(compile(config_file.read(), filename, 'exec'), d.__dict__) + except IOError as e: + if silent and e.errno in ( + errno.ENOENT, errno.EISDIR, errno.ENOTDIR + ): + return False + e.strerror = 'Unable to load configuration file (%s)' % e.strerror + raise + self.from_object(d) + return True + + def from_object(self, obj): + """Updates the values from the given object. An object can be of one + of the following two types: + + - a string: in this case the object with that name will be imported + - an actual object reference: that object is used directly + + Objects are usually either modules or classes. :meth:`from_object` + loads only the uppercase attributes of the module/class. A ``dict`` + object will not work with :meth:`from_object` because the keys of a + ``dict`` are not attributes of the ``dict`` class. + + Example of module-based configuration:: + + app.config.from_object('yourapplication.default_config') + from yourapplication import default_config + app.config.from_object(default_config) + + You should not use this function to load the actual configuration but + rather configuration defaults. The actual config should be loaded + with :meth:`from_pyfile` and ideally from a location not within the + package because the package might be installed system wide. + + See :ref:`config-dev-prod` for an example of class-based configuration + using :meth:`from_object`. + + :param obj: an import name or object + """ + if isinstance(obj, string_types): + obj = import_string(obj) + for key in dir(obj): + if key.isupper(): + self[key] = getattr(obj, key) + + def from_json(self, filename, silent=False): + """Updates the values in the config from a JSON file. This function + behaves as if the JSON object was a dictionary and passed to the + :meth:`from_mapping` function. + + :param filename: the filename of the JSON file. This can either be an + absolute filename or a filename relative to the + root path. + :param silent: set to ``True`` if you want silent failure for missing + files. + + .. versionadded:: 0.11 + """ + filename = os.path.join(self.root_path, filename) + + try: + with open(filename) as json_file: + obj = json.loads(json_file.read()) + except IOError as e: + if silent and e.errno in (errno.ENOENT, errno.EISDIR): + return False + e.strerror = 'Unable to load configuration file (%s)' % e.strerror + raise + return self.from_mapping(obj) + + def from_mapping(self, *mapping, **kwargs): + """Updates the config like :meth:`update` ignoring items with non-upper + keys. + + .. versionadded:: 0.11 + """ + mappings = [] + if len(mapping) == 1: + if hasattr(mapping[0], 'items'): + mappings.append(mapping[0].items()) + else: + mappings.append(mapping[0]) + elif len(mapping) > 1: + raise TypeError( + 'expected at most 1 positional argument, got %d' % len(mapping) + ) + mappings.append(kwargs.items()) + for mapping in mappings: + for (key, value) in mapping: + if key.isupper(): + self[key] = value + return True + + def get_namespace(self, namespace, lowercase=True, trim_namespace=True): + """Returns a dictionary containing a subset of configuration options + that match the specified namespace/prefix. Example usage:: + + app.config['IMAGE_STORE_TYPE'] = 'fs' + app.config['IMAGE_STORE_PATH'] = '/var/app/images' + app.config['IMAGE_STORE_BASE_URL'] = 'http://img.website.com' + image_store_config = app.config.get_namespace('IMAGE_STORE_') + + The resulting dictionary `image_store_config` would look like:: + + { + 'type': 'fs', + 'path': '/var/app/images', + 'base_url': 'http://img.website.com' + } + + This is often useful when configuration options map directly to + keyword arguments in functions or class constructors. + + :param namespace: a configuration namespace + :param lowercase: a flag indicating if the keys of the resulting + dictionary should be lowercase + :param trim_namespace: a flag indicating if the keys of the resulting + dictionary should not include the namespace + + .. versionadded:: 0.11 + """ + rv = {} + for k, v in iteritems(self): + if not k.startswith(namespace): + continue + if trim_namespace: + key = k[len(namespace):] + else: + key = k + if lowercase: + key = key.lower() + rv[key] = v + return rv + + def __repr__(self): + return '<%s %s>' % (self.__class__.__name__, dict.__repr__(self)) diff --git a/flask/venv/lib/python3.6/site-packages/flask/ctx.py b/flask/venv/lib/python3.6/site-packages/flask/ctx.py new file mode 100644 index 0000000..8472c92 --- /dev/null +++ b/flask/venv/lib/python3.6/site-packages/flask/ctx.py @@ -0,0 +1,457 @@ +# -*- coding: utf-8 -*- +""" + flask.ctx + ~~~~~~~~~ + + Implements the objects required to keep the context. + + :copyright: © 2010 by the Pallets team. + :license: BSD, see LICENSE for more details. +""" + +import sys +from functools import update_wrapper + +from werkzeug.exceptions import HTTPException + +from .globals import _request_ctx_stack, _app_ctx_stack +from .signals import appcontext_pushed, appcontext_popped +from ._compat import BROKEN_PYPY_CTXMGR_EXIT, reraise + + +# a singleton sentinel value for parameter defaults +_sentinel = object() + + +class _AppCtxGlobals(object): + """A plain object. Used as a namespace for storing data during an + application context. + + Creating an app context automatically creates this object, which is + made available as the :data:`g` proxy. + + .. describe:: 'key' in g + + Check whether an attribute is present. + + .. versionadded:: 0.10 + + .. describe:: iter(g) + + Return an iterator over the attribute names. + + .. versionadded:: 0.10 + """ + + def get(self, name, default=None): + """Get an attribute by name, or a default value. Like + :meth:`dict.get`. + + :param name: Name of attribute to get. + :param default: Value to return if the attribute is not present. + + .. versionadded:: 0.10 + """ + return self.__dict__.get(name, default) + + def pop(self, name, default=_sentinel): + """Get and remove an attribute by name. Like :meth:`dict.pop`. + + :param name: Name of attribute to pop. + :param default: Value to return if the attribute is not present, + instead of raise a ``KeyError``. + + .. versionadded:: 0.11 + """ + if default is _sentinel: + return self.__dict__.pop(name) + else: + return self.__dict__.pop(name, default) + + def setdefault(self, name, default=None): + """Get the value of an attribute if it is present, otherwise + set and return a default value. Like :meth:`dict.setdefault`. + + :param name: Name of attribute to get. + :param: default: Value to set and return if the attribute is not + present. + + .. versionadded:: 0.11 + """ + return self.__dict__.setdefault(name, default) + + def __contains__(self, item): + return item in self.__dict__ + + def __iter__(self): + return iter(self.__dict__) + + def __repr__(self): + top = _app_ctx_stack.top + if top is not None: + return '' % top.app.name + return object.__repr__(self) + + +def after_this_request(f): + """Executes a function after this request. This is useful to modify + response objects. The function is passed the response object and has + to return the same or a new one. + + Example:: + + @app.route('/') + def index(): + @after_this_request + def add_header(response): + response.headers['X-Foo'] = 'Parachute' + return response + return 'Hello World!' + + This is more useful if a function other than the view function wants to + modify a response. For instance think of a decorator that wants to add + some headers without converting the return value into a response object. + + .. versionadded:: 0.9 + """ + _request_ctx_stack.top._after_request_functions.append(f) + return f + + +def copy_current_request_context(f): + """A helper function that decorates a function to retain the current + request context. This is useful when working with greenlets. The moment + the function is decorated a copy of the request context is created and + then pushed when the function is called. + + Example:: + + import gevent + from flask import copy_current_request_context + + @app.route('/') + def index(): + @copy_current_request_context + def do_some_work(): + # do some work here, it can access flask.request like you + # would otherwise in the view function. + ... + gevent.spawn(do_some_work) + return 'Regular response' + + .. versionadded:: 0.10 + """ + top = _request_ctx_stack.top + if top is None: + raise RuntimeError('This decorator can only be used at local scopes ' + 'when a request context is on the stack. For instance within ' + 'view functions.') + reqctx = top.copy() + def wrapper(*args, **kwargs): + with reqctx: + return f(*args, **kwargs) + return update_wrapper(wrapper, f) + + +def has_request_context(): + """If you have code that wants to test if a request context is there or + not this function can be used. For instance, you may want to take advantage + of request information if the request object is available, but fail + silently if it is unavailable. + + :: + + class User(db.Model): + + def __init__(self, username, remote_addr=None): + self.username = username + if remote_addr is None and has_request_context(): + remote_addr = request.remote_addr + self.remote_addr = remote_addr + + Alternatively you can also just test any of the context bound objects + (such as :class:`request` or :class:`g` for truthness):: + + class User(db.Model): + + def __init__(self, username, remote_addr=None): + self.username = username + if remote_addr is None and request: + remote_addr = request.remote_addr + self.remote_addr = remote_addr + + .. versionadded:: 0.7 + """ + return _request_ctx_stack.top is not None + + +def has_app_context(): + """Works like :func:`has_request_context` but for the application + context. You can also just do a boolean check on the + :data:`current_app` object instead. + + .. versionadded:: 0.9 + """ + return _app_ctx_stack.top is not None + + +class AppContext(object): + """The application context binds an application object implicitly + to the current thread or greenlet, similar to how the + :class:`RequestContext` binds request information. The application + context is also implicitly created if a request context is created + but the application is not on top of the individual application + context. + """ + + def __init__(self, app): + self.app = app + self.url_adapter = app.create_url_adapter(None) + self.g = app.app_ctx_globals_class() + + # Like request context, app contexts can be pushed multiple times + # but there a basic "refcount" is enough to track them. + self._refcnt = 0 + + def push(self): + """Binds the app context to the current context.""" + self._refcnt += 1 + if hasattr(sys, 'exc_clear'): + sys.exc_clear() + _app_ctx_stack.push(self) + appcontext_pushed.send(self.app) + + def pop(self, exc=_sentinel): + """Pops the app context.""" + try: + self._refcnt -= 1 + if self._refcnt <= 0: + if exc is _sentinel: + exc = sys.exc_info()[1] + self.app.do_teardown_appcontext(exc) + finally: + rv = _app_ctx_stack.pop() + assert rv is self, 'Popped wrong app context. (%r instead of %r)' \ + % (rv, self) + appcontext_popped.send(self.app) + + def __enter__(self): + self.push() + return self + + def __exit__(self, exc_type, exc_value, tb): + self.pop(exc_value) + + if BROKEN_PYPY_CTXMGR_EXIT and exc_type is not None: + reraise(exc_type, exc_value, tb) + + +class RequestContext(object): + """The request context contains all request relevant information. It is + created at the beginning of the request and pushed to the + `_request_ctx_stack` and removed at the end of it. It will create the + URL adapter and request object for the WSGI environment provided. + + Do not attempt to use this class directly, instead use + :meth:`~flask.Flask.test_request_context` and + :meth:`~flask.Flask.request_context` to create this object. + + When the request context is popped, it will evaluate all the + functions registered on the application for teardown execution + (:meth:`~flask.Flask.teardown_request`). + + The request context is automatically popped at the end of the request + for you. In debug mode the request context is kept around if + exceptions happen so that interactive debuggers have a chance to + introspect the data. With 0.4 this can also be forced for requests + that did not fail and outside of ``DEBUG`` mode. By setting + ``'flask._preserve_context'`` to ``True`` on the WSGI environment the + context will not pop itself at the end of the request. This is used by + the :meth:`~flask.Flask.test_client` for example to implement the + deferred cleanup functionality. + + You might find this helpful for unittests where you need the + information from the context local around for a little longer. Make + sure to properly :meth:`~werkzeug.LocalStack.pop` the stack yourself in + that situation, otherwise your unittests will leak memory. + """ + + def __init__(self, app, environ, request=None): + self.app = app + if request is None: + request = app.request_class(environ) + self.request = request + self.url_adapter = app.create_url_adapter(self.request) + self.flashes = None + self.session = None + + # Request contexts can be pushed multiple times and interleaved with + # other request contexts. Now only if the last level is popped we + # get rid of them. Additionally if an application context is missing + # one is created implicitly so for each level we add this information + self._implicit_app_ctx_stack = [] + + # indicator if the context was preserved. Next time another context + # is pushed the preserved context is popped. + self.preserved = False + + # remembers the exception for pop if there is one in case the context + # preservation kicks in. + self._preserved_exc = None + + # Functions that should be executed after the request on the response + # object. These will be called before the regular "after_request" + # functions. + self._after_request_functions = [] + + self.match_request() + + def _get_g(self): + return _app_ctx_stack.top.g + def _set_g(self, value): + _app_ctx_stack.top.g = value + g = property(_get_g, _set_g) + del _get_g, _set_g + + def copy(self): + """Creates a copy of this request context with the same request object. + This can be used to move a request context to a different greenlet. + Because the actual request object is the same this cannot be used to + move a request context to a different thread unless access to the + request object is locked. + + .. versionadded:: 0.10 + """ + return self.__class__(self.app, + environ=self.request.environ, + request=self.request + ) + + def match_request(self): + """Can be overridden by a subclass to hook into the matching + of the request. + """ + try: + url_rule, self.request.view_args = \ + self.url_adapter.match(return_rule=True) + self.request.url_rule = url_rule + except HTTPException as e: + self.request.routing_exception = e + + def push(self): + """Binds the request context to the current context.""" + # If an exception occurs in debug mode or if context preservation is + # activated under exception situations exactly one context stays + # on the stack. The rationale is that you want to access that + # information under debug situations. However if someone forgets to + # pop that context again we want to make sure that on the next push + # it's invalidated, otherwise we run at risk that something leaks + # memory. This is usually only a problem in test suite since this + # functionality is not active in production environments. + top = _request_ctx_stack.top + if top is not None and top.preserved: + top.pop(top._preserved_exc) + + # Before we push the request context we have to ensure that there + # is an application context. + app_ctx = _app_ctx_stack.top + if app_ctx is None or app_ctx.app != self.app: + app_ctx = self.app.app_context() + app_ctx.push() + self._implicit_app_ctx_stack.append(app_ctx) + else: + self._implicit_app_ctx_stack.append(None) + + if hasattr(sys, 'exc_clear'): + sys.exc_clear() + + _request_ctx_stack.push(self) + + # Open the session at the moment that the request context is available. + # This allows a custom open_session method to use the request context. + # Only open a new session if this is the first time the request was + # pushed, otherwise stream_with_context loses the session. + if self.session is None: + session_interface = self.app.session_interface + self.session = session_interface.open_session( + self.app, self.request + ) + + if self.session is None: + self.session = session_interface.make_null_session(self.app) + + def pop(self, exc=_sentinel): + """Pops the request context and unbinds it by doing that. This will + also trigger the execution of functions registered by the + :meth:`~flask.Flask.teardown_request` decorator. + + .. versionchanged:: 0.9 + Added the `exc` argument. + """ + app_ctx = self._implicit_app_ctx_stack.pop() + + try: + clear_request = False + if not self._implicit_app_ctx_stack: + self.preserved = False + self._preserved_exc = None + if exc is _sentinel: + exc = sys.exc_info()[1] + self.app.do_teardown_request(exc) + + # If this interpreter supports clearing the exception information + # we do that now. This will only go into effect on Python 2.x, + # on 3.x it disappears automatically at the end of the exception + # stack. + if hasattr(sys, 'exc_clear'): + sys.exc_clear() + + request_close = getattr(self.request, 'close', None) + if request_close is not None: + request_close() + clear_request = True + finally: + rv = _request_ctx_stack.pop() + + # get rid of circular dependencies at the end of the request + # so that we don't require the GC to be active. + if clear_request: + rv.request.environ['werkzeug.request'] = None + + # Get rid of the app as well if necessary. + if app_ctx is not None: + app_ctx.pop(exc) + + assert rv is self, 'Popped wrong request context. ' \ + '(%r instead of %r)' % (rv, self) + + def auto_pop(self, exc): + if self.request.environ.get('flask._preserve_context') or \ + (exc is not None and self.app.preserve_context_on_exception): + self.preserved = True + self._preserved_exc = exc + else: + self.pop(exc) + + def __enter__(self): + self.push() + return self + + def __exit__(self, exc_type, exc_value, tb): + # do not pop the request stack if we are in debug mode and an + # exception happened. This will allow the debugger to still + # access the request object in the interactive shell. Furthermore + # the context can be force kept alive for the test client. + # See flask.testing for how this works. + self.auto_pop(exc_value) + + if BROKEN_PYPY_CTXMGR_EXIT and exc_type is not None: + reraise(exc_type, exc_value, tb) + + def __repr__(self): + return '<%s \'%s\' [%s] of %s>' % ( + self.__class__.__name__, + self.request.url, + self.request.method, + self.app.name, + ) diff --git a/flask/venv/lib/python3.6/site-packages/flask/debughelpers.py b/flask/venv/lib/python3.6/site-packages/flask/debughelpers.py new file mode 100644 index 0000000..e9765f2 --- /dev/null +++ b/flask/venv/lib/python3.6/site-packages/flask/debughelpers.py @@ -0,0 +1,168 @@ +# -*- coding: utf-8 -*- +""" + flask.debughelpers + ~~~~~~~~~~~~~~~~~~ + + Various helpers to make the development experience better. + + :copyright: © 2010 by the Pallets team. + :license: BSD, see LICENSE for more details. +""" + +import os +from warnings import warn + +from ._compat import implements_to_string, text_type +from .app import Flask +from .blueprints import Blueprint +from .globals import _request_ctx_stack + + +class UnexpectedUnicodeError(AssertionError, UnicodeError): + """Raised in places where we want some better error reporting for + unexpected unicode or binary data. + """ + + +@implements_to_string +class DebugFilesKeyError(KeyError, AssertionError): + """Raised from request.files during debugging. The idea is that it can + provide a better error message than just a generic KeyError/BadRequest. + """ + + def __init__(self, request, key): + form_matches = request.form.getlist(key) + buf = ['You tried to access the file "%s" in the request.files ' + 'dictionary but it does not exist. The mimetype for the request ' + 'is "%s" instead of "multipart/form-data" which means that no ' + 'file contents were transmitted. To fix this error you should ' + 'provide enctype="multipart/form-data" in your form.' % + (key, request.mimetype)] + if form_matches: + buf.append('\n\nThe browser instead transmitted some file names. ' + 'This was submitted: %s' % ', '.join('"%s"' % x + for x in form_matches)) + self.msg = ''.join(buf) + + def __str__(self): + return self.msg + + +class FormDataRoutingRedirect(AssertionError): + """This exception is raised by Flask in debug mode if it detects a + redirect caused by the routing system when the request method is not + GET, HEAD or OPTIONS. Reasoning: form data will be dropped. + """ + + def __init__(self, request): + exc = request.routing_exception + buf = ['A request was sent to this URL (%s) but a redirect was ' + 'issued automatically by the routing system to "%s".' + % (request.url, exc.new_url)] + + # In case just a slash was appended we can be extra helpful + if request.base_url + '/' == exc.new_url.split('?')[0]: + buf.append(' The URL was defined with a trailing slash so ' + 'Flask will automatically redirect to the URL ' + 'with the trailing slash if it was accessed ' + 'without one.') + + buf.append(' Make sure to directly send your %s-request to this URL ' + 'since we can\'t make browsers or HTTP clients redirect ' + 'with form data reliably or without user interaction.' % + request.method) + buf.append('\n\nNote: this exception is only raised in debug mode') + AssertionError.__init__(self, ''.join(buf).encode('utf-8')) + + +def attach_enctype_error_multidict(request): + """Since Flask 0.8 we're monkeypatching the files object in case a + request is detected that does not use multipart form data but the files + object is accessed. + """ + oldcls = request.files.__class__ + class newcls(oldcls): + def __getitem__(self, key): + try: + return oldcls.__getitem__(self, key) + except KeyError: + if key not in request.form: + raise + raise DebugFilesKeyError(request, key) + newcls.__name__ = oldcls.__name__ + newcls.__module__ = oldcls.__module__ + request.files.__class__ = newcls + + +def _dump_loader_info(loader): + yield 'class: %s.%s' % (type(loader).__module__, type(loader).__name__) + for key, value in sorted(loader.__dict__.items()): + if key.startswith('_'): + continue + if isinstance(value, (tuple, list)): + if not all(isinstance(x, (str, text_type)) for x in value): + continue + yield '%s:' % key + for item in value: + yield ' - %s' % item + continue + elif not isinstance(value, (str, text_type, int, float, bool)): + continue + yield '%s: %r' % (key, value) + + +def explain_template_loading_attempts(app, template, attempts): + """This should help developers understand what failed""" + info = ['Locating template "%s":' % template] + total_found = 0 + blueprint = None + reqctx = _request_ctx_stack.top + if reqctx is not None and reqctx.request.blueprint is not None: + blueprint = reqctx.request.blueprint + + for idx, (loader, srcobj, triple) in enumerate(attempts): + if isinstance(srcobj, Flask): + src_info = 'application "%s"' % srcobj.import_name + elif isinstance(srcobj, Blueprint): + src_info = 'blueprint "%s" (%s)' % (srcobj.name, + srcobj.import_name) + else: + src_info = repr(srcobj) + + info.append('% 5d: trying loader of %s' % ( + idx + 1, src_info)) + + for line in _dump_loader_info(loader): + info.append(' %s' % line) + + if triple is None: + detail = 'no match' + else: + detail = 'found (%r)' % (triple[1] or '') + total_found += 1 + info.append(' -> %s' % detail) + + seems_fishy = False + if total_found == 0: + info.append('Error: the template could not be found.') + seems_fishy = True + elif total_found > 1: + info.append('Warning: multiple loaders returned a match for the template.') + seems_fishy = True + + if blueprint is not None and seems_fishy: + info.append(' The template was looked up from an endpoint that ' + 'belongs to the blueprint "%s".' % blueprint) + info.append(' Maybe you did not place a template in the right folder?') + info.append(' See http://flask.pocoo.org/docs/blueprints/#templates') + + app.logger.info('\n'.join(info)) + + +def explain_ignored_app_run(): + if os.environ.get('WERKZEUG_RUN_MAIN') != 'true': + warn(Warning('Silently ignoring app.run() because the ' + 'application is run from the flask command line ' + 'executable. Consider putting app.run() behind an ' + 'if __name__ == "__main__" guard to silence this ' + 'warning.'), stacklevel=3) diff --git a/flask/venv/lib/python3.6/site-packages/flask/globals.py b/flask/venv/lib/python3.6/site-packages/flask/globals.py new file mode 100644 index 0000000..7d50a6f --- /dev/null +++ b/flask/venv/lib/python3.6/site-packages/flask/globals.py @@ -0,0 +1,61 @@ +# -*- coding: utf-8 -*- +""" + flask.globals + ~~~~~~~~~~~~~ + + Defines all the global objects that are proxies to the current + active context. + + :copyright: © 2010 by the Pallets team. + :license: BSD, see LICENSE for more details. +""" + +from functools import partial +from werkzeug.local import LocalStack, LocalProxy + + +_request_ctx_err_msg = '''\ +Working outside of request context. + +This typically means that you attempted to use functionality that needed +an active HTTP request. Consult the documentation on testing for +information about how to avoid this problem.\ +''' +_app_ctx_err_msg = '''\ +Working outside of application context. + +This typically means that you attempted to use functionality that needed +to interface with the current application object in some way. To solve +this, set up an application context with app.app_context(). See the +documentation for more information.\ +''' + + +def _lookup_req_object(name): + top = _request_ctx_stack.top + if top is None: + raise RuntimeError(_request_ctx_err_msg) + return getattr(top, name) + + +def _lookup_app_object(name): + top = _app_ctx_stack.top + if top is None: + raise RuntimeError(_app_ctx_err_msg) + return getattr(top, name) + + +def _find_app(): + top = _app_ctx_stack.top + if top is None: + raise RuntimeError(_app_ctx_err_msg) + return top.app + + +# context locals +_request_ctx_stack = LocalStack() +_app_ctx_stack = LocalStack() +current_app = LocalProxy(_find_app) +request = LocalProxy(partial(_lookup_req_object, 'request')) +session = LocalProxy(partial(_lookup_req_object, 'session')) +g = LocalProxy(partial(_lookup_app_object, 'g')) diff --git a/flask/venv/lib/python3.6/site-packages/flask/helpers.py b/flask/venv/lib/python3.6/site-packages/flask/helpers.py new file mode 100644 index 0000000..df0b91f --- /dev/null +++ b/flask/venv/lib/python3.6/site-packages/flask/helpers.py @@ -0,0 +1,1044 @@ +# -*- coding: utf-8 -*- +""" + flask.helpers + ~~~~~~~~~~~~~ + + Implements various helpers. + + :copyright: © 2010 by the Pallets team. + :license: BSD, see LICENSE for more details. +""" + +import os +import socket +import sys +import pkgutil +import posixpath +import mimetypes +from time import time +from zlib import adler32 +from threading import RLock +import unicodedata +from werkzeug.routing import BuildError +from functools import update_wrapper + +from werkzeug.urls import url_quote +from werkzeug.datastructures import Headers, Range +from werkzeug.exceptions import BadRequest, NotFound, \ + RequestedRangeNotSatisfiable + +from werkzeug.wsgi import wrap_file +from jinja2 import FileSystemLoader + +from .signals import message_flashed +from .globals import session, _request_ctx_stack, _app_ctx_stack, \ + current_app, request +from ._compat import string_types, text_type, PY2 + +# sentinel +_missing = object() + + +# what separators does this operating system provide that are not a slash? +# this is used by the send_from_directory function to ensure that nobody is +# able to access files from outside the filesystem. +_os_alt_seps = list(sep for sep in [os.path.sep, os.path.altsep] + if sep not in (None, '/')) + + +def get_env(): + """Get the environment the app is running in, indicated by the + :envvar:`FLASK_ENV` environment variable. The default is + ``'production'``. + """ + return os.environ.get('FLASK_ENV') or 'production' + + +def get_debug_flag(): + """Get whether debug mode should be enabled for the app, indicated + by the :envvar:`FLASK_DEBUG` environment variable. The default is + ``True`` if :func:`.get_env` returns ``'development'``, or ``False`` + otherwise. + """ + val = os.environ.get('FLASK_DEBUG') + + if not val: + return get_env() == 'development' + + return val.lower() not in ('0', 'false', 'no') + + +def get_load_dotenv(default=True): + """Get whether the user has disabled loading dotenv files by setting + :envvar:`FLASK_SKIP_DOTENV`. The default is ``True``, load the + files. + + :param default: What to return if the env var isn't set. + """ + val = os.environ.get('FLASK_SKIP_DOTENV') + + if not val: + return default + + return val.lower() in ('0', 'false', 'no') + + +def _endpoint_from_view_func(view_func): + """Internal helper that returns the default endpoint for a given + function. This always is the function name. + """ + assert view_func is not None, 'expected view func if endpoint ' \ + 'is not provided.' + return view_func.__name__ + + +def stream_with_context(generator_or_function): + """Request contexts disappear when the response is started on the server. + This is done for efficiency reasons and to make it less likely to encounter + memory leaks with badly written WSGI middlewares. The downside is that if + you are using streamed responses, the generator cannot access request bound + information any more. + + This function however can help you keep the context around for longer:: + + from flask import stream_with_context, request, Response + + @app.route('/stream') + def streamed_response(): + @stream_with_context + def generate(): + yield 'Hello ' + yield request.args['name'] + yield '!' + return Response(generate()) + + Alternatively it can also be used around a specific generator:: + + from flask import stream_with_context, request, Response + + @app.route('/stream') + def streamed_response(): + def generate(): + yield 'Hello ' + yield request.args['name'] + yield '!' + return Response(stream_with_context(generate())) + + .. versionadded:: 0.9 + """ + try: + gen = iter(generator_or_function) + except TypeError: + def decorator(*args, **kwargs): + gen = generator_or_function(*args, **kwargs) + return stream_with_context(gen) + return update_wrapper(decorator, generator_or_function) + + def generator(): + ctx = _request_ctx_stack.top + if ctx is None: + raise RuntimeError('Attempted to stream with context but ' + 'there was no context in the first place to keep around.') + with ctx: + # Dummy sentinel. Has to be inside the context block or we're + # not actually keeping the context around. + yield None + + # The try/finally is here so that if someone passes a WSGI level + # iterator in we're still running the cleanup logic. Generators + # don't need that because they are closed on their destruction + # automatically. + try: + for item in gen: + yield item + finally: + if hasattr(gen, 'close'): + gen.close() + + # The trick is to start the generator. Then the code execution runs until + # the first dummy None is yielded at which point the context was already + # pushed. This item is discarded. Then when the iteration continues the + # real generator is executed. + wrapped_g = generator() + next(wrapped_g) + return wrapped_g + + +def make_response(*args): + """Sometimes it is necessary to set additional headers in a view. Because + views do not have to return response objects but can return a value that + is converted into a response object by Flask itself, it becomes tricky to + add headers to it. This function can be called instead of using a return + and you will get a response object which you can use to attach headers. + + If view looked like this and you want to add a new header:: + + def index(): + return render_template('index.html', foo=42) + + You can now do something like this:: + + def index(): + response = make_response(render_template('index.html', foo=42)) + response.headers['X-Parachutes'] = 'parachutes are cool' + return response + + This function accepts the very same arguments you can return from a + view function. This for example creates a response with a 404 error + code:: + + response = make_response(render_template('not_found.html'), 404) + + The other use case of this function is to force the return value of a + view function into a response which is helpful with view + decorators:: + + response = make_response(view_function()) + response.headers['X-Parachutes'] = 'parachutes are cool' + + Internally this function does the following things: + + - if no arguments are passed, it creates a new response argument + - if one argument is passed, :meth:`flask.Flask.make_response` + is invoked with it. + - if more than one argument is passed, the arguments are passed + to the :meth:`flask.Flask.make_response` function as tuple. + + .. versionadded:: 0.6 + """ + if not args: + return current_app.response_class() + if len(args) == 1: + args = args[0] + return current_app.make_response(args) + + +def url_for(endpoint, **values): + """Generates a URL to the given endpoint with the method provided. + + Variable arguments that are unknown to the target endpoint are appended + to the generated URL as query arguments. If the value of a query argument + is ``None``, the whole pair is skipped. In case blueprints are active + you can shortcut references to the same blueprint by prefixing the + local endpoint with a dot (``.``). + + This will reference the index function local to the current blueprint:: + + url_for('.index') + + For more information, head over to the :ref:`Quickstart `. + + To integrate applications, :class:`Flask` has a hook to intercept URL build + errors through :attr:`Flask.url_build_error_handlers`. The `url_for` + function results in a :exc:`~werkzeug.routing.BuildError` when the current + app does not have a URL for the given endpoint and values. When it does, the + :data:`~flask.current_app` calls its :attr:`~Flask.url_build_error_handlers` if + it is not ``None``, which can return a string to use as the result of + `url_for` (instead of `url_for`'s default to raise the + :exc:`~werkzeug.routing.BuildError` exception) or re-raise the exception. + An example:: + + def external_url_handler(error, endpoint, values): + "Looks up an external URL when `url_for` cannot build a URL." + # This is an example of hooking the build_error_handler. + # Here, lookup_url is some utility function you've built + # which looks up the endpoint in some external URL registry. + url = lookup_url(endpoint, **values) + if url is None: + # External lookup did not have a URL. + # Re-raise the BuildError, in context of original traceback. + exc_type, exc_value, tb = sys.exc_info() + if exc_value is error: + raise exc_type, exc_value, tb + else: + raise error + # url_for will use this result, instead of raising BuildError. + return url + + app.url_build_error_handlers.append(external_url_handler) + + Here, `error` is the instance of :exc:`~werkzeug.routing.BuildError`, and + `endpoint` and `values` are the arguments passed into `url_for`. Note + that this is for building URLs outside the current application, and not for + handling 404 NotFound errors. + + .. versionadded:: 0.10 + The `_scheme` parameter was added. + + .. versionadded:: 0.9 + The `_anchor` and `_method` parameters were added. + + .. versionadded:: 0.9 + Calls :meth:`Flask.handle_build_error` on + :exc:`~werkzeug.routing.BuildError`. + + :param endpoint: the endpoint of the URL (name of the function) + :param values: the variable arguments of the URL rule + :param _external: if set to ``True``, an absolute URL is generated. Server + address can be changed via ``SERVER_NAME`` configuration variable which + defaults to `localhost`. + :param _scheme: a string specifying the desired URL scheme. The `_external` + parameter must be set to ``True`` or a :exc:`ValueError` is raised. The default + behavior uses the same scheme as the current request, or + ``PREFERRED_URL_SCHEME`` from the :ref:`app configuration ` if no + request context is available. As of Werkzeug 0.10, this also can be set + to an empty string to build protocol-relative URLs. + :param _anchor: if provided this is added as anchor to the URL. + :param _method: if provided this explicitly specifies an HTTP method. + """ + appctx = _app_ctx_stack.top + reqctx = _request_ctx_stack.top + + if appctx is None: + raise RuntimeError( + 'Attempted to generate a URL without the application context being' + ' pushed. This has to be executed when application context is' + ' available.' + ) + + # If request specific information is available we have some extra + # features that support "relative" URLs. + if reqctx is not None: + url_adapter = reqctx.url_adapter + blueprint_name = request.blueprint + + if endpoint[:1] == '.': + if blueprint_name is not None: + endpoint = blueprint_name + endpoint + else: + endpoint = endpoint[1:] + + external = values.pop('_external', False) + + # Otherwise go with the url adapter from the appctx and make + # the URLs external by default. + else: + url_adapter = appctx.url_adapter + + if url_adapter is None: + raise RuntimeError( + 'Application was not able to create a URL adapter for request' + ' independent URL generation. You might be able to fix this by' + ' setting the SERVER_NAME config variable.' + ) + + external = values.pop('_external', True) + + anchor = values.pop('_anchor', None) + method = values.pop('_method', None) + scheme = values.pop('_scheme', None) + appctx.app.inject_url_defaults(endpoint, values) + + # This is not the best way to deal with this but currently the + # underlying Werkzeug router does not support overriding the scheme on + # a per build call basis. + old_scheme = None + if scheme is not None: + if not external: + raise ValueError('When specifying _scheme, _external must be True') + old_scheme = url_adapter.url_scheme + url_adapter.url_scheme = scheme + + try: + try: + rv = url_adapter.build(endpoint, values, method=method, + force_external=external) + finally: + if old_scheme is not None: + url_adapter.url_scheme = old_scheme + except BuildError as error: + # We need to inject the values again so that the app callback can + # deal with that sort of stuff. + values['_external'] = external + values['_anchor'] = anchor + values['_method'] = method + values['_scheme'] = scheme + return appctx.app.handle_url_build_error(error, endpoint, values) + + if anchor is not None: + rv += '#' + url_quote(anchor) + return rv + + +def get_template_attribute(template_name, attribute): + """Loads a macro (or variable) a template exports. This can be used to + invoke a macro from within Python code. If you for example have a + template named :file:`_cider.html` with the following contents: + + .. sourcecode:: html+jinja + + {% macro hello(name) %}Hello {{ name }}!{% endmacro %} + + You can access this from Python code like this:: + + hello = get_template_attribute('_cider.html', 'hello') + return hello('World') + + .. versionadded:: 0.2 + + :param template_name: the name of the template + :param attribute: the name of the variable of macro to access + """ + return getattr(current_app.jinja_env.get_template(template_name).module, + attribute) + + +def flash(message, category='message'): + """Flashes a message to the next request. In order to remove the + flashed message from the session and to display it to the user, + the template has to call :func:`get_flashed_messages`. + + .. versionchanged:: 0.3 + `category` parameter added. + + :param message: the message to be flashed. + :param category: the category for the message. The following values + are recommended: ``'message'`` for any kind of message, + ``'error'`` for errors, ``'info'`` for information + messages and ``'warning'`` for warnings. However any + kind of string can be used as category. + """ + # Original implementation: + # + # session.setdefault('_flashes', []).append((category, message)) + # + # This assumed that changes made to mutable structures in the session are + # always in sync with the session object, which is not true for session + # implementations that use external storage for keeping their keys/values. + flashes = session.get('_flashes', []) + flashes.append((category, message)) + session['_flashes'] = flashes + message_flashed.send(current_app._get_current_object(), + message=message, category=category) + + +def get_flashed_messages(with_categories=False, category_filter=[]): + """Pulls all flashed messages from the session and returns them. + Further calls in the same request to the function will return + the same messages. By default just the messages are returned, + but when `with_categories` is set to ``True``, the return value will + be a list of tuples in the form ``(category, message)`` instead. + + Filter the flashed messages to one or more categories by providing those + categories in `category_filter`. This allows rendering categories in + separate html blocks. The `with_categories` and `category_filter` + arguments are distinct: + + * `with_categories` controls whether categories are returned with message + text (``True`` gives a tuple, where ``False`` gives just the message text). + * `category_filter` filters the messages down to only those matching the + provided categories. + + See :ref:`message-flashing-pattern` for examples. + + .. versionchanged:: 0.3 + `with_categories` parameter added. + + .. versionchanged:: 0.9 + `category_filter` parameter added. + + :param with_categories: set to ``True`` to also receive categories. + :param category_filter: whitelist of categories to limit return values + """ + flashes = _request_ctx_stack.top.flashes + if flashes is None: + _request_ctx_stack.top.flashes = flashes = session.pop('_flashes') \ + if '_flashes' in session else [] + if category_filter: + flashes = list(filter(lambda f: f[0] in category_filter, flashes)) + if not with_categories: + return [x[1] for x in flashes] + return flashes + + +def send_file(filename_or_fp, mimetype=None, as_attachment=False, + attachment_filename=None, add_etags=True, + cache_timeout=None, conditional=False, last_modified=None): + """Sends the contents of a file to the client. This will use the + most efficient method available and configured. By default it will + try to use the WSGI server's file_wrapper support. Alternatively + you can set the application's :attr:`~Flask.use_x_sendfile` attribute + to ``True`` to directly emit an ``X-Sendfile`` header. This however + requires support of the underlying webserver for ``X-Sendfile``. + + By default it will try to guess the mimetype for you, but you can + also explicitly provide one. For extra security you probably want + to send certain files as attachment (HTML for instance). The mimetype + guessing requires a `filename` or an `attachment_filename` to be + provided. + + ETags will also be attached automatically if a `filename` is provided. You + can turn this off by setting `add_etags=False`. + + If `conditional=True` and `filename` is provided, this method will try to + upgrade the response stream to support range requests. This will allow + the request to be answered with partial content response. + + Please never pass filenames to this function from user sources; + you should use :func:`send_from_directory` instead. + + .. versionadded:: 0.2 + + .. versionadded:: 0.5 + The `add_etags`, `cache_timeout` and `conditional` parameters were + added. The default behavior is now to attach etags. + + .. versionchanged:: 0.7 + mimetype guessing and etag support for file objects was + deprecated because it was unreliable. Pass a filename if you are + able to, otherwise attach an etag yourself. This functionality + will be removed in Flask 1.0 + + .. versionchanged:: 0.9 + cache_timeout pulls its default from application config, when None. + + .. versionchanged:: 0.12 + The filename is no longer automatically inferred from file objects. If + you want to use automatic mimetype and etag support, pass a filepath via + `filename_or_fp` or `attachment_filename`. + + .. versionchanged:: 0.12 + The `attachment_filename` is preferred over `filename` for MIME-type + detection. + + .. versionchanged:: 1.0 + UTF-8 filenames, as specified in `RFC 2231`_, are supported. + + .. _RFC 2231: https://tools.ietf.org/html/rfc2231#section-4 + + :param filename_or_fp: the filename of the file to send. + This is relative to the :attr:`~Flask.root_path` + if a relative path is specified. + Alternatively a file object might be provided in + which case ``X-Sendfile`` might not work and fall + back to the traditional method. Make sure that the + file pointer is positioned at the start of data to + send before calling :func:`send_file`. + :param mimetype: the mimetype of the file if provided. If a file path is + given, auto detection happens as fallback, otherwise an + error will be raised. + :param as_attachment: set to ``True`` if you want to send this file with + a ``Content-Disposition: attachment`` header. + :param attachment_filename: the filename for the attachment if it + differs from the file's filename. + :param add_etags: set to ``False`` to disable attaching of etags. + :param conditional: set to ``True`` to enable conditional responses. + + :param cache_timeout: the timeout in seconds for the headers. When ``None`` + (default), this value is set by + :meth:`~Flask.get_send_file_max_age` of + :data:`~flask.current_app`. + :param last_modified: set the ``Last-Modified`` header to this value, + a :class:`~datetime.datetime` or timestamp. + If a file was passed, this overrides its mtime. + """ + mtime = None + fsize = None + if isinstance(filename_or_fp, string_types): + filename = filename_or_fp + if not os.path.isabs(filename): + filename = os.path.join(current_app.root_path, filename) + file = None + if attachment_filename is None: + attachment_filename = os.path.basename(filename) + else: + file = filename_or_fp + filename = None + + if mimetype is None: + if attachment_filename is not None: + mimetype = mimetypes.guess_type(attachment_filename)[0] \ + or 'application/octet-stream' + + if mimetype is None: + raise ValueError( + 'Unable to infer MIME-type because no filename is available. ' + 'Please set either `attachment_filename`, pass a filepath to ' + '`filename_or_fp` or set your own MIME-type via `mimetype`.' + ) + + headers = Headers() + if as_attachment: + if attachment_filename is None: + raise TypeError('filename unavailable, required for ' + 'sending as attachment') + + try: + attachment_filename = attachment_filename.encode('latin-1') + except UnicodeEncodeError: + filenames = { + 'filename': unicodedata.normalize( + 'NFKD', attachment_filename).encode('latin-1', 'ignore'), + 'filename*': "UTF-8''%s" % url_quote(attachment_filename), + } + else: + filenames = {'filename': attachment_filename} + + headers.add('Content-Disposition', 'attachment', **filenames) + + if current_app.use_x_sendfile and filename: + if file is not None: + file.close() + headers['X-Sendfile'] = filename + fsize = os.path.getsize(filename) + headers['Content-Length'] = fsize + data = None + else: + if file is None: + file = open(filename, 'rb') + mtime = os.path.getmtime(filename) + fsize = os.path.getsize(filename) + headers['Content-Length'] = fsize + data = wrap_file(request.environ, file) + + rv = current_app.response_class(data, mimetype=mimetype, headers=headers, + direct_passthrough=True) + + if last_modified is not None: + rv.last_modified = last_modified + elif mtime is not None: + rv.last_modified = mtime + + rv.cache_control.public = True + if cache_timeout is None: + cache_timeout = current_app.get_send_file_max_age(filename) + if cache_timeout is not None: + rv.cache_control.max_age = cache_timeout + rv.expires = int(time() + cache_timeout) + + if add_etags and filename is not None: + from warnings import warn + + try: + rv.set_etag('%s-%s-%s' % ( + os.path.getmtime(filename), + os.path.getsize(filename), + adler32( + filename.encode('utf-8') if isinstance(filename, text_type) + else filename + ) & 0xffffffff + )) + except OSError: + warn('Access %s failed, maybe it does not exist, so ignore etags in ' + 'headers' % filename, stacklevel=2) + + if conditional: + try: + rv = rv.make_conditional(request, accept_ranges=True, + complete_length=fsize) + except RequestedRangeNotSatisfiable: + if file is not None: + file.close() + raise + # make sure we don't send x-sendfile for servers that + # ignore the 304 status code for x-sendfile. + if rv.status_code == 304: + rv.headers.pop('x-sendfile', None) + return rv + + +def safe_join(directory, *pathnames): + """Safely join `directory` and zero or more untrusted `pathnames` + components. + + Example usage:: + + @app.route('/wiki/') + def wiki_page(filename): + filename = safe_join(app.config['WIKI_FOLDER'], filename) + with open(filename, 'rb') as fd: + content = fd.read() # Read and process the file content... + + :param directory: the trusted base directory. + :param pathnames: the untrusted pathnames relative to that directory. + :raises: :class:`~werkzeug.exceptions.NotFound` if one or more passed + paths fall out of its boundaries. + """ + + parts = [directory] + + for filename in pathnames: + if filename != '': + filename = posixpath.normpath(filename) + + if ( + any(sep in filename for sep in _os_alt_seps) + or os.path.isabs(filename) + or filename == '..' + or filename.startswith('../') + ): + raise NotFound() + + parts.append(filename) + + return posixpath.join(*parts) + + +def send_from_directory(directory, filename, **options): + """Send a file from a given directory with :func:`send_file`. This + is a secure way to quickly expose static files from an upload folder + or something similar. + + Example usage:: + + @app.route('/uploads/') + def download_file(filename): + return send_from_directory(app.config['UPLOAD_FOLDER'], + filename, as_attachment=True) + + .. admonition:: Sending files and Performance + + It is strongly recommended to activate either ``X-Sendfile`` support in + your webserver or (if no authentication happens) to tell the webserver + to serve files for the given path on its own without calling into the + web application for improved performance. + + .. versionadded:: 0.5 + + :param directory: the directory where all the files are stored. + :param filename: the filename relative to that directory to + download. + :param options: optional keyword arguments that are directly + forwarded to :func:`send_file`. + """ + filename = safe_join(directory, filename) + if not os.path.isabs(filename): + filename = os.path.join(current_app.root_path, filename) + try: + if not os.path.isfile(filename): + raise NotFound() + except (TypeError, ValueError): + raise BadRequest() + options.setdefault('conditional', True) + return send_file(filename, **options) + + +def get_root_path(import_name): + """Returns the path to a package or cwd if that cannot be found. This + returns the path of a package or the folder that contains a module. + + Not to be confused with the package path returned by :func:`find_package`. + """ + # Module already imported and has a file attribute. Use that first. + mod = sys.modules.get(import_name) + if mod is not None and hasattr(mod, '__file__'): + return os.path.dirname(os.path.abspath(mod.__file__)) + + # Next attempt: check the loader. + loader = pkgutil.get_loader(import_name) + + # Loader does not exist or we're referring to an unloaded main module + # or a main module without path (interactive sessions), go with the + # current working directory. + if loader is None or import_name == '__main__': + return os.getcwd() + + # For .egg, zipimporter does not have get_filename until Python 2.7. + # Some other loaders might exhibit the same behavior. + if hasattr(loader, 'get_filename'): + filepath = loader.get_filename(import_name) + else: + # Fall back to imports. + __import__(import_name) + mod = sys.modules[import_name] + filepath = getattr(mod, '__file__', None) + + # If we don't have a filepath it might be because we are a + # namespace package. In this case we pick the root path from the + # first module that is contained in our package. + if filepath is None: + raise RuntimeError('No root path can be found for the provided ' + 'module "%s". This can happen because the ' + 'module came from an import hook that does ' + 'not provide file name information or because ' + 'it\'s a namespace package. In this case ' + 'the root path needs to be explicitly ' + 'provided.' % import_name) + + # filepath is import_name.py for a module, or __init__.py for a package. + return os.path.dirname(os.path.abspath(filepath)) + + +def _matching_loader_thinks_module_is_package(loader, mod_name): + """Given the loader that loaded a module and the module this function + attempts to figure out if the given module is actually a package. + """ + # If the loader can tell us if something is a package, we can + # directly ask the loader. + if hasattr(loader, 'is_package'): + return loader.is_package(mod_name) + # importlib's namespace loaders do not have this functionality but + # all the modules it loads are packages, so we can take advantage of + # this information. + elif (loader.__class__.__module__ == '_frozen_importlib' and + loader.__class__.__name__ == 'NamespaceLoader'): + return True + # Otherwise we need to fail with an error that explains what went + # wrong. + raise AttributeError( + ('%s.is_package() method is missing but is required by Flask of ' + 'PEP 302 import hooks. If you do not use import hooks and ' + 'you encounter this error please file a bug against Flask.') % + loader.__class__.__name__) + + +def find_package(import_name): + """Finds a package and returns the prefix (or None if the package is + not installed) as well as the folder that contains the package or + module as a tuple. The package path returned is the module that would + have to be added to the pythonpath in order to make it possible to + import the module. The prefix is the path below which a UNIX like + folder structure exists (lib, share etc.). + """ + root_mod_name = import_name.split('.')[0] + loader = pkgutil.get_loader(root_mod_name) + if loader is None or import_name == '__main__': + # import name is not found, or interactive/main module + package_path = os.getcwd() + else: + # For .egg, zipimporter does not have get_filename until Python 2.7. + if hasattr(loader, 'get_filename'): + filename = loader.get_filename(root_mod_name) + elif hasattr(loader, 'archive'): + # zipimporter's loader.archive points to the .egg or .zip + # archive filename is dropped in call to dirname below. + filename = loader.archive + else: + # At least one loader is missing both get_filename and archive: + # Google App Engine's HardenedModulesHook + # + # Fall back to imports. + __import__(import_name) + filename = sys.modules[import_name].__file__ + package_path = os.path.abspath(os.path.dirname(filename)) + + # In case the root module is a package we need to chop of the + # rightmost part. This needs to go through a helper function + # because of python 3.3 namespace packages. + if _matching_loader_thinks_module_is_package( + loader, root_mod_name): + package_path = os.path.dirname(package_path) + + site_parent, site_folder = os.path.split(package_path) + py_prefix = os.path.abspath(sys.prefix) + if package_path.startswith(py_prefix): + return py_prefix, package_path + elif site_folder.lower() == 'site-packages': + parent, folder = os.path.split(site_parent) + # Windows like installations + if folder.lower() == 'lib': + base_dir = parent + # UNIX like installations + elif os.path.basename(parent).lower() == 'lib': + base_dir = os.path.dirname(parent) + else: + base_dir = site_parent + return base_dir, package_path + return None, package_path + + +class locked_cached_property(object): + """A decorator that converts a function into a lazy property. The + function wrapped is called the first time to retrieve the result + and then that calculated result is used the next time you access + the value. Works like the one in Werkzeug but has a lock for + thread safety. + """ + + def __init__(self, func, name=None, doc=None): + self.__name__ = name or func.__name__ + self.__module__ = func.__module__ + self.__doc__ = doc or func.__doc__ + self.func = func + self.lock = RLock() + + def __get__(self, obj, type=None): + if obj is None: + return self + with self.lock: + value = obj.__dict__.get(self.__name__, _missing) + if value is _missing: + value = self.func(obj) + obj.__dict__[self.__name__] = value + return value + + +class _PackageBoundObject(object): + #: The name of the package or module that this app belongs to. Do not + #: change this once it is set by the constructor. + import_name = None + + #: Location of the template files to be added to the template lookup. + #: ``None`` if templates should not be added. + template_folder = None + + #: Absolute path to the package on the filesystem. Used to look up + #: resources contained in the package. + root_path = None + + def __init__(self, import_name, template_folder=None, root_path=None): + self.import_name = import_name + self.template_folder = template_folder + + if root_path is None: + root_path = get_root_path(self.import_name) + + self.root_path = root_path + self._static_folder = None + self._static_url_path = None + + def _get_static_folder(self): + if self._static_folder is not None: + return os.path.join(self.root_path, self._static_folder) + + def _set_static_folder(self, value): + self._static_folder = value + + static_folder = property( + _get_static_folder, _set_static_folder, + doc='The absolute path to the configured static folder.' + ) + del _get_static_folder, _set_static_folder + + def _get_static_url_path(self): + if self._static_url_path is not None: + return self._static_url_path + + if self.static_folder is not None: + return '/' + os.path.basename(self.static_folder) + + def _set_static_url_path(self, value): + self._static_url_path = value + + static_url_path = property( + _get_static_url_path, _set_static_url_path, + doc='The URL prefix that the static route will be registered for.' + ) + del _get_static_url_path, _set_static_url_path + + @property + def has_static_folder(self): + """This is ``True`` if the package bound object's container has a + folder for static files. + + .. versionadded:: 0.5 + """ + return self.static_folder is not None + + @locked_cached_property + def jinja_loader(self): + """The Jinja loader for this package bound object. + + .. versionadded:: 0.5 + """ + if self.template_folder is not None: + return FileSystemLoader(os.path.join(self.root_path, + self.template_folder)) + + def get_send_file_max_age(self, filename): + """Provides default cache_timeout for the :func:`send_file` functions. + + By default, this function returns ``SEND_FILE_MAX_AGE_DEFAULT`` from + the configuration of :data:`~flask.current_app`. + + Static file functions such as :func:`send_from_directory` use this + function, and :func:`send_file` calls this function on + :data:`~flask.current_app` when the given cache_timeout is ``None``. If a + cache_timeout is given in :func:`send_file`, that timeout is used; + otherwise, this method is called. + + This allows subclasses to change the behavior when sending files based + on the filename. For example, to set the cache timeout for .js files + to 60 seconds:: + + class MyFlask(flask.Flask): + def get_send_file_max_age(self, name): + if name.lower().endswith('.js'): + return 60 + return flask.Flask.get_send_file_max_age(self, name) + + .. versionadded:: 0.9 + """ + return total_seconds(current_app.send_file_max_age_default) + + def send_static_file(self, filename): + """Function used internally to send static files from the static + folder to the browser. + + .. versionadded:: 0.5 + """ + if not self.has_static_folder: + raise RuntimeError('No static folder for this object') + # Ensure get_send_file_max_age is called in all cases. + # Here, we ensure get_send_file_max_age is called for Blueprints. + cache_timeout = self.get_send_file_max_age(filename) + return send_from_directory(self.static_folder, filename, + cache_timeout=cache_timeout) + + def open_resource(self, resource, mode='rb'): + """Opens a resource from the application's resource folder. To see + how this works, consider the following folder structure:: + + /myapplication.py + /schema.sql + /static + /style.css + /templates + /layout.html + /index.html + + If you want to open the :file:`schema.sql` file you would do the + following:: + + with app.open_resource('schema.sql') as f: + contents = f.read() + do_something_with(contents) + + :param resource: the name of the resource. To access resources within + subfolders use forward slashes as separator. + :param mode: resource file opening mode, default is 'rb'. + """ + if mode not in ('r', 'rb'): + raise ValueError('Resources can only be opened for reading') + return open(os.path.join(self.root_path, resource), mode) + + +def total_seconds(td): + """Returns the total seconds from a timedelta object. + + :param timedelta td: the timedelta to be converted in seconds + + :returns: number of seconds + :rtype: int + """ + return td.days * 60 * 60 * 24 + td.seconds + + +def is_ip(value): + """Determine if the given string is an IP address. + + Python 2 on Windows doesn't provide ``inet_pton``, so this only + checks IPv4 addresses in that environment. + + :param value: value to check + :type value: str + + :return: True if string is an IP address + :rtype: bool + """ + if PY2 and os.name == 'nt': + try: + socket.inet_aton(value) + return True + except socket.error: + return False + + for family in (socket.AF_INET, socket.AF_INET6): + try: + socket.inet_pton(family, value) + except socket.error: + pass + else: + return True + + return False diff --git a/flask/venv/lib/python3.6/site-packages/flask/json/__init__.py b/flask/venv/lib/python3.6/site-packages/flask/json/__init__.py new file mode 100644 index 0000000..fbe6b92 --- /dev/null +++ b/flask/venv/lib/python3.6/site-packages/flask/json/__init__.py @@ -0,0 +1,327 @@ +# -*- coding: utf-8 -*- +""" +flask.json +~~~~~~~~~~ + +:copyright: © 2010 by the Pallets team. +:license: BSD, see LICENSE for more details. +""" +import codecs +import io +import uuid +from datetime import date, datetime +from flask.globals import current_app, request +from flask._compat import text_type, PY2 + +from werkzeug.http import http_date +from jinja2 import Markup + +# Use the same json implementation as itsdangerous on which we +# depend anyways. +from itsdangerous import json as _json + + +# Figure out if simplejson escapes slashes. This behavior was changed +# from one version to another without reason. +_slash_escape = '\\/' not in _json.dumps('/') + + +__all__ = ['dump', 'dumps', 'load', 'loads', 'htmlsafe_dump', + 'htmlsafe_dumps', 'JSONDecoder', 'JSONEncoder', + 'jsonify'] + + +def _wrap_reader_for_text(fp, encoding): + if isinstance(fp.read(0), bytes): + fp = io.TextIOWrapper(io.BufferedReader(fp), encoding) + return fp + + +def _wrap_writer_for_text(fp, encoding): + try: + fp.write('') + except TypeError: + fp = io.TextIOWrapper(fp, encoding) + return fp + + +class JSONEncoder(_json.JSONEncoder): + """The default Flask JSON encoder. This one extends the default simplejson + encoder by also supporting ``datetime`` objects, ``UUID`` as well as + ``Markup`` objects which are serialized as RFC 822 datetime strings (same + as the HTTP date format). In order to support more data types override the + :meth:`default` method. + """ + + def default(self, o): + """Implement this method in a subclass such that it returns a + serializable object for ``o``, or calls the base implementation (to + raise a :exc:`TypeError`). + + For example, to support arbitrary iterators, you could implement + default like this:: + + def default(self, o): + try: + iterable = iter(o) + except TypeError: + pass + else: + return list(iterable) + return JSONEncoder.default(self, o) + """ + if isinstance(o, datetime): + return http_date(o.utctimetuple()) + if isinstance(o, date): + return http_date(o.timetuple()) + if isinstance(o, uuid.UUID): + return str(o) + if hasattr(o, '__html__'): + return text_type(o.__html__()) + return _json.JSONEncoder.default(self, o) + + +class JSONDecoder(_json.JSONDecoder): + """The default JSON decoder. This one does not change the behavior from + the default simplejson decoder. Consult the :mod:`json` documentation + for more information. This decoder is not only used for the load + functions of this module but also :attr:`~flask.Request`. + """ + + +def _dump_arg_defaults(kwargs): + """Inject default arguments for dump functions.""" + if current_app: + bp = current_app.blueprints.get(request.blueprint) if request else None + kwargs.setdefault( + 'cls', + bp.json_encoder if bp and bp.json_encoder + else current_app.json_encoder + ) + + if not current_app.config['JSON_AS_ASCII']: + kwargs.setdefault('ensure_ascii', False) + + kwargs.setdefault('sort_keys', current_app.config['JSON_SORT_KEYS']) + else: + kwargs.setdefault('sort_keys', True) + kwargs.setdefault('cls', JSONEncoder) + + +def _load_arg_defaults(kwargs): + """Inject default arguments for load functions.""" + if current_app: + bp = current_app.blueprints.get(request.blueprint) if request else None + kwargs.setdefault( + 'cls', + bp.json_decoder if bp and bp.json_decoder + else current_app.json_decoder + ) + else: + kwargs.setdefault('cls', JSONDecoder) + + +def detect_encoding(data): + """Detect which UTF codec was used to encode the given bytes. + + The latest JSON standard (:rfc:`8259`) suggests that only UTF-8 is + accepted. Older documents allowed 8, 16, or 32. 16 and 32 can be big + or little endian. Some editors or libraries may prepend a BOM. + + :param data: Bytes in unknown UTF encoding. + :return: UTF encoding name + """ + head = data[:4] + + if head[:3] == codecs.BOM_UTF8: + return 'utf-8-sig' + + if b'\x00' not in head: + return 'utf-8' + + if head in (codecs.BOM_UTF32_BE, codecs.BOM_UTF32_LE): + return 'utf-32' + + if head[:2] in (codecs.BOM_UTF16_BE, codecs.BOM_UTF16_LE): + return 'utf-16' + + if len(head) == 4: + if head[:3] == b'\x00\x00\x00': + return 'utf-32-be' + + if head[::2] == b'\x00\x00': + return 'utf-16-be' + + if head[1:] == b'\x00\x00\x00': + return 'utf-32-le' + + if head[1::2] == b'\x00\x00': + return 'utf-16-le' + + if len(head) == 2: + return 'utf-16-be' if head.startswith(b'\x00') else 'utf-16-le' + + return 'utf-8' + + +def dumps(obj, **kwargs): + """Serialize ``obj`` to a JSON formatted ``str`` by using the application's + configured encoder (:attr:`~flask.Flask.json_encoder`) if there is an + application on the stack. + + This function can return ``unicode`` strings or ascii-only bytestrings by + default which coerce into unicode strings automatically. That behavior by + default is controlled by the ``JSON_AS_ASCII`` configuration variable + and can be overridden by the simplejson ``ensure_ascii`` parameter. + """ + _dump_arg_defaults(kwargs) + encoding = kwargs.pop('encoding', None) + rv = _json.dumps(obj, **kwargs) + if encoding is not None and isinstance(rv, text_type): + rv = rv.encode(encoding) + return rv + + +def dump(obj, fp, **kwargs): + """Like :func:`dumps` but writes into a file object.""" + _dump_arg_defaults(kwargs) + encoding = kwargs.pop('encoding', None) + if encoding is not None: + fp = _wrap_writer_for_text(fp, encoding) + _json.dump(obj, fp, **kwargs) + + +def loads(s, **kwargs): + """Unserialize a JSON object from a string ``s`` by using the application's + configured decoder (:attr:`~flask.Flask.json_decoder`) if there is an + application on the stack. + """ + _load_arg_defaults(kwargs) + if isinstance(s, bytes): + encoding = kwargs.pop('encoding', None) + if encoding is None: + encoding = detect_encoding(s) + s = s.decode(encoding) + return _json.loads(s, **kwargs) + + +def load(fp, **kwargs): + """Like :func:`loads` but reads from a file object. + """ + _load_arg_defaults(kwargs) + if not PY2: + fp = _wrap_reader_for_text(fp, kwargs.pop('encoding', None) or 'utf-8') + return _json.load(fp, **kwargs) + + +def htmlsafe_dumps(obj, **kwargs): + """Works exactly like :func:`dumps` but is safe for use in ``') + # => <script> do_nasty_stuff() </script> + # sanitize_html('Click here for $100') + # => Click here for $100 + 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"] = "" % 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/flask/venv/lib/python3.6/site-packages/pip/_vendor/html5lib/filters/whitespace.py b/flask/venv/lib/python3.6/site-packages/pip/_vendor/html5lib/filters/whitespace.py new file mode 100644 index 0000000..0d12584 --- /dev/null +++ b/flask/venv/lib/python3.6/site-packages/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/flask/venv/lib/python3.6/site-packages/pip/_vendor/html5lib/html5parser.py b/flask/venv/lib/python3.6/site-packages/pip/_vendor/html5lib/html5parser.py new file mode 100644 index 0000000..ae41a13 --- /dev/null +++ b/flask/venv/lib/python3.6/site-packages/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('

This is a doc

') + + + """ + 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('this is a fragment') + + + """ + 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('

This is a doc

') + + + """ + 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('this is a fragment') + + + """ + 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
, , and ",k.noCloneChecked=!!b.cloneNode(!0).lastChild.defaultValue,c.appendChild(b),b.innerHTML="",k.checkClone=b.cloneNode(!0).cloneNode(!0).lastChild.checked,k.noCloneEvent=!0,b.attachEvent&&(b.attachEvent("onclick",function(){k.noCloneEvent=!1}),b.cloneNode(!0).click()),null==k.deleteExpando){k.deleteExpando=!0;try{delete b.test}catch(d){k.deleteExpando=!1}}}(),function(){var b,c,d=y.createElement("div");for(b in{submit:!0,change:!0,focusin:!0})c="on"+b,(k[b+"Bubbles"]=c in a)||(d.setAttribute(c,"t"),k[b+"Bubbles"]=d.attributes[c].expando===!1);d=null}();var X=/^(?:input|select|textarea)$/i,Y=/^key/,Z=/^(?:mouse|pointer|contextmenu)|click/,$=/^(?:focusinfocus|focusoutblur)$/,_=/^([^.]*)(?:\.(.+)|)$/;function aa(){return!0}function ba(){return!1}function ca(){try{return y.activeElement}catch(a){}}m.event={global:{},add:function(a,b,c,d,e){var f,g,h,i,j,k,l,n,o,p,q,r=m._data(a);if(r){c.handler&&(i=c,c=i.handler,e=i.selector),c.guid||(c.guid=m.guid++),(g=r.events)||(g=r.events={}),(k=r.handle)||(k=r.handle=function(a){return typeof m===K||a&&m.event.triggered===a.type?void 0:m.event.dispatch.apply(k.elem,arguments)},k.elem=a),b=(b||"").match(E)||[""],h=b.length;while(h--)f=_.exec(b[h])||[],o=q=f[1],p=(f[2]||"").split(".").sort(),o&&(j=m.event.special[o]||{},o=(e?j.delegateType:j.bindType)||o,j=m.event.special[o]||{},l=m.extend({type:o,origType:q,data:d,handler:c,guid:c.guid,selector:e,needsContext:e&&m.expr.match.needsContext.test(e),namespace:p.join(".")},i),(n=g[o])||(n=g[o]=[],n.delegateCount=0,j.setup&&j.setup.call(a,d,p,k)!==!1||(a.addEventListener?a.addEventListener(o,k,!1):a.attachEvent&&a.attachEvent("on"+o,k))),j.add&&(j.add.call(a,l),l.handler.guid||(l.handler.guid=c.guid)),e?n.splice(n.delegateCount++,0,l):n.push(l),m.event.global[o]=!0);a=null}},remove:function(a,b,c,d,e){var f,g,h,i,j,k,l,n,o,p,q,r=m.hasData(a)&&m._data(a);if(r&&(k=r.events)){b=(b||"").match(E)||[""],j=b.length;while(j--)if(h=_.exec(b[j])||[],o=q=h[1],p=(h[2]||"").split(".").sort(),o){l=m.event.special[o]||{},o=(d?l.delegateType:l.bindType)||o,n=k[o]||[],h=h[2]&&new RegExp("(^|\\.)"+p.join("\\.(?:.*\\.|)")+"(\\.|$)"),i=f=n.length;while(f--)g=n[f],!e&&q!==g.origType||c&&c.guid!==g.guid||h&&!h.test(g.namespace)||d&&d!==g.selector&&("**"!==d||!g.selector)||(n.splice(f,1),g.selector&&n.delegateCount--,l.remove&&l.remove.call(a,g));i&&!n.length&&(l.teardown&&l.teardown.call(a,p,r.handle)!==!1||m.removeEvent(a,o,r.handle),delete k[o])}else for(o in k)m.event.remove(a,o+b[j],c,d,!0);m.isEmptyObject(k)&&(delete r.handle,m._removeData(a,"events"))}},trigger:function(b,c,d,e){var f,g,h,i,k,l,n,o=[d||y],p=j.call(b,"type")?b.type:b,q=j.call(b,"namespace")?b.namespace.split("."):[];if(h=l=d=d||y,3!==d.nodeType&&8!==d.nodeType&&!$.test(p+m.event.triggered)&&(p.indexOf(".")>=0&&(q=p.split("."),p=q.shift(),q.sort()),g=p.indexOf(":")<0&&"on"+p,b=b[m.expando]?b:new m.Event(p,"object"==typeof b&&b),b.isTrigger=e?2:3,b.namespace=q.join("."),b.namespace_re=b.namespace?new RegExp("(^|\\.)"+q.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,b.result=void 0,b.target||(b.target=d),c=null==c?[b]:m.makeArray(c,[b]),k=m.event.special[p]||{},e||!k.trigger||k.trigger.apply(d,c)!==!1)){if(!e&&!k.noBubble&&!m.isWindow(d)){for(i=k.delegateType||p,$.test(i+p)||(h=h.parentNode);h;h=h.parentNode)o.push(h),l=h;l===(d.ownerDocument||y)&&o.push(l.defaultView||l.parentWindow||a)}n=0;while((h=o[n++])&&!b.isPropagationStopped())b.type=n>1?i:k.bindType||p,f=(m._data(h,"events")||{})[b.type]&&m._data(h,"handle"),f&&f.apply(h,c),f=g&&h[g],f&&f.apply&&m.acceptData(h)&&(b.result=f.apply(h,c),b.result===!1&&b.preventDefault());if(b.type=p,!e&&!b.isDefaultPrevented()&&(!k._default||k._default.apply(o.pop(),c)===!1)&&m.acceptData(d)&&g&&d[p]&&!m.isWindow(d)){l=d[g],l&&(d[g]=null),m.event.triggered=p;try{d[p]()}catch(r){}m.event.triggered=void 0,l&&(d[g]=l)}return b.result}},dispatch:function(a){a=m.event.fix(a);var b,c,e,f,g,h=[],i=d.call(arguments),j=(m._data(this,"events")||{})[a.type]||[],k=m.event.special[a.type]||{};if(i[0]=a,a.delegateTarget=this,!k.preDispatch||k.preDispatch.call(this,a)!==!1){h=m.event.handlers.call(this,a,j),b=0;while((f=h[b++])&&!a.isPropagationStopped()){a.currentTarget=f.elem,g=0;while((e=f.handlers[g++])&&!a.isImmediatePropagationStopped())(!a.namespace_re||a.namespace_re.test(e.namespace))&&(a.handleObj=e,a.data=e.data,c=((m.event.special[e.origType]||{}).handle||e.handler).apply(f.elem,i),void 0!==c&&(a.result=c)===!1&&(a.preventDefault(),a.stopPropagation()))}return k.postDispatch&&k.postDispatch.call(this,a),a.result}},handlers:function(a,b){var c,d,e,f,g=[],h=b.delegateCount,i=a.target;if(h&&i.nodeType&&(!a.button||"click"!==a.type))for(;i!=this;i=i.parentNode||this)if(1===i.nodeType&&(i.disabled!==!0||"click"!==a.type)){for(e=[],f=0;h>f;f++)d=b[f],c=d.selector+" ",void 0===e[c]&&(e[c]=d.needsContext?m(c,this).index(i)>=0:m.find(c,this,null,[i]).length),e[c]&&e.push(d);e.length&&g.push({elem:i,handlers:e})}return h]","i"),ha=/^\s+/,ia=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,ja=/<([\w:]+)/,ka=/\s*$/g,ra={option:[1,""],legend:[1,"
","
"],area:[1,"",""],param:[1,"",""],thead:[1,"","
"],tr:[2,"","
"],col:[2,"","
"],td:[3,"","
"],_default:k.htmlSerialize?[0,"",""]:[1,"X
","
"]},sa=da(y),ta=sa.appendChild(y.createElement("div"));ra.optgroup=ra.option,ra.tbody=ra.tfoot=ra.colgroup=ra.caption=ra.thead,ra.th=ra.td;function ua(a,b){var c,d,e=0,f=typeof a.getElementsByTagName!==K?a.getElementsByTagName(b||"*"):typeof a.querySelectorAll!==K?a.querySelectorAll(b||"*"):void 0;if(!f)for(f=[],c=a.childNodes||a;null!=(d=c[e]);e++)!b||m.nodeName(d,b)?f.push(d):m.merge(f,ua(d,b));return void 0===b||b&&m.nodeName(a,b)?m.merge([a],f):f}function va(a){W.test(a.type)&&(a.defaultChecked=a.checked)}function wa(a,b){return m.nodeName(a,"table")&&m.nodeName(11!==b.nodeType?b:b.firstChild,"tr")?a.getElementsByTagName("tbody")[0]||a.appendChild(a.ownerDocument.createElement("tbody")):a}function xa(a){return a.type=(null!==m.find.attr(a,"type"))+"/"+a.type,a}function ya(a){var b=pa.exec(a.type);return b?a.type=b[1]:a.removeAttribute("type"),a}function za(a,b){for(var c,d=0;null!=(c=a[d]);d++)m._data(c,"globalEval",!b||m._data(b[d],"globalEval"))}function Aa(a,b){if(1===b.nodeType&&m.hasData(a)){var c,d,e,f=m._data(a),g=m._data(b,f),h=f.events;if(h){delete g.handle,g.events={};for(c in h)for(d=0,e=h[c].length;e>d;d++)m.event.add(b,c,h[c][d])}g.data&&(g.data=m.extend({},g.data))}}function Ba(a,b){var c,d,e;if(1===b.nodeType){if(c=b.nodeName.toLowerCase(),!k.noCloneEvent&&b[m.expando]){e=m._data(b);for(d in e.events)m.removeEvent(b,d,e.handle);b.removeAttribute(m.expando)}"script"===c&&b.text!==a.text?(xa(b).text=a.text,ya(b)):"object"===c?(b.parentNode&&(b.outerHTML=a.outerHTML),k.html5Clone&&a.innerHTML&&!m.trim(b.innerHTML)&&(b.innerHTML=a.innerHTML)):"input"===c&&W.test(a.type)?(b.defaultChecked=b.checked=a.checked,b.value!==a.value&&(b.value=a.value)):"option"===c?b.defaultSelected=b.selected=a.defaultSelected:("input"===c||"textarea"===c)&&(b.defaultValue=a.defaultValue)}}m.extend({clone:function(a,b,c){var d,e,f,g,h,i=m.contains(a.ownerDocument,a);if(k.html5Clone||m.isXMLDoc(a)||!ga.test("<"+a.nodeName+">")?f=a.cloneNode(!0):(ta.innerHTML=a.outerHTML,ta.removeChild(f=ta.firstChild)),!(k.noCloneEvent&&k.noCloneChecked||1!==a.nodeType&&11!==a.nodeType||m.isXMLDoc(a)))for(d=ua(f),h=ua(a),g=0;null!=(e=h[g]);++g)d[g]&&Ba(e,d[g]);if(b)if(c)for(h=h||ua(a),d=d||ua(f),g=0;null!=(e=h[g]);g++)Aa(e,d[g]);else Aa(a,f);return d=ua(f,"script"),d.length>0&&za(d,!i&&ua(a,"script")),d=h=e=null,f},buildFragment:function(a,b,c,d){for(var e,f,g,h,i,j,l,n=a.length,o=da(b),p=[],q=0;n>q;q++)if(f=a[q],f||0===f)if("object"===m.type(f))m.merge(p,f.nodeType?[f]:f);else if(la.test(f)){h=h||o.appendChild(b.createElement("div")),i=(ja.exec(f)||["",""])[1].toLowerCase(),l=ra[i]||ra._default,h.innerHTML=l[1]+f.replace(ia,"<$1>")+l[2],e=l[0];while(e--)h=h.lastChild;if(!k.leadingWhitespace&&ha.test(f)&&p.push(b.createTextNode(ha.exec(f)[0])),!k.tbody){f="table"!==i||ka.test(f)?""!==l[1]||ka.test(f)?0:h:h.firstChild,e=f&&f.childNodes.length;while(e--)m.nodeName(j=f.childNodes[e],"tbody")&&!j.childNodes.length&&f.removeChild(j)}m.merge(p,h.childNodes),h.textContent="";while(h.firstChild)h.removeChild(h.firstChild);h=o.lastChild}else p.push(b.createTextNode(f));h&&o.removeChild(h),k.appendChecked||m.grep(ua(p,"input"),va),q=0;while(f=p[q++])if((!d||-1===m.inArray(f,d))&&(g=m.contains(f.ownerDocument,f),h=ua(o.appendChild(f),"script"),g&&za(h),c)){e=0;while(f=h[e++])oa.test(f.type||"")&&c.push(f)}return h=null,o},cleanData:function(a,b){for(var d,e,f,g,h=0,i=m.expando,j=m.cache,l=k.deleteExpando,n=m.event.special;null!=(d=a[h]);h++)if((b||m.acceptData(d))&&(f=d[i],g=f&&j[f])){if(g.events)for(e in g.events)n[e]?m.event.remove(d,e):m.removeEvent(d,e,g.handle);j[f]&&(delete j[f],l?delete d[i]:typeof d.removeAttribute!==K?d.removeAttribute(i):d[i]=null,c.push(f))}}}),m.fn.extend({text:function(a){return V(this,function(a){return void 0===a?m.text(this):this.empty().append((this[0]&&this[0].ownerDocument||y).createTextNode(a))},null,a,arguments.length)},append:function(){return this.domManip(arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=wa(this,a);b.appendChild(a)}})},prepend:function(){return this.domManip(arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=wa(this,a);b.insertBefore(a,b.firstChild)}})},before:function(){return this.domManip(arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this)})},after:function(){return this.domManip(arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this.nextSibling)})},remove:function(a,b){for(var c,d=a?m.filter(a,this):this,e=0;null!=(c=d[e]);e++)b||1!==c.nodeType||m.cleanData(ua(c)),c.parentNode&&(b&&m.contains(c.ownerDocument,c)&&za(ua(c,"script")),c.parentNode.removeChild(c));return this},empty:function(){for(var a,b=0;null!=(a=this[b]);b++){1===a.nodeType&&m.cleanData(ua(a,!1));while(a.firstChild)a.removeChild(a.firstChild);a.options&&m.nodeName(a,"select")&&(a.options.length=0)}return this},clone:function(a,b){return a=null==a?!1:a,b=null==b?a:b,this.map(function(){return m.clone(this,a,b)})},html:function(a){return V(this,function(a){var b=this[0]||{},c=0,d=this.length;if(void 0===a)return 1===b.nodeType?b.innerHTML.replace(fa,""):void 0;if(!("string"!=typeof a||ma.test(a)||!k.htmlSerialize&&ga.test(a)||!k.leadingWhitespace&&ha.test(a)||ra[(ja.exec(a)||["",""])[1].toLowerCase()])){a=a.replace(ia,"<$1>");try{for(;d>c;c++)b=this[c]||{},1===b.nodeType&&(m.cleanData(ua(b,!1)),b.innerHTML=a);b=0}catch(e){}}b&&this.empty().append(a)},null,a,arguments.length)},replaceWith:function(){var a=arguments[0];return this.domManip(arguments,function(b){a=this.parentNode,m.cleanData(ua(this)),a&&a.replaceChild(b,this)}),a&&(a.length||a.nodeType)?this:this.remove()},detach:function(a){return this.remove(a,!0)},domManip:function(a,b){a=e.apply([],a);var c,d,f,g,h,i,j=0,l=this.length,n=this,o=l-1,p=a[0],q=m.isFunction(p);if(q||l>1&&"string"==typeof p&&!k.checkClone&&na.test(p))return this.each(function(c){var d=n.eq(c);q&&(a[0]=p.call(this,c,d.html())),d.domManip(a,b)});if(l&&(i=m.buildFragment(a,this[0].ownerDocument,!1,this),c=i.firstChild,1===i.childNodes.length&&(i=c),c)){for(g=m.map(ua(i,"script"),xa),f=g.length;l>j;j++)d=i,j!==o&&(d=m.clone(d,!0,!0),f&&m.merge(g,ua(d,"script"))),b.call(this[j],d,j);if(f)for(h=g[g.length-1].ownerDocument,m.map(g,ya),j=0;f>j;j++)d=g[j],oa.test(d.type||"")&&!m._data(d,"globalEval")&&m.contains(h,d)&&(d.src?m._evalUrl&&m._evalUrl(d.src):m.globalEval((d.text||d.textContent||d.innerHTML||"").replace(qa,"")));i=c=null}return this}}),m.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){m.fn[a]=function(a){for(var c,d=0,e=[],g=m(a),h=g.length-1;h>=d;d++)c=d===h?this:this.clone(!0),m(g[d])[b](c),f.apply(e,c.get());return this.pushStack(e)}});var Ca,Da={};function Ea(b,c){var d,e=m(c.createElement(b)).appendTo(c.body),f=a.getDefaultComputedStyle&&(d=a.getDefaultComputedStyle(e[0]))?d.display:m.css(e[0],"display");return e.detach(),f}function Fa(a){var b=y,c=Da[a];return c||(c=Ea(a,b),"none"!==c&&c||(Ca=(Ca||m("