Repository: hylang/hy

Issue:
One-character REPL input provokes a continuation line
```
Hy 0.26.0+28.g0e3409ab using CPython(main) 3.10.7 on Linux
=>  1
1
=> 1
... 
1
```

I haven't yet bisected this, but I suspect it's a regression I introduced in #2399 or one of my recent reader changes.


Discussion:

Resolving patch:
diff --git a/hy/cmdline.py b/hy/cmdline.py
--- a/hy/cmdline.py
+++ b/hy/cmdline.py
@@ -35,7 +35,7 @@ def run_command(source, filename=None):
     with filtered_hy_exceptions():
         try:
             hy_eval(
-                read_many(source, filename=filename, skip_shebang=True),
+                read_many(source, filename=filename),
                 __main__.__dict__,
                 __main__,
                 filename=filename,
diff --git a/hy/reader/hy_reader.py b/hy/reader/hy_reader.py
--- a/hy/reader/hy_reader.py
+++ b/hy/reader/hy_reader.py
@@ -160,7 +160,8 @@ def parse(self, stream, filename=None, skip_shebang=False):
         """
         self._set_source(stream, filename)
 
-        if skip_shebang and "".join(islice(self.peeking(), len("#!"))) == "#!":
+        if skip_shebang and "".join(
+                islice(self.peeking(eof_ok = True), len("#!"))) == "#!":
             for c in self.chars():
                 if c == "\n":
                     break
diff --git a/hy/repl.py b/hy/repl.py
--- a/hy/repl.py
+++ b/hy/repl.py
@@ -167,7 +167,7 @@ def __call__(self, source, filename="<input>", symbol="single"):
             self.hy_compiler.filename = name
             self.hy_compiler.source = source
             hy_ast = read_many(
-                source, filename=name, reader=self.reader, skip_shebang=True
+                source, filename=name, reader=self.reader
             )
             exec_ast, eval_ast = hy_compile(
                 hy_ast,


Test patch:
diff --git a/tests/native_tests/repl.hy b/tests/native_tests/repl.hy
--- a/tests/native_tests/repl.hy
+++ b/tests/native_tests/repl.hy
@@ -2,7 +2,8 @@
 
 (import
   io
-  sys)
+  sys
+  pytest)
 
 (defn test-preserve-ps1 [monkeypatch]
   ; https://github.com/hylang/hy/issues/1323#issuecomment-1310837340
@@ -11,3 +12,16 @@
   (assert (= sys.ps1 "chippy"))
   (.run (hy.REPL))
   (assert (= sys.ps1 "chippy")))
+
+(defn test-repl-input-1char [monkeypatch capsys]
+  ; https://github.com/hylang/hy/issues/2430
+  (monkeypatch.setattr "sys.stdin" (io.StringIO "1\n"))
+  (.run (hy.REPL))
+  (assert (= (. capsys (readouterr) out) "=> 1\n=> " )))
+
+(defn test-repl-no-shebangs [monkeypatch capsys]
+  (monkeypatch.setattr "sys.stdin" (io.StringIO "#!/usr/bin/env hy\n"))
+  (.run (hy.REPL))
+  (assert (in
+    "hy.reader.exceptions.LexException"
+    (. capsys (readouterr) err))))
diff --git a/tests/test_bin.py b/tests/test_bin.py
--- a/tests/test_bin.py
+++ b/tests/test_bin.py
@@ -303,6 +303,10 @@ def test_cmd():
     _, err = run_cmd("""hy -c '(print (.upper "hello")'""", expect=1)
     assert "Premature end of input" in err
 
+    # No shebang is allowed.
+    _, err = run_cmd("""hy -c '#!/usr/bin/env hy'""", expect = 1)
+    assert "LexException" in err
+
     # https://github.com/hylang/hy/issues/1879
     output, _ = run_cmd(
         """hy -c '(setv x "bing") (defn f [] (+ "fiz" x)) (print (f))'"""
@@ -332,6 +336,13 @@ def test_icmd_and_spy():
     assert "[] + []" in output
 
 
+def test_empty_file(tmp_path):
+    # https://github.com/hylang/hy/issues/2427
+    (tmp_path / 'foo.hy').write_text('')
+    run_cmd(['hy', (tmp_path / 'foo.hy')])
+      # This asserts that the return code is 0.
+
+
 def test_missing_file():
     _, err = run_cmd("hy foobarbaz", expect=2)
     assert "No such file" in err