Skip to content

Commit a3b3cc5

Browse files
author
Kareem Zidane
authored
Merge pull request #135 from cs50/develop
Fixes support for transactions, drops support for unpacking of args to execute
2 parents 2d40229 + 4887b5f commit a3b3cc5

File tree

9 files changed

+248
-251
lines changed

9 files changed

+248
-251
lines changed

README.md

+71
Original file line numberDiff line numberDiff line change
@@ -19,3 +19,74 @@ f = cs50.get_float();
1919
i = cs50.get_int();
2020
s = cs50.get_string();
2121
```
22+
23+
## Testing
24+
25+
1. Run `cli50` in `python-cs50`.
26+
1. Run `sudo su -`.
27+
1. Run `apt install -y libmysqlclient-dev mysql-server postgresql`.
28+
1. Run `pip3 install mysqlclient psycopg2-binary`.
29+
1. In `/etc/mysql/mysql.conf.d/mysqld.cnf`, add `skip-grant-tables` under `[mysqld]`.
30+
1. In `/etc/profile.d/cli.sh`, remove `valgrind` function for now.
31+
1. Run `service mysql start`.
32+
1. Run `mysql -e 'CREATE DATABASE IF NOT EXISTS test;'`.
33+
1. In `/etc/postgresql/10/main/pg_hba.conf, change:
34+
```
35+
local all postgres peer
36+
host all all 127.0.0.1/32 md5
37+
```
38+
to:
39+
```
40+
local all postgres trust
41+
host all all 127.0.0.1/32 trust
42+
```
43+
1. Run `service postgresql start`.
44+
1. Run `psql -c 'create database test;' -U postgres`.
45+
1. Run `touch test.db`.
46+
47+
### Sample Tests
48+
49+
```
50+
import cs50
51+
db = cs50.SQL("sqlite:///foo.db")
52+
db.execute("CREATE TABLE IF NOT EXISTS cs50 (id INTEGER PRIMARY KEY, val TEXT, bin BLOB)")
53+
db.execute("INSERT INTO cs50 (val) VALUES('a')")
54+
db.execute("INSERT INTO cs50 (val) VALUES('b')")
55+
db.execute("BEGIN")
56+
db.execute("INSERT INTO cs50 (val) VALUES('c')")
57+
db.execute("INSERT INTO cs50 (val) VALUES('x')")
58+
db.execute("INSERT INTO cs50 (val) VALUES('y')")
59+
db.execute("ROLLBACK")
60+
db.execute("INSERT INTO cs50 (val) VALUES('z')")
61+
db.execute("COMMIT")
62+
63+
---
64+
65+
import cs50
66+
db = cs50.SQL("mysql://root@localhost/test")
67+
db.execute("CREATE TABLE IF NOT EXISTS cs50 (id INTEGER PRIMARY KEY, val TEXT, bin BLOB)")
68+
db.execute("INSERT INTO cs50 (val) VALUES('a')")
69+
db.execute("INSERT INTO cs50 (val) VALUES('b')")
70+
db.execute("BEGIN")
71+
db.execute("INSERT INTO cs50 (val) VALUES('c')")
72+
db.execute("INSERT INTO cs50 (val) VALUES('x')")
73+
db.execute("INSERT INTO cs50 (val) VALUES('y')")
74+
db.execute("ROLLBACK")
75+
db.execute("INSERT INTO cs50 (val) VALUES('z')")
76+
db.execute("COMMIT")
77+
78+
---
79+
80+
import cs50
81+
db = cs50.SQL("postgresql://postgres@localhost/test")
82+
db.execute("CREATE TABLE IF NOT EXISTS cs50 (id SERIAL PRIMARY KEY, val VARCHAR(16), bin BYTEA)")
83+
db.execute("INSERT INTO cs50 (val) VALUES('a')")
84+
db.execute("INSERT INTO cs50 (val) VALUES('b')")
85+
db.execute("BEGIN")
86+
db.execute("INSERT INTO cs50 (val) VALUES('c')")
87+
db.execute("INSERT INTO cs50 (val) VALUES('x')")
88+
db.execute("INSERT INTO cs50 (val) VALUES('y')")
89+
db.execute("ROLLBACK")
90+
db.execute("INSERT INTO cs50 (val) VALUES('z')")
91+
db.execute("COMMIT")
92+
```

setup.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -16,5 +16,5 @@
1616
package_dir={"": "src"},
1717
packages=["cs50"],
1818
url="https://github.com/cs50/python-cs50",
19-
version="5.1.0"
19+
version="6.0.0"
2020
)

src/cs50/cs50.py

+27
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
from __future__ import print_function
22

33
import inspect
4+
import logging
45
import os
56
import re
67
import sys
@@ -11,6 +12,32 @@
1112
from traceback import format_exception
1213

1314

15+
# Configure default logging handler and formatter
16+
# Prevent flask, werkzeug, etc from adding default handler
17+
logging.basicConfig(format="%(levelname)s: %(message)s", level=logging.DEBUG)
18+
19+
try:
20+
# Patch formatException
21+
logging.root.handlers[0].formatter.formatException = lambda exc_info: _formatException(*exc_info)
22+
except IndexError:
23+
pass
24+
25+
# Configure cs50 logger
26+
_logger = logging.getLogger("cs50")
27+
_logger.setLevel(logging.DEBUG)
28+
29+
# Log messages once
30+
_logger.propagate = False
31+
32+
handler = logging.StreamHandler()
33+
handler.setLevel(logging.DEBUG)
34+
35+
formatter = logging.Formatter("%(levelname)s: %(message)s")
36+
formatter.formatException = lambda exc_info: _formatException(*exc_info)
37+
handler.setFormatter(formatter)
38+
_logger.addHandler(handler)
39+
40+
1441
class _flushfile():
1542
"""
1643
Disable buffering for standard output and standard error.

src/cs50/flask.py

+3-5
Original file line numberDiff line numberDiff line change
@@ -12,22 +12,20 @@ def _wrap_flask(f):
1212
if f.__version__ < StrictVersion("1.0"):
1313
return
1414

15-
f.logging.default_handler.formatter.formatException = lambda exc_info: _formatException(*exc_info)
16-
1715
if os.getenv("CS50_IDE_TYPE") == "online":
1816
from werkzeug.middleware.proxy_fix import ProxyFix
1917
_flask_init_before = f.Flask.__init__
2018
def _flask_init_after(self, *args, **kwargs):
2119
_flask_init_before(self, *args, **kwargs)
22-
self.wsgi_app = ProxyFix(self.wsgi_app, x_proto=1)
20+
self.wsgi_app = ProxyFix(self.wsgi_app, x_proto=1) # For HTTPS-to-HTTP proxy
2321
f.Flask.__init__ = _flask_init_after
2422

2523

26-
# Flask was imported before cs50
24+
# If Flask was imported before cs50
2725
if "flask" in sys.modules:
2826
_wrap_flask(sys.modules["flask"])
2927

30-
# Flask wasn't imported
28+
# If Flask wasn't imported
3129
else:
3230
flask_loader = pkgutil.get_loader('flask')
3331
if flask_loader:

0 commit comments

Comments
 (0)