From 78ad44bbb6703dedee2f31c34eb863b9fe870d53 Mon Sep 17 00:00:00 2001
From: "David J. Malan" <malan@harvard.edu>
Date: Sun, 9 Apr 2017 17:42:00 -0400
Subject: [PATCH 1/2] added support for optional args for parity with newest C
 library

---
 cs50/cs50.py    | 40 +++++++++++++++++++++++++++-------------
 setup.py        |  2 +-
 test/python2.py |  2 --
 test/python3.py |  2 --
 4 files changed, 28 insertions(+), 18 deletions(-)

diff --git a/cs50/cs50.py b/cs50/cs50.py
index 657f405..d9c2923 100644
--- a/cs50/cs50.py
+++ b/cs50/cs50.py
@@ -20,20 +20,23 @@ def write(self, x):
 sys.stderr = flushfile(sys.stderr)
 sys.stdout = flushfile(sys.stdout)
 
-def get_char():
+def get_char(prompt=None):
     """Read a line of text from standard input and return the equivalent char."""
     while True:
-        s = get_string()
+        s = get_string(prompt)
         if s is None:
             return None
         if len(s) == 1:
             return s[0]
-        print("Retry: ", end="")
 
-def get_float():
+        # temporarily here for backwards compatibility
+        if prompt is None:
+            print("Retry: ", end="")
+
+def get_float(prompt=None):
     """Read a line of text from standard input and return the equivalent float."""
     while True:
-        s = get_string()
+        s = get_string(prompt)
         if s is None:
             return None
         if len(s) > 0 and re.search(r"^[+-]?\d*(?:\.\d*)?$", s):
@@ -41,12 +44,15 @@ def get_float():
                 return float(s)
             except ValueError:
                 pass
-        print("Retry: ", end="")
 
-def get_int():
+        # temporarily here for backwards compatibility
+        if prompt is None:
+            print("Retry: ", end="")
+
+def get_int(prompt=None):
     """Read a line of text from standard input and return the equivalent int."""
     while True:
-        s = get_string();
+        s = get_string(prompt);
         if s is None:
             return None
         if re.search(r"^[+-]?\d+$", s):
@@ -56,13 +62,16 @@ def get_int():
                     return i
             except ValueError:
                 pass
-        print("Retry: ", end="")
+
+        # temporarily here for backwards compatibility
+        if prompt is None:
+            print("Retry: ", end="")
 
 if sys.version_info.major != 3:
-    def get_long():
+    def get_long(prompt=None):
         """Read a line of text from standard input and return the equivalent long."""
         while True:
-            s = get_string();
+            s = get_string(prompt)
             if s is None:
                 return None
             if re.search(r"^[+-]?\d+$", s):
@@ -70,11 +79,16 @@ def get_long():
                     return long(s, 10)
                 except ValueError:
                     pass
-            print("Retry: ", end="")
 
-def get_string():
+            # temporarily here for backwards compatibility
+            if prompt is None:
+                print("Retry: ", end="")
+
+def get_string(prompt=None):
     """Read a line of text from standard input and return it as a string."""
     try:
+        if prompt is not None:
+            print(prompt, end="")
         s = sys.stdin.readline()
         return re.sub(r"(?:\r|\r\n|\n)$", "", s)
     except ValueError:
diff --git a/setup.py b/setup.py
index cee2266..09c4c5e 100644
--- a/setup.py
+++ b/setup.py
@@ -15,5 +15,5 @@
     name="cs50",
     packages=["cs50"],
     url="https://github.com/cs50/python-cs50",
-    version="1.3.0"
+    version="2.0.0"
 )
diff --git a/test/python2.py b/test/python2.py
index 10f19e4..69de822 100644
--- a/test/python2.py
+++ b/test/python2.py
@@ -1,6 +1,4 @@
 import cs50
 
-from cs50 import SQL
-
 l = cs50.get_long()
 print(l)
diff --git a/test/python3.py b/test/python3.py
index efef779..b545b98 100644
--- a/test/python3.py
+++ b/test/python3.py
@@ -1,6 +1,4 @@
 import cs50
-from cs50 import SQL
 
 i = cs50.get_int()
 print(i)
-

From d8a74a34fd5ce16c23b8a13b0dbbbc96d530bb19 Mon Sep 17 00:00:00 2001
From: "David J. Malan" <malan@harvard.edu>
Date: Sat, 29 Apr 2017 11:47:52 -0400
Subject: [PATCH 2/2] returning None for EOF, updated comments

---
 cs50/cs50.py | 33 ++++++++++++++++++++++++++++-----
 1 file changed, 28 insertions(+), 5 deletions(-)

diff --git a/cs50/cs50.py b/cs50/cs50.py
index d9c2923..edcb52d 100644
--- a/cs50/cs50.py
+++ b/cs50/cs50.py
@@ -21,7 +21,11 @@ def write(self, x):
 sys.stdout = flushfile(sys.stdout)
 
 def get_char(prompt=None):
-    """Read a line of text from standard input and return the equivalent char."""
+    """
+    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:
@@ -34,7 +38,11 @@ def get_char(prompt=None):
             print("Retry: ", end="")
 
 def get_float(prompt=None):
-    """Read a line of text from standard input and return the equivalent float."""
+    """
+    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
+    prompted to retry. If line can't be read, return None.
+    """
     while True:
         s = get_string(prompt)
         if s is None:
@@ -50,7 +58,11 @@ def get_float(prompt=None):
             print("Retry: ", end="")
 
 def get_int(prompt=None):
-    """Read a line of text from standard input and return the equivalent int."""
+    """
+    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
+    can't be read, return None.
+    """
     while True:
         s = get_string(prompt);
         if s is None:
@@ -69,7 +81,11 @@ def get_int(prompt=None):
 
 if sys.version_info.major != 3:
     def get_long(prompt=None):
-        """Read a line of text from standard input and return the equivalent long."""
+        """
+        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:
@@ -85,11 +101,18 @@ def get_long(prompt=None):
                 print("Retry: ", end="")
 
 def get_string(prompt=None):
-    """Read a line of text from standard input and return it as a string."""
+    """
+    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)
+    as line endings. If user inputs only a line ending, returns "", not None.
+    Returns None upon error or no input whatsoever (i.e., just EOF).
+    """
     try:
         if prompt is not None:
             print(prompt, end="")
         s = sys.stdin.readline()
+        if not s:
+            return None
         return re.sub(r"(?:\r|\r\n|\n)$", "", s)
     except ValueError:
         return None