Skip to content

Commit

Permalink
Merge pull request #427 from hpyproject/fa/prepare_0.9
Browse files Browse the repository at this point in the history
Prepare next release (version 0.9.0).
  • Loading branch information
fangerer authored May 2, 2023
2 parents b804cb2 + 25b4742 commit 885add8
Show file tree
Hide file tree
Showing 8 changed files with 286 additions and 37 deletions.
127 changes: 93 additions & 34 deletions .github/workflows/release-pypi.yml
Original file line number Diff line number Diff line change
@@ -1,20 +1,36 @@
---
name: Release to PyPI
name: Publish to PyPI

# manually trigger this workflow
on:
release:
types: [created]

workflow_dispatch:
inputs:
tag:
description: 'The Git tag to create or test a release for. Official releases should always be made from an existing tag.'
required: true
type: string
official:
description: 'If true, publish to official PyPI and create GitHub release. Otherwise publish only to test PyPI.'
default: false
type: boolean

jobs:
build_sdist:
name: Build source package
runs-on: 'ubuntu-latest'
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
with:
ref: ${{ inputs.tag }}

- name: Set up Python
uses: actions/setup-python@v4
with:
# HPy requires at least Python 3.8; we mostly work with >=3.10
python-version: '>=3.10'

- name: Install/Upgrade Python dependencies
run: python -m pip install --upgrade pip wheel
run: python -m pip install --upgrade pip wheel 'setuptools>=60.2'

- name: Build and install Python source package
run: |
Expand All @@ -23,12 +39,14 @@ jobs:
- name: Run tests
run: |
pip install pytest pytest-xdist
make
pip install pytest pytest-xdist filelock
pytest -n auto test/
- uses: actions/upload-artifact@v2
- uses: actions/upload-artifact@v3
with:
path: dist/*.tar.gz
retention-days: 5


build_bdist:
Expand All @@ -37,46 +55,87 @@ jobs:
strategy:
matrix:
# Windows tests fail when built as a binary wheel for some reason
os: [ubuntu-latest, macos-latest] # windows-latest
# 'macos-12' doesn't pass the tests
os: [ubuntu-latest, macos-11] # windows-latest

steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
with:
ref: ${{ inputs.tag }}

# setup Python for cibuildwheel
- name: Set up Python
uses: actions/setup-python@v2
uses: actions/setup-python@v4
with:
python-version: '3.x'

# for other architectures, see: https://cibuildwheel.readthedocs.io/en/stable/faq/#emulation
- name: Build wheels for CPython
uses: pypa/cibuildwheel@v2.1.1
uses: pypa/cibuildwheel@v2.12.3
env:
CIBW_BUILD: 'cp*' # no PyPI builds
CIBW_SKIP: 'cp310-*' # 3.10 builds are broken
CIBW_ARCHS: 'auto64' # only 64-bit
CIBW_TEST_REQUIRES: pytest pytest-xdist
CIBW_TEST_COMMAND: pytest -n auto {project}/test/

- uses: actions/upload-artifact@v2
# cibuildwheel automatically reads 'python_requires' from 'setup.py'
CIBW_BUILD: 'cp*' # no PyPy builds
CIBW_ARCHS_LINUX: "x86_64" # only Intel 64-bit
CIBW_ARCHS_MACOS: "x86_64" # only Intel 64-bit
CIBW_TEST_REQUIRES: pytest pytest-xdist filelock setuptools>=60.2
# only copy test dir to current working dir
CIBW_TEST_COMMAND: cp -R {project}/test ./ && pytest --basetemp=.tmpdir --ignore=test/hpy_devel -n auto ./test/

- uses: actions/upload-artifact@v3
with:
path: ./wheelhouse/*.whl

retention-days: 5

upload_pypi:
name: Publish packages to PyPI
# only publish packages once everything is successful
needs: [build_bdist, build_sdist]
name: Publish packages to (Test) PyPI
needs: [build_sdist, build_bdist]
runs-on: ubuntu-latest
# don't do this action on forks by default
if: github.event_name == 'push' && github.repository == 'hpyproject/hpy'
steps:
- uses: actions/download-artifact@v3
with:
name: artifact
path: dist

- name: Upload to Test PyPI
uses: pypa/gh-action-pypi-publish@v1.8.5
if: ${{ !inputs.official }}
with:
verbose: true
user: __token__
password: ${{ secrets.TEST_PYPI_API_TOKEN }}
repository-url: https://test.pypi.org/legacy/

- name: Upload to PyPI
uses: pypa/gh-action-pypi-publish@v1.8.5
if: ${{ inputs.official }}
with:
verbose: true
user: __token__
password: ${{ secrets.PYPI_API_TOKEN }}

create_gh_release:
needs: [upload_pypi]
runs-on: ubuntu-latest
# don't do this action on forks by default
if: github.event_name == 'push' && github.repository == 'hpyproject/hpy'
steps:
- uses: actions/download-artifact@v2
with:
name: artifact
path: dist

- uses: pypa/gh-action-pypi-publish@v1.4.2
with:
user: __token__
password: ${{ secrets.pypi_api_token }}
# uncomment the following to upload to test.pypi.org
# repository_url: https://test.pypi.org/legacy/
- uses: actions/download-artifact@v3
with:
name: artifact
path: dist

- name: Checkout
uses: actions/checkout@v3
with:
ref: ${{ inputs.tag }}

- name: Release
uses: softprops/action-gh-release@v1
with:
files: dist/*
# consider tags in form '*.*.*rc*' to indicate a pre-release
prerelease: ${{ contains(github.ref, 'rc') }}
draft: ${{ !inputs.official }}
tag_name: ${{ inputs.tag }}
5 changes: 5 additions & 0 deletions docs/api-reference/hpy-dict.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
HPy Dict
========

.. autocmodule:: autogen/public_api.h
:members: HPyDict_Check, HPyDict_New, HPyDict_Keys, HPyDict_Copy
1 change: 1 addition & 0 deletions docs/api-reference/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ between the modes.
hpy-call
hpy-field
hpy-global
hpy-dict
hpy-gil
hpy-err
builder
Expand Down
153 changes: 153 additions & 0 deletions docs/changelog.rst
Original file line number Diff line number Diff line change
@@ -1,6 +1,159 @@
Changelog
=========

Version 0.9 (April 25th, 2023)
------------------------------

This release adds numerous major features and indicates the end of HPy's *alhpa*
phase. We've migrated several key packages to HPy (for a list, see our website
https://hpyproject.org) and we are now confident that HPy is mature enough for
being used as serious extension API. We also plan that the next major release
will be ``1.0``.

Major new features
~~~~~~~~~~~~~~~~~~

Support subclasses of built-in types
It is now possible to create pure HPy types that inherit from built-in types
like ``type`` or ``float``. This was already possible before but in a very
limited way, i.e., by setting :c:member:`HPyType_Spec.basicsize` to ``0``. In
this case, the type implicitly inherited the basic size of the supertype but
that also means that you cannot have a custom C struct. It is now possible
inherit from a built-in type **AND** have a custom C struct. For further
reference, see :c:member:`HPyType_Spec.builtin_shape` and
:c:enum:`HPyType_BuiltinShape`.

Support for metaclasses
HPy now supports creating types with metaclasses. This can be done by passing
type specification parameter with kind
:c:enumerator:`HPyType_SpecParam_Metaclass` when calling
:c:func:`HPyType_FromSpec`.

:term:`HPy Hybrid ABI`
In addition to :term:`CPython ABI` and :term:`HPy Universal ABI`, we now
introduced the Hybrid ABI. The major difference is that whenever you use a
legacy API like :c:func:`HPy_AsPyObject` or :c:func:`HPy_FromPyObject`, the
prdouced binary will then be specific to one interpreter. This was necessary
to ensure that universal binaries are really portable and can be used on any
HPy-capable interpreter.

:doc:`trace-mode`
Similar to the :doc:`debug-mode`, HPy now provides the Trace Mode that can be
enabled at runtime and helps analyzing API usage and identifying performance
issues.

:ref:`porting-guide:multi-phase module initialization`
HPy now support multi-phase module initialization which is an important
feature in particular needed for two important use cases: (1) module state
support (which is planned to be introduced in the next major release), and (2)
subinterpreters. We decided to drop support for single-phase module
initialization since this makes the API cleaner and easier to use.

HPy :ref:`porting-guide:calling protocol`
This was a big missing piece and is now eventually available. It enables slot
``HPy_tp_call``, which can now be used in the HPy type specification. We
decided to use a calling convention similar to CPython's vectorcall calling
convention. This is: the arguments are passed in a C array and the keyword
argument names are provided as a Python tuple. Before this release, the only
way to create a callable type was to set the special method ``__call__``.
However, this has several disadvantages. In particlar, poor performance on
CPython (and maybe other implementations) and it was not possible to have
specialized call function implementations per object (see
:c:func:`HPy_SetCallFunction`)

Added APIs
~~~~~~~~~~

Deleting attributes and items
:c:func:`HPy_DelAttr`, :c:func:`HPy_DelAttr_s`, :c:func:`HPy_DelItem`, :c:func:`HPy_DelItem_i`, :c:func:`HPy_DelItem_s`

Capsule API
:c:func:`HPyCapsule_New`, :c:func:`HPyCapsule_IsValid`, :c:func:`HPyCapsule_Get`, :c:func:`HPyCapsule_Set`

Eval API
:c:func:`HPy_Compile_s` and :c:func:`HPy_EvalCode`

Formatting helpers
:c:func:`HPyUnicode_FromFormat` and :c:func:`HPyErr_Format`

Contextvar API
:c:func:`HPyContextVar_New`, :c:func:`HPyContextVar_Get`, :c:func:`HPyContextVar_Set`

Unicode API
:c:func:`HPyUnicode_FromEncodedObject` and :c:func:`HPyUnicode_Substring`

Dict API
:c:func:`HPyDict_Keys` and :c:func:`HPyDict_Copy`

Type API
:c:func:`HPyType_GetName` and :c:func:`HPyType_IsSubtype`

Slice API
:c:func:`HPySlice_Unpack` and :c:func:`HPySlice_AdjustIndices`

Structseq API
:c:func:`HPyStructSequence_NewType`, :c:func:`HPyStructSequence_New`

Call API
:c:func:`HPy_Call`, :c:func:`HPy_CallMethod`, :c:func:`HPy_CallMethodTupleDict`, :c:func:`HPy_CallMethodTupleDict_s`

HPy call protocol
:c:func:`HPy_SetCallFunction`

Debug mode
~~~~~~~~~~

* Detect closing and returning (without dup) of context handles
* Detect invalid usage of stored ``HPyContext *`` pointer
* Detect invalid usage of tuple and list builders
* Added Windows support for checking invalid use of raw data pointers (e.g
``HPyUnicode_AsUTF8AndSize``) after handle was closed.
* Added support for backtrace on MacOS

Documentation
~~~~~~~~~~~~~

* Added incremental :doc:`porting-example/index`
* Added :doc:`quickstart` guide
* Extended :doc:`api-reference/index`
* Added :doc:`api-reference/function-index`
* Added possiblity to generate examples from tests with argument ``--dump-dir``
(see :ref:`api:hpy unit tests`)
* Added initial :doc:`contributing/index` docs

Incompatible changes to version 0.0.4
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

* Simplified ``HPyDef_*`` macros
* Changed macro :c:macro:`HPy_MODINIT` because of multi-phase module init
support.
* Replace environment variable ``HPY_DEBUG`` by ``HPY`` (see :doc:`debug-mode`
or :doc:`trace-mode`).
* Changed signature of ``HPyFunc_VARARGS`` and ``HPyFunc_ KEYWORDS`` to align
with HPy's call protocol calling convention.

Supported Python versions
~~~~~~~~~~~~~~~~~~~~~~~~~

* Added Python 3.11 support
* Preliminary Python 3.12 support
* Dropped Python 3.6 support (since EOL)
* Dropped Python 3.7 support (since EOL by June 2023)

Misc
~~~~

* Ensure deterministic auto-generation
* Ensure ABI backwards compatibility

* Explicitly define slot within HPyContext of function pointers and handles
* Compile HPy ABI version into binary and verify at load time
* Added proper support for object members ``HPyMember_OBJECT``
* Changed :c:func:`HPyBytes_AsString` and :c:func:`HPyBytes_AS_STRING` to return ``const char *``
* Use fixed-width integers in context functions



Version 0.0.4 (May 25th, 2022)
------------------------------

Expand Down
2 changes: 1 addition & 1 deletion docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
author = "HPy Collective"

# The full version, including alpha/beta/rc tags
release = "0.0.4"
release = "0.9"


# -- General configuration ---------------------------------------------------
Expand Down
6 changes: 6 additions & 0 deletions hpy/devel/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,12 @@ def handle_hpy_ext_modules(dist, attr, hpy_ext_modules):
"""
assert attr == 'hpy_ext_modules'

# It can happen that this hook will be called multiple times depending on
# which command was used. So, skip patching if we already patched the
# distribution.
if getattr(dist, 'hpydevel', None):
return

# add a global option --hpy-abi to setup.py
dist.__class__.hpy_abi = DEFAULT_HPY_ABI
dist.__class__.hpy_use_static_libs = False
Expand Down
Loading

0 comments on commit 885add8

Please sign in to comment.