Skip to content

Commit

Permalink
Merge branch 'master' into nogil-unsafe-borrowed-references
Browse files Browse the repository at this point in the history
  • Loading branch information
da-woods authored Jul 3, 2024
2 parents c86305b + 0b05b91 commit b4badde
Show file tree
Hide file tree
Showing 105 changed files with 2,628 additions and 1,036 deletions.
2 changes: 1 addition & 1 deletion .codespellrc
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,4 @@ ignore-regex= Tripple|/Fo|ist das|TOi|respect to the includee
# forin - ? tag used in 3 files. may be could be renamed?
# delimeters - typo, but used in API so kept as is
# implementor,implementors - was decided that both forms are ok
ignore-words-list = asend,forin,nd,mis,te,nin,ue,ccompiler,ket,defin,delimeters,filetests,crasher,implementor,implementors
ignore-words-list = asend,forin,nd,mis,te,nin,ue,ccompiler,ket,defin,delimeters,filetests,crasher,implementor,implementors,assertIn
18 changes: 16 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -106,12 +106,12 @@ jobs:
- os: ubuntu-20.04
python-version: "3.7"
backend: "c,cpp"
env: { LIMITED_API: "--limited-api", EXCLUDE: "--no-file" }
env: { LIMITED_API: "--limited-api", NO_LIMITED_COMPILE: 1, EXCLUDE: "--no-file" }
extra_hash: "-limited_api"
- os: ubuntu-20.04
python-version: "3.8"
backend: "c,cpp"
env: { LIMITED_API: "--limited-api", EXCLUDE: "--no-file" }
env: { LIMITED_API: "--limited-api", NO_LIMITED_COMPILE: 1, EXCLUDE: "--no-file" }
extra_hash: "-limited_api"
- os: ubuntu-20.04
python-version: "3.11"
Expand Down Expand Up @@ -161,6 +161,12 @@ jobs:
python-version: pypy-3.10
backend: c
env: { NO_CYTHON_COMPILE: 1 }
# Free-threading
- os: ubuntu-20.04
python-version: 3.13-freethreading-dev
backend: "c,cpp"
env: {}
allowed_failure: true

# This defaults to 360 minutes (6h) which is way too long and if a test gets stuck, it can block other pipelines.
# From testing, the runs tend to take ~20 minutes for ubuntu / macos and ~40 for windows,
Expand All @@ -186,9 +192,17 @@ jobs:

- name: Setup python
uses: actions/[email protected]
if: "!endsWith(matrix.python-version, '-freethreading-dev')"
with:
python-version: ${{ matrix.python-version }}

- name: Setup python from deadsnakes
uses: deadsnakes/[email protected]
if: "endsWith(matrix.python-version, '-freethreading-dev')"
with:
python-version: 3.13-dev
nogil: true

- name: Compilation Cache
uses: hendrikmuhs/[email protected]
with:
Expand Down
63 changes: 63 additions & 0 deletions .github/workflows/nightly-wheels.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
# Workflow to build non-compiled nightly wheel.

name: Nightly wheels
on:
schedule:
# ┌───────────── minute (0 - 59)
# │ ┌───────────── hour (0 - 23)
# │ │ ┌───────────── day of the month (1 - 31)
# │ │ │ ┌───────────── month (1 - 12 or JAN-DEC)
# │ │ │ │ ┌───────────── day of the week (0 - 6 or SUN-SAT)
# │ │ │ │ │
- cron: "42 1 * * 0,3"
pull_request:
types: [labeled, opened, synchronize, reopened]
paths:
#- Cython/Build/**
- .github/workflows/nightly-wheels.yml
- pyproject.toml
- MANIFEST.in
- setup.*
workflow_dispatch:

concurrency:
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
cancel-in-progress: true

permissions:
contents: read # to fetch code (actions/checkout)

jobs:
build_pure_wheel:
name: Build pure wheel and upload to Anaconda's PyPI
if: >-
github.event_name == 'schedule' ||
github.event_name == 'workflow_dispatch' ||
(github.event_name == 'pull_request' &&
contains(github.event.pull_request.labels.*.name, 'Build System'))
runs-on: ubuntu-latest
steps:
- name: Checkout Cython
uses: actions/[email protected]

- uses: deadsnakes/[email protected]
with:
python-version: 3.13-dev
nogil: true

- name: Build pure wheel
run: |
pip install --upgrade wheel setuptools
python setup.py bdist_wheel --no-cython-compile
- uses: actions/[email protected]
with:
name: pure-wheel
path: ./dist/*.whl

- name: Upload wheels to scientific-python-nightly-wheels
if: github.event_name == 'schedule' || github.event_name == 'workflow_dispatch'
uses: scientific-python/upload-nightly-action@b67d7fcc0396e1128a474d1ab2b48aa94680f9fc # 0.5.0
with:
artifacts_path: dist
anaconda_nightly_upload_token: ${{ secrets.CYTHON_NIGHTLY_UPLOAD_TOKEN }}
25 changes: 25 additions & 0 deletions CHANGES.rst
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,31 @@ Other changes
* Includes all fixes as of Cython 3.0.10 (but generates C99 code in some places).


3.0.11 (2024-??-??)
===================

Bugs fixed
----------

* The exception check value of functions declared in pxd files was not always applied in 3.0.10.
(Github issue :issue:`6122`)

* A crash on exception deallocations was fixed.
(Github issue :issue:`6022`)

* ``bytes.startswith/endswith()`` failed for non-bytes substrings (e.g. ``bytearray``).
(Github issue :issue:`6168`)

* A compiler crash was fixed when using extension types in fused types.
(Github issue :issue:`6204`)

* The module cleanup code was incorrect for globally defined memory view slices.
(Github issue :issue:`6276`)

* Some adaptations were made to enable compilation in Python 3.13.
(Github issues :issue:`5997`, :issue:`6182`, :issue:`6251`)


3.0.10 (2024-03-30)
===================

Expand Down
2 changes: 2 additions & 0 deletions Cython/Build/Dependencies.py
Original file line number Diff line number Diff line change
Expand Up @@ -705,6 +705,8 @@ def default_create_extension(template, kwds):

t = template.__class__
ext = t(**kwds)
if hasattr(template, "py_limited_api"):
ext.py_limited_api = template.py_limited_api
metadata = dict(distutils=kwds, module_name=kwds['name'])
return (ext, metadata)

Expand Down
5 changes: 5 additions & 0 deletions Cython/Build/Inline.py
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,11 @@ def _populate_unbound(kwds, unbound_symbols, locals=None, globals=None):
locals = calling_frame.f_locals
if globals is None:
globals = calling_frame.f_globals
if not isinstance(locals, dict):
# FrameLocalsProxy is stricter than dict on how it looks up keys
# and this means our "EncodedStrings" don't match the keys in locals.
# Therefore copy to a dict.
locals = dict(locals)
if symbol in locals:
kwds[symbol] = locals[symbol]
elif symbol in globals:
Expand Down
17 changes: 1 addition & 16 deletions Cython/Build/IpythonMagic.py
Original file line number Diff line number Diff line change
Expand Up @@ -379,26 +379,11 @@ def _profile_pgo_wrapper(self, extension, lib_dir):
with open(pgo_wrapper_c_file, 'w', encoding='utf-8') as f:
f.write(textwrap.dedent("""
#include "Python.h"
#if PY_MAJOR_VERSION < 3
extern PyMODINIT_FUNC init%(module_name)s(void);
PyMODINIT_FUNC init%(pgo_module_name)s(void); /*proto*/
PyMODINIT_FUNC init%(pgo_module_name)s(void) {
PyObject *sys_modules;
init%(module_name)s(); if (PyErr_Occurred()) return;
sys_modules = PyImport_GetModuleDict(); /* borrowed, no exception, "never" fails */
if (sys_modules) {
PyObject *module = PyDict_GetItemString(sys_modules, "%(module_name)s"); if (!module) return;
PyDict_SetItemString(sys_modules, "%(pgo_module_name)s", module);
Py_DECREF(module);
}
}
#else
extern PyMODINIT_FUNC PyInit_%(module_name)s(void);
PyMODINIT_FUNC PyInit_%(pgo_module_name)s(void); /*proto*/
PyMODINIT_FUNC PyInit_%(pgo_module_name)s(void) {
return PyInit_%(module_name)s();
}
#endif
""" % {'module_name': module_name, 'pgo_module_name': pgo_module_name}))

extension.sources = extension.sources + [pgo_wrapper_c_file] # do not modify in place!
Expand Down Expand Up @@ -568,7 +553,7 @@ def clean_annotated_html(html, include_style=True):
__doc__ = __doc__.format(
# rST doesn't see the -+ flag as part of an option list, so we
# hide it from the module-level docstring.
CYTHON_DOC=dedent(CythonMagics.cython.__doc__\
CYTHON_DOC=dedent(CythonMagics.cython.__doc__
.replace('-+, --cplus', '--cplus ')),
CYTHON_INLINE_DOC=dedent(CythonMagics.cython_inline.__doc__),
CYTHON_PYXIMPORT_DOC=dedent(CythonMagics.cython_pyximport.__doc__),
Expand Down
2 changes: 2 additions & 0 deletions Cython/Build/Tests/TestCythonizeArgsParser.py
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,8 @@ def test_directives_types(self):
options, args = self.parse_args(['-X', cmd])
self.assertFalse(args)
self.assertTrue(self.are_default(options, ['directives']), msg = "Error for option: "+cmd)
if value == 'str':
value = 'unicode'
self.assertEqual(options.directives[key], value, msg = "Error for option: "+cmd)

def test_directives_wrong(self):
Expand Down
37 changes: 13 additions & 24 deletions Cython/Compiler/Annotate.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,8 +69,8 @@ def _css(self):
"""css template will later allow to choose a colormap"""
css = [self._css_template]
for i in range(255):
color = "FFFF%02x" % int(255.0 // (1.0 + i/10.0))
css.append('.cython.score-%d {background-color: #%s;}' % (i, color))
color_shade = int(255.0 // (1.0 + i/10.0))
css.append(f'.cython.score-{i:d} {{background-color: #FFFF{color_shade:02x};}}')
try:
from pygments.formatters import HtmlFormatter
except ImportError:
Expand Down Expand Up @@ -232,8 +232,7 @@ def _save_annotation_body(self, cython_code, generated_code, annotation_items, s
def annotate(match):
group_name = match.lastgroup
calls[group_name] += 1
return "<span class='%s'>%s</span>" % (
group_name, match.group(group_name))
return f"<span class='{group_name}'>{match.group(group_name)}</span>"

lines = self._htmlify_code(cython_code, "cython").splitlines()
lineno_width = len(str(len(lines)))
Expand Down Expand Up @@ -270,34 +269,24 @@ def annotate(match):
covered = 'run' if hits else 'mis'

outlist.append(
'<pre class="cython line score-{score}"{onclick}>'
f'<pre class="cython line score-{score}"{onclick}>'
# generate line number with expand symbol in front,
# and the right number of digit
'{expandsymbol}<span class="{covered}">{line:0{lineno_width}d}</span>: {code}</pre>\n'.format(
score=score,
expandsymbol=expandsymbol,
covered=covered,
lineno_width=lineno_width,
line=k,
code=line.rstrip(),
onclick=onclick,
))
f'{expandsymbol}<span class="{covered}">{k:0{lineno_width}d}</span>: {line.rstrip()}</pre>\n'
)
if c_code:
outlist.append("<pre class='cython code score-{score} {covered}'>{code}</pre>".format(
score=score, covered=covered, code=c_code))
outlist.append(f"<pre class='cython code score-{score} {covered}'>{c_code}</pre>")
outlist.append("</div>")

# now the whole c-code if needed:
if self.show_entire_c_code:
outlist.append('<p><div class="cython">')
onclick_title = "<pre class='cython line'{onclick}>+ {title}</pre>\n"
outlist.append(onclick_title.format(
onclick=self._onclick_attr,
title=AnnotationCCodeWriter.COMPLETE_CODE_TITLE,
))
complete_code_as_html = self._htmlify_code(self.buffer.getvalue(), "c/cpp")
outlist.append("<pre class='cython code'>{code}</pre>".format(code=complete_code_as_html))
outlist.append("</div></p>")
outlist.append(
'<p><div class="cython">'
f"<pre class='cython line'{self._onclick_attr}>+ {AnnotationCCodeWriter.COMPLETE_CODE_TITLE}</pre>\n"
f"<pre class='cython code'>{complete_code_as_html}</pre>"
"</div></p>"
)

return outlist

Expand Down
3 changes: 3 additions & 0 deletions Cython/Compiler/AutoDocTransforms.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import inspect

from .Visitor import CythonTransform
from .StringEncoding import EncodedString
from . import Options
Expand Down Expand Up @@ -177,6 +179,7 @@ def _embed_signature(self, signature, node_doc):
docfmt = "%s\n--\n\n%s"
else:
docfmt = "%s\n%s"
node_doc = inspect.cleandoc(node_doc)
return docfmt % (signature, node_doc)
else:
if self.is_format_clinic:
Expand Down
3 changes: 3 additions & 0 deletions Cython/Compiler/Builtin.py
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,9 @@ def declare_in_type(self, self_type):
#('compile', "", "", ""), # PyObject* Py_CompileString( char *str, char *filename, int start)
BuiltinFunction('delattr', "OO", "r", "PyObject_DelAttr"),
BuiltinFunction('dir', "O", "O", "PyObject_Dir"),
BuiltinFunction('divmod', "ii", "O", "__Pyx_divmod_int",
utility_code=UtilityCode.load("divmod_int", "Builtins.c"),
is_strict_signature = True),
BuiltinFunction('divmod', "OO", "O", "PyNumber_Divmod"),
BuiltinFunction('exec', "O", "O", "__Pyx_PyExecGlobals",
utility_code = pyexec_globals_utility_code),
Expand Down
Loading

0 comments on commit b4badde

Please sign in to comment.