Skip to content

Commit 1724c55

Browse files
committedOct 23, 2019
lazily imports more modules for performance
1 parent 89f7279 commit 1724c55

File tree

4 files changed

+44
-20
lines changed

4 files changed

+44
-20
lines changed
 

‎src/cs50/__init__.py

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,28 @@
11
import os
22
import sys
33

4+
5+
class CustomImporter(object):
6+
"""
7+
Import cs50.SQL lazily for performance (and so that rest of library can be used without SQLAlchemy installed).
8+
https://docs.python.org/3/library/imp.html
9+
http://xion.org.pl/2012/05/06/hacking-python-imports/
10+
http://dangerontheranger.blogspot.com/2012/07/how-to-use-sysmetapath-with-python.html
11+
"""
12+
13+
def find_module(self, fullname, path=None):
14+
if fullname == "cs50.SQL":
15+
return self
16+
return None
17+
18+
def load_module(self, name):
19+
if name in sys.modules:
20+
return sys.modules[name]
21+
from .sql import SQL
22+
sys.modules[name] = SQL
23+
return SQL
24+
25+
426
try:
527

628
# Save student's sys.path
@@ -19,8 +41,8 @@
1941
# Replace Flask's logger
2042
from . import flask
2143

22-
# Wrap SQLAlchemy
23-
from .sql import SQL
44+
# Lazily load CS50.SQL
45+
sys.meta_path.append(CustomImporter())
2446

2547
finally:
2648

‎src/cs50/flask.py

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

33
from distutils.version import StrictVersion
4-
from os import getenv
54
from pkg_resources import get_distribution
65

76
from .cs50 import _formatException
@@ -44,6 +43,7 @@ def _execute_after(*args, **kwargs):
4443

4544
# When behind CS50 IDE's proxy, ensure that flask.redirect doesn't redirect from HTTPS to HTTP
4645
# https://werkzeug.palletsprojects.com/en/0.15.x/middleware/proxy_fix/#module-werkzeug.middleware.proxy_fix
46+
from os import getenv
4747
if getenv("CS50_IDE_TYPE") == "online":
4848
try:
4949
import flask

‎src/cs50/sql.py

Lines changed: 17 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,3 @@
1-
import datetime
2-
import decimal
3-
import importlib
4-
import logging
5-
import os
6-
import re
7-
import sqlalchemy
8-
import sqlite3
9-
import sqlparse
10-
import sys
11-
import termcolor
12-
import warnings
13-
14-
151
class SQL(object):
162
"""Wrap SQLAlchemy to provide a simple SQL API."""
173

@@ -25,6 +11,13 @@ def __init__(self, url, **kwargs):
2511
http://docs.sqlalchemy.org/en/latest/dialects/index.html
2612
"""
2713

14+
# Lazily import
15+
import logging
16+
import os
17+
import re
18+
import sqlalchemy
19+
import sqlite3
20+
2821
# Get logger
2922
self._logger = logging.getLogger("cs50")
3023

@@ -74,6 +67,12 @@ def connect(dbapi_connection, connection_record):
7467
def execute(self, sql, *args, **kwargs):
7568
"""Execute a SQL statement."""
7669

70+
# Lazily import
71+
import decimal
72+
import sqlparse
73+
import termcolor
74+
import warnings
75+
7776
# Allow only one statement at a time, since SQLite doesn't support multiple
7877
# https://docs.python.org/3/library/sqlite3.html#sqlite3.Cursor.execute
7978
statements = sqlparse.parse(sql)
@@ -217,7 +216,7 @@ def execute(self, sql, *args, **kwargs):
217216

218217
# Catch SQLAlchemy warnings
219218
with warnings.catch_warnings():
220-
219+
221220
# Raise exceptions for warnings
222221
warnings.simplefilter("error")
223222

@@ -284,6 +283,9 @@ def _escape(self, value):
284283

285284
def __escape(value):
286285

286+
# Lazily import
287+
import datetime
288+
287289
# bool
288290
if type(value) is bool:
289291
return sqlparse.sql.Token(

‎tests/python.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,5 @@
44

55
import cs50
66

7-
i = cs50.get_int()
8-
print(i)
7+
i = cs50.get_int("Input: ")
8+
print(f"Output: {i}")

0 commit comments

Comments
 (0)