Skip to content

Commit 706be81

Browse files
authored
Merge pull request #2652 from Kodiologist/py-pi
Support Python 3.14
2 parents de884a5 + ecfd6b3 commit 706be81

File tree

7 files changed

+31
-16
lines changed

7 files changed

+31
-16
lines changed

.github/workflows/tests.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ jobs:
1212
matrix:
1313
name-prefix: ['']
1414
os: [ubuntu-latest]
15-
python: [3.9, '3.10', 3.11, 3.12, 3.13, pypy-3.10]
15+
python: [3.9, '3.10', 3.11, 3.12, 3.13, 3.14-dev, pypy-3.10]
1616
include:
1717
# To keep the overall number of runs low, we test Windows and MacOS
1818
# only on the latest CPython.

NEWS.rst

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
Unreleased
44
======================================================================
55

6-
Supports Python 3.9 – Python 3.x
6+
Supports Python 3.9 – Python 3.14
77

88
New Features
99
------------------------------
@@ -16,6 +16,7 @@ Bug Fixes
1616
`(except [] …)`, which catches all exceptions.
1717
* `(except [e []] …)` is now translated to Python correctly by `hy2py`.
1818
* Fixed a bug where logical ops starting with a `(setv …)` expression failed to compile.
19+
* A complex `imag` argument to `hy.models.Complex` is no longer allowed.
1920

2021
1.0.0 ("Afternoon Review", released 2024-09-22)
2122
======================================================================

docs/api.rst

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1137,7 +1137,7 @@ Modules
11371137

11381138
;; Import several names from a single module.
11391139
;; Python: from os.path import exists, isdir as is_dir, isfile
1140-
(import os.path [exists isdir :as dir? isfile])
1140+
(import os.path [exists isdir :as is-dir isfile])
11411141

11421142
;; Import a module with an alias for the whole module.
11431143
;; Python: import sys as systest
@@ -1155,8 +1155,8 @@ Modules
11551155
;; from math import *
11561156
(import tests.resources [kwtest function-with-a-dash]
11571157
os.path [exists
1158-
isdir :as dir?
1159-
isfile :as file?]
1158+
isdir :as is-dir
1159+
isfile :as is-file]
11601160
sys :as systest
11611161
math *)
11621162

docs/macros.rst

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ You don't need to always return a model because the compiler calls :hy:func:`hy.
7070
Arguments are always passed in as models. You can use quasiquotation (see :hy:func:`quasiquote`) to concisely define a model with partly literal and partly evaluated components::
7171

7272
(defmacro set-to-2 [variable]
73-
`(setv ~variable 2))
73+
`(setv ~variable 2))
7474
(set-to-2 foobar)
7575
(print foobar)
7676

@@ -160,19 +160,26 @@ By the way, despite the need for ``eval-and-compile``, extracting a lot of compl
160160
The important take-home big fat WARNING
161161
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
162162

163-
A typical macro should use only four kinds of names in its expansion: gensyms, core macros, objects that Python puts in scope by default (like its built-in functions), and ``hy`` and its attributes. It's possible to rebind nearly all these names, so surprise shadowing is still theoretically possible. Unfortunately, the only way to prevent these pathological rebindings from coming about is… don't do that. Don't make a new macro named ``setv`` or name a function argument ``type`` unless you're ready for every macro you call to break, the same way you wouldn't monkey-patch a built-in Python module without thinking carefully. This kind of thing is the responsibility of the macro caller; the macro writer can't do much to defend against it. There is at least a pragma :ref:`warn-on-core-shadow <warn-on-core-shadow>`, enabled by default, that causes ``defmacro`` and ``require`` to warn you if you give your new macro the same name as a core macro.
163+
A typical macro should use only names of these four kinds in its expansion:
164+
165+
- gensyms
166+
- core macros
167+
- objects that Python puts in scope by default (like its built-in functions)
168+
- ``hy`` and its attributes
169+
170+
It's possible to rebind nearly all these names, so surprise shadowing is still theoretically possible. Unfortunately, the only way to prevent these pathological rebindings from coming about is… don't do that. Don't make a new macro named ``setv`` or name a function parameter ``type`` unless you're ready for every macro you call to break, the same way you wouldn't monkey-patch a built-in Python module without thinking carefully. This kind of thing is the responsibility of the macro caller; the macro writer can't do much to defend against it. There is at least a pragma :ref:`warn-on-core-shadow <warn-on-core-shadow>`, enabled by default, that causes ``defmacro`` and ``require`` to warn you if you give your new macro the same name as a core macro.
164171

165172
.. _reader-macros:
166173

167174
Reader macros
168175
-------------
169176

170-
Reader macros allow you to hook directly into Hy's parser to customize how text is parsed into models. They're defined with :hy:func:`defreader <hy.core.macros.defreader>`, or, like regular macros, brought in from other modules with :hy:func:`require`. Rather than receiving function arguments, a reader macro has access to a :py:class:`hy.HyReader` object named ``&reader``, which provides all the text-parsing logic that Hy uses to parse itself (see :py:class:`hy.HyReader` and its base class :py:class:`hy.Reader` for the available methods). A reader macro is called with the hash sign ``#``, and like a regular macro, it should return a model or something convertible to a model.
177+
Reader macros allow you to hook into Hy's parser to customize how text is parsed into models. They're defined with :hy:func:`defreader <hy.core.macros.defreader>`, or, like regular macros, brought in from other modules with :hy:func:`require`. Rather than receiving function arguments, a reader macro has access to a :py:class:`hy.HyReader` object named ``&reader``, which provides all the text-parsing logic that Hy uses to parse itself (see :py:class:`hy.HyReader` and its base class :py:class:`hy.Reader` for the available methods). A reader macro is called with the hash sign ``#``, and like a regular macro, it should return a model or something convertible to a model.
171178

172179
The simplest kind of reader macro doesn't read anything::
173180

174181
(defreader hi
175-
`(print "Hello."))
182+
'(print "Hello."))
176183

177184
#hi #hi #hi
178185

@@ -233,7 +240,7 @@ There are three scoped varieties of regular macro. First are **core macros**, wh
233240

234241
(defmacro m []
235242
"This is a docstring."
236-
`(print "Hello, world."))
243+
'(print "Hello, world."))
237244
(print (in "m" _hy_macros)) ; => True
238245
(help (get-macro m))
239246
(m) ; => "Hello, world."

hy/core/macros.hy

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
1-
;;; Hy core macros
1+
"This file has the few core macros that are implemented in Hy instead of Python."
22

3-
;;; These macros form the hy language
4-
;;; They are automatically required in every module, except inside hy.core
53

64
(defmacro cond [#* args]
75
"Shorthand for a nested sequence of :hy:func:`if` forms, like an
@@ -121,7 +119,7 @@
121119
(help (get (local-macros) "m")))
122120
(f)
123121
124-
The equivalency is rough in the sense that ``local-macros`` returns a literal dictionary, not a preexisting object that Hy uses for resolving macro names. So, modifying the dictionary will have no effect.
122+
The equivalency is rough in the sense that ``local-macros`` expands to a literal dictionary, not a preexisting object that Hy uses for resolving macro names. So, modifying the dictionary will have no effect.
125123
126124
See also :hy:func:`get-macro <hy.core.macros.get-macro>`.]]
127125
(_local-macros _hy_compiler))

hy/models.py

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -343,7 +343,10 @@ def __new__(cls, num, *args, **kwargs):
343343

344344
class Complex(Object, complex):
345345
"""
346-
Represents a literal floating-point complex number (:class:`complex`).
346+
Represents a literal floating-point complex number (:class:`complex`). If
347+
``real`` is itself a :class:`complex` object, its imaginary part is extracted and
348+
added to the imaginary part of the new model, but ``imag``, if provided, must be
349+
real.
347350
"""
348351

349352
def __new__(cls, real, imag=0, *args, **kwargs):
@@ -354,6 +357,12 @@ def __new__(cls, real, imag=0, *args, **kwargs):
354357
if p2:
355358
check_inf_nan_cap(p2, value.imag)
356359
return value
360+
if isinstance(imag, complex):
361+
raise TypeError("`imag` must be real")
362+
if isinstance(real, complex):
363+
# This is deprecated by Python 3.14's `complex`, so
364+
# extract the imaginary part before passing through.
365+
real, imag = real.real, imag + real.imag
357366
return super().__new__(cls, real, imag)
358367

359368

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ def run(self):
4343
version='0.0.0',
4444
setup_requires=["wheel"] + requires,
4545
install_requires=requires,
46-
python_requires=">= 3.9, < 3.14",
46+
python_requires=">= 3.9, < 3.15",
4747
entry_points={
4848
"console_scripts": [
4949
"hy = hy.cmdline:hy_main",

0 commit comments

Comments
 (0)