diff --git a/README.md b/README.md index 4d687f3..fb37280 100644 --- a/README.md +++ b/README.md @@ -10,11 +10,12 @@ pip install cs50 ## Usage - import cs50 +``` +import cs50 - ... +... - c = cs50.get_char(); - f = cs50.get_float(); - i = cs50.get_int(); - s = cs50.get_string(); +f = cs50.get_float(); +i = cs50.get_int(); +s = cs50.get_string(); +``` diff --git a/setup.py b/setup.py index 3ca103a..5b56aad 100644 --- a/setup.py +++ b/setup.py @@ -16,5 +16,5 @@ package_dir={"": "src"}, packages=["cs50"], url="https://github.com/cs50/python-cs50", - version="3.2.0" + version="4.0.0" ) diff --git a/src/cs50/cs50.py b/src/cs50/cs50.py index 2fc4912..2e92239 100644 --- a/src/cs50/cs50.py +++ b/src/cs50/cs50.py @@ -1,16 +1,17 @@ from __future__ import print_function import inspect +import os import re import sys from distutils.sysconfig import get_python_lib from os.path import abspath, join from termcolor import colored -from traceback import extract_tb, format_list, format_exception_only, format_exception +from traceback import format_exception -class flushfile(): +class _flushfile(): """ Disable buffering for standard output and standard error. @@ -28,23 +29,11 @@ def write(self, x): self.f.flush() -sys.stderr = flushfile(sys.stderr) -sys.stdout = flushfile(sys.stdout) +sys.stderr = _flushfile(sys.stderr) +sys.stdout = _flushfile(sys.stdout) -def eprint(*args, **kwargs): - """ - Print an error message to standard error, prefixing it with - file name and line number from which method was called. - """ - end = kwargs.get("end", "\n") - sep = kwargs.get("sep", " ") - (filename, lineno) = inspect.stack()[1][1:3] - print("{}:{}: ".format(filename, lineno), end="") - print(*args, end=end, file=sys.stderr, sep=sep) - - -def formatException(type, value, tb): +def _formatException(type, value, tb): """ Format traceback, darkening entries from global site-packages directories and user-specific site-packages directory. @@ -67,28 +56,18 @@ def formatException(type, value, tb): return "".join(lines).rstrip() -sys.excepthook = lambda type, value, tb: print(formatException(type, value, tb), file=sys.stderr) +sys.excepthook = lambda type, value, tb: print(_formatException(type, value, tb), file=sys.stderr) -def get_char(prompt=None): - """ - Read a line of text from standard input and return the equivalent char; - if text is not a single char, user is prompted to retry. If line can't - be read, return None. - """ - while True: - s = get_string(prompt) - if s is None: - return None - if len(s) == 1: - return s[0] +def eprint(*args, **kwargs): + raise RuntimeError("The CS50 Library for Python no longer supports eprint, but you can use print instead!") - # Temporarily here for backwards compatibility - if prompt is None: - print("Retry: ", end="") +def get_char(prompt): + raise RuntimeError("The CS50 Library for Python no longer supports get_char, but you can use get_string instead!") -def get_float(prompt=None): + +def get_float(prompt): """ Read a line of text from standard input and return the equivalent float as precisely as possible; if text does not represent a double, user is @@ -104,12 +83,8 @@ def get_float(prompt=None): except ValueError: pass - # Temporarily here for backwards compatibility - if prompt is None: - print("Retry: ", end="") - -def get_int(prompt=None): +def get_int(prompt): """ Read a line of text from standard input and return the equivalent int; if text does not represent an int, user is prompted to retry. If line @@ -121,40 +96,12 @@ def get_int(prompt=None): return None if re.search(r"^[+-]?\d+$", s): try: - i = int(s, 10) - if type(i) is int: # Could become long in Python 2 - return i + return int(s, 10) except ValueError: pass - # Temporarily here for backwards compatibility - if prompt is None: - print("Retry: ", end="") - - -if sys.version_info.major != 3: - def get_long(prompt=None): - """ - Read a line of text from standard input and return the equivalent long; - if text does not represent a long, user is prompted to retry. If line - can't be read, return None. - """ - while True: - s = get_string(prompt) - if s is None: - return None - if re.search(r"^[+-]?\d+$", s): - try: - return long(s, 10) - except ValueError: - pass - - # Temporarily here for backwards compatibility - if prompt is None: - print("Retry: ", end="") - - -def get_string(prompt=None): + +def get_string(prompt): """ Read a line of text from standard input and return it as a string, sans trailing line ending. Supports CR (\r), LF (\n), and CRLF (\r\n) diff --git a/src/cs50/flask.py b/src/cs50/flask.py index d4a063c..a20d53c 100644 --- a/src/cs50/flask.py +++ b/src/cs50/flask.py @@ -4,7 +4,7 @@ from os import getenv from pkg_resources import get_distribution -from .cs50 import formatException +from .cs50 import _formatException # Try to monkey-patch Flask, if installed try: @@ -18,7 +18,7 @@ # https://docs.python.org/3/library/logging.html#logging.Formatter.formatException try: import flask.logging - flask.logging.default_handler.formatter.formatException = lambda exc_info: formatException(*exc_info) + flask.logging.default_handler.formatter.formatException = lambda exc_info: _formatException(*exc_info) except Exception: pass @@ -42,16 +42,16 @@ def _after(*args, **kwargs): logging.getLogger("cs50").disabled = disabled SQL.execute = _after - # Add support for Cloud9 proxy so that flask.redirect doesn't redirect from HTTPS to HTTP - # http://stackoverflow.com/a/23504684/5156190 + # When behind CS50 IDE's proxy, ensure that flask.redirect doesn't redirect from HTTPS to HTTP + # https://werkzeug.palletsprojects.com/en/0.15.x/middleware/proxy_fix/#module-werkzeug.middleware.proxy_fix if getenv("C9_HOSTNAME") and not getenv("IDE_OFFLINE"): try: import flask - from werkzeug.contrib.fixers import ProxyFix + from werkzeug.middleware.proxy_fix import ProxyFix _before = flask.Flask.__init__ def _after(*args, **kwargs): _before(*args, **kwargs) - self.wsgi_app = ProxyFix(self.wsgi_app) + self.wsgi_app = ProxyFix(self.wsgi_app, x_proto=1) flask.Flask.__init__ = _after except: pass