Skip to content

Commit a971704

Browse files
authored
Merge pull request #2680 from Kodiologist/misc
Miscellany
2 parents 2e4a80f + e3bdf2a commit a971704

File tree

8 files changed

+79
-98
lines changed

8 files changed

+79
-98
lines changed

LICENSE

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
Copyright 2025 the authors.
1+
Copyright 2026 the authors.
22
Portions of setup.py, copyright 2016 Jason R Coombs <[email protected]>.
33

44
Permission is hereby granted, free of charge, to any person obtaining a

README.md

Lines changed: 0 additions & 35 deletions
This file was deleted.

README.rst

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
Hy
2+
==
3+
4+
.. image:: https://img.shields.io/pypi/v/hy.svg
5+
:target: https://pypi.python.org/pypi/hy
6+
:alt: Version
7+
8+
.. image:: https://raw.github.com/hylang/shyte/18f6925e08684b0e1f52b2cc2c803989cd62cd91/imgs/xkcd.png
9+
:target: https://xkcd.com/224/
10+
:alt: XKCD #224
11+
12+
.. comment
13+
:title: We lost the documentation on quantum mechanics. You'll have to decode the regexes yourself.
14+
15+
Lisp and Python should love each other. Let's make it happen.
16+
17+
Hy is a Lisp dialect that's embedded in Python. Since Hy transforms its Lisp
18+
code into Python abstract syntax tree (AST) objects, you have the whole
19+
beautiful world of Python at your fingertips, in Lisp form.
20+
21+
To install the latest release of Hy, just use the command ``pip3 install
22+
--user hy``. Then you can start an interactive read-eval-print loop (REPL) with
23+
the command ``hy``, or run a Hy program with ``hy myprogram.hy``.
24+
25+
* `The Hy homepage <http://hylang.org>`__
26+
* `Try Hy with a web console <http://hylang.org/try-hy>`__
27+
28+
Project
29+
-------
30+
31+
* Code: https://github.com/hylang/hy
32+
* Documentation: http://hylang.org/hy/doc
33+
* Bug reports: We have no bugs! Your bugs are your own! (https://github.com/hylang/hy/issues)
34+
* License: MIT (Expat)
35+
* Community: Join us on `Github Discussions <https://github.com/hylang/hy/discussions>`__
36+
* `Stack Overflow: The [hy] tag <https://stackoverflow.com/questions/tagged/hy>`__
37+
38+
Hy's current maintainer is `Kodi Arfer <https://github.com/Kodiologist>`__. He takes responsibility for answering user questions, which should primarily be asked on Stack Overflow or GitHub Discussions, but feel free to `poke him <http://arfer.net/elsewhere>`__ if he's missed a question or you've found a serious security issue.
39+
40+
.. image:: https://i.imgur.com/QbPMXTN.png
41+
:alt: Cuddles the Hacker
42+
43+
(fan art from the one and only `doctormo <http://doctormo.deviantart.com/art/Cuddles-the-Hacker-372184766>`__)

hy/compat.py

Lines changed: 0 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -38,29 +38,6 @@ def rewriting_unparse(ast_obj):
3838
ast.unparse = rewriting_unparse
3939

4040

41-
if True:
42-
import pydoc, inspect, re
43-
true_getdoc = pydoc.getdoc
44-
def getdoc(object):
45-
"""A monkey-patched `pydoc.getdoc` that tries to avoid calling
46-
`inspect.getcomments` for an object defined in Hy code, which would try
47-
to parse the Hy as Python. The implementation is based on Python
48-
3.12.3's `getdoc`."""
49-
result = pydoc._getdoc(object)
50-
if not result:
51-
can_get_comments = True
52-
try:
53-
file_path = inspect.getfile(object)
54-
except TypeError:
55-
None
56-
else:
57-
can_get_comments = not file_path.endswith('.hy')
58-
if can_get_comments:
59-
result = inspect.getcomments(object)
60-
return result and re.sub('^ *\n', '', result.rstrip()) or ''
61-
pydoc.getdoc = getdoc
62-
63-
6441
def reu(x):
6542
'(R)eplace an (e)rror (u)nderline. This is only used for testing Hy.'
6643
return x.replace('-', '^') if PY3_13 else x

hy/compiler.py

Lines changed: 2 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -37,22 +37,6 @@
3737
from hy.reader import mangle, HyReader
3838
from hy.scoping import ResolveOuterVars, ScopeGlobal
3939

40-
hy_ast_compile_flags = 0
41-
42-
43-
def ast_compile(a, filename, mode):
44-
"""Compile AST.
45-
46-
Args:
47-
a (ast.AST): instance of `ast.AST`
48-
filename (str): Filename used for run-time error messages
49-
mode (str): `compile` mode parameter
50-
51-
Returns:
52-
types.CodeType: instance of `types.CodeType`
53-
"""
54-
return compile(a, filename, mode, hy_ast_compile_flags)
55-
5640

5741
def calling_module(n=1):
5842
"""Get the module calling, if available.
@@ -766,10 +750,10 @@ def hy_eval(
766750
globals = module.__dict__
767751

768752
# Two-step eval: eval() the body of the exec call
769-
eval(ast_compile(_ast, filename, "exec"), globals, locals)
753+
eval(compile(_ast, filename, "exec"), globals, locals)
770754

771755
# Then eval the expression context and return that
772-
return eval(ast_compile(expr, filename, "eval"), globals, locals)
756+
return eval(compile(expr, filename, "eval"), globals, locals)
773757

774758

775759
def hy_eval_user(model, globals = None, locals = None, module = None, macros = None):

setup.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010

1111
import os
1212

13+
from pathlib import Path
1314
from setuptools import find_packages, setup
1415
from setuptools.command.install import install
1516

@@ -56,7 +57,8 @@ def run(self):
5657
},
5758
author="Paul Tagliamonte",
5859
author_email="[email protected]",
59-
long_description=long_description,
60+
long_description=Path('README.rst').read_text(),
61+
long_description_content_type='text/x-rst',
6062
description="A Lisp dialect embedded in Python",
6163
license="Expat",
6264
url="http://hylang.org/",

tests/native_tests/other.hy

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@
66
importlib
77
pydoc
88
pytest
9-
hy.errors [HyLanguageError HySyntaxError])
9+
hy.errors [HyLanguageError HySyntaxError]
10+
hy.compat [PY3_13])
1011

1112

1213
(defn test-pragma-hy []
@@ -99,14 +100,15 @@
99100
(importlib.invalidate-caches)
100101
(import pydoc-hy)
101102
(assert (= (pydoc.getdoc pydoc-hy.C1) "C1 docstring"))
102-
(assert (= (pydoc.getdoc pydoc-hy.C2) "")))
103-
; `pydoc` shouldn't try to get a comment from Hy code, since it
104-
; doesn't know how to parse Hy.
103+
(assert (= (pydoc.getdoc pydoc-hy.C2) (if PY3_13
104+
; Class location via Hy isn't implemented on earlier Pythons.
105+
"; a comment"
106+
""))))
105107

106108

107109
(defn test-help-class-attr []
108-
"Our tampering with `pydoc` shouldn't cause `help` to raise
109-
`TypeError` on classes with non-method attributes."
110+
"Our tampering with `pydoc` or `inspect` shouldn't cause `help` to
111+
raise `TypeError` on classes with non-method attributes."
110112
(defclass C []
111113
(setv attribute 1))
112114
(help C))

tests/test_bin.py

Lines changed: 22 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
from importlib.util import cache_from_source
1111
from pathlib import Path
1212

13-
from hy.compat import PY3_13
13+
from hy.compat import PY3_10, PY3_13
1414

1515
import pytest
1616

@@ -447,9 +447,10 @@ def test_traceback_shebang(tmp_path):
447447
assert '(/ 1 0)' in error
448448

449449

450-
@pytest.mark.xfail(not PY3_13, reason = 'likely Hy bug in line-number assignment')
450+
@pytest.mark.xfail(not PY3_10, reason = 'not worth debugging, since CPython 3.9 is unmaintained and this is a minor, undocumented feature')
451451
def test_pdb_ll(tmp_path):
452452
# Test the Python debugger's `ll` command.
453+
453454
p = tmp_path / 'ex.hy'
454455
p.write_text(str.strip(dedent('''
455456
(defn f []
@@ -458,20 +459,27 @@ def test_pdb_ll(tmp_path):
458459
(print (.upper "bbb")))
459460
(f)''')))
460461
o, _ = run_cmd(['hy', p], 'll\nquit\n', expect = 1)
462+
461463
assert 'AAA' in o
462464
assert 'BBB' not in o
463-
got = re.sub(r'\s+', ' ', o).strip()
464-
expect = re.sub(r'\s+', ' ', f'''
465-
ex.hy(3)f()
466-
-> (breakpoint)
467-
(Pdb) 1 (defn f []
468-
2 (print (.upper "aaa"))
469-
3 -> (breakpoint)
470-
4 (print (.upper "bbb")))
471-
(Pdb)''').strip()
472-
print('Got: ', repr(got))
473-
print('Expect: ', repr(expect))
474-
assert expect in got
465+
466+
arrow_line = 3 if PY3_13 else 4
467+
# Bizarrely, Python 3.12 and earlier will point the arrow to the
468+
# line after the breakpoint rather than the line with the
469+
# breakpoint, even in pure Python.
470+
def arrow(i):
471+
return '->' if i == arrow_line else ''
472+
def clean(x):
473+
return re.sub(r'\s+', ' ', x).strip()
474+
475+
assert (
476+
clean(f'''
477+
(Pdb) 1 (defn f []
478+
2 (print (.upper "aaa"))
479+
3 {arrow(3)} (breakpoint)
480+
4 {arrow(4)} (print (.upper "bbb")))
481+
(Pdb)''')
482+
in clean(o))
475483

476484

477485
def test_hystartup():

0 commit comments

Comments
 (0)