Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit a706a5e

Browse files
committedOct 30, 2017
reimplemented exception-darkening code, added support for Flask
1 parent df491f9 commit a706a5e

File tree

9 files changed

+109
-23
lines changed

9 files changed

+109
-23
lines changed
 

‎src/cs50/__init__.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,12 @@
11
import sys
22

3-
from .cs50 import *
3+
from .cs50 import eprint, get_char, get_float, get_int, get_string
4+
try:
5+
from .cs50 import get_long
6+
except:
7+
pass
8+
9+
from . import flask
410

511

612
class CustomImporter(object):

‎src/cs50/cs50.py

Lines changed: 27 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -6,28 +6,8 @@
66

77
from distutils.sysconfig import get_python_lib
88
from os.path import abspath, join
9-
from termcolor import cprint
10-
from traceback import extract_tb, format_list, format_exception_only
11-
12-
13-
def excepthook(type, value, tb):
14-
"""
15-
Format traceback, darkening entries from global site-packages directories
16-
and user-specific site-packages directory.
17-
18-
https://stackoverflow.com/a/46071447/5156190
19-
"""
20-
packages = tuple(join(abspath(p), "") for p in sys.path[1:])
21-
for entry in extract_tb(tb):
22-
fmt = format_list((entry,))
23-
if (entry[0].startswith(packages)):
24-
cprint("".join(fmt), attrs=["dark"], end="", file=sys.stderr)
25-
else:
26-
cprint("".join(fmt), end="", file=sys.stderr)
27-
cprint("".join(format_exception_only(type, value)), end="")
28-
29-
30-
sys.excepthook = excepthook
9+
from termcolor import colored
10+
from traceback import extract_tb, format_list, format_exception_only, format_exception
3111

3212

3313
class flushfile():
@@ -64,6 +44,31 @@ def eprint(*args, **kwargs):
6444
print(*args, end=end, file=sys.stderr, sep=sep)
6545

6646

47+
def formatException(type, value, tb):
48+
"""
49+
Format traceback, darkening entries from global site-packages directories
50+
and user-specific site-packages directory.
51+
52+
https://stackoverflow.com/a/46071447/5156190
53+
"""
54+
55+
# Absolute paths to site-packages
56+
packages = tuple(join(abspath(p), "") for p in sys.path[1:])
57+
58+
# Darken lines referring to files in site-packages
59+
lines = []
60+
for line in format_exception(type, value, tb):
61+
matches = re.search(r"^ File \"([^\"]+)\", line \d+, in .+", line)
62+
if matches and matches.group(1).startswith(packages):
63+
lines += colored(line, attrs=["dark"])
64+
else:
65+
lines += line
66+
return "".join(lines).rstrip()
67+
68+
69+
sys.excepthook = lambda type, value, tb: print(formatException(type, value, tb), file=sys.stderr)
70+
71+
6772
def get_char(prompt=None):
6873
"""
6974
Read a line of text from standard input and return the equivalent char;

‎src/cs50/flask.py

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
from distutils.version import StrictVersion
2+
from pkg_resources import get_distribution
3+
4+
from .cs50 import formatException
5+
6+
# Try to monkey-patch Flask, if installed
7+
try:
8+
9+
# Only patch 0.12 (in case logging changes in 0.13)
10+
version = StrictVersion(get_distribution("flask").version)
11+
assert version >= StrictVersion("0.12") and version < StrictVersion("0.13")
12+
13+
# Get default logger
14+
import flask.logging
15+
f = flask.logging.create_logger
16+
17+
def create_logger(app):
18+
"""Wrap default logger"""
19+
20+
# Create default logger
21+
logger = f(app)
22+
23+
# Reformat default logger's exceptions
24+
# https://docs.python.org/3/library/logging.html#logging.Formatter.formatException
25+
for handler in logger.handlers:
26+
handler.formatter.formatException = lambda exc_info: formatException(*exc_info)
27+
return logger
28+
29+
# Replace default logger
30+
flask.logging.create_logger = create_logger
31+
32+
except:
33+
pass

‎tests/flask/application.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
from flask import Flask, render_template
2+
3+
app = Flask(__name__)
4+
5+
import cs50
6+
import requests
7+
@app.route("/")
8+
def index():
9+
def f():
10+
res = requests.get("cs50.harvard.edu")
11+
f()
12+
return render_template("index.html")
13+
14+
@app.route("/foo", methods=["POST"])
15+
def foo():
16+
return ""

‎tests/flask/requirements.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
cs50
2+
Flask

‎tests/flask/templates/error.html

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<!DOCTYPE html>
2+
3+
<html>
4+
<head>
5+
<title>error</title>
6+
</head>
7+
<body>
8+
error
9+
</body>
10+
</html>

‎tests/flask/templates/index.html

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<!DOCTYPE html>
2+
3+
<html>
4+
<head>
5+
<title>flask</title>
6+
</head>
7+
<body>
8+
flask
9+
</body>
10+
</html>
File renamed without changes.

‎tests/sqlite.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
from cs50 import SQL
2+
3+
db = SQL("sqlite:///sqlite.db")
4+
db.execute("SELECT 1")

0 commit comments

Comments
 (0)
Please sign in to comment.