Skip to content

Commit

Permalink
Merge branch 'main' into feat/proptest2
Browse files Browse the repository at this point in the history
  • Loading branch information
doug-q authored May 21, 2024
2 parents 6e425d8 + dbaf601 commit 979103a
Show file tree
Hide file tree
Showing 22 changed files with 219 additions and 109 deletions.
2 changes: 1 addition & 1 deletion .release-please-manifest.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
{
"hugr-py": "0.2.0a1"
"hugr-py": "0.2.1"
}
47 changes: 47 additions & 0 deletions DEVELOPMENT.md
Original file line number Diff line number Diff line change
Expand Up @@ -136,3 +136,50 @@ We accept the following contribution types:
- ci: CI related changes. These changes are not published in the changelog.
- chore: Updating build tasks, package manager configs, etc. These changes are not published in the changelog.
- revert: Reverting previous commits.

## :shipit: Releasing new versions

We use automation to bump the version number and generate changelog entries
based on the [conventional commits](https://www.conventionalcommits.org/en/v1.0.0/) labels. Release PRs are created automatically
for each package when new changes are merged into the `main` branch. Once the PR is
approved by someone in the [release team](.github/CODEOWNERS) and is merged, the new package
is published on PyPI or crates.io as appropriate.

The changelog can be manually edited before merging the release PR. Note however
that modifying the diff before other changes are merged will cause the
automation to close the release PR and create a new one to avoid conflicts.

### Rust crate release

Rust releases are managed by `release-plz`. This tool will automatically detect
breaking changes even when they are not marked as such in the commit message,
and bump the version accordingly.

To modify the version being released, update the `Cargo.toml`,
CHANGELOG.md, PR name, and PR description in the release PR with the desired version. You may also have to update the dates.
Rust pre-release versions should be formatted as `0.1.0-alpha.1` (or `-beta`, or `-rc`).

### Python package release

Python releases are managed by `release-please`. This tool always bumps the
minor version (or the pre-release version if the previous version was a
pre-release).

To override the version getting released, you must merge a PR to `main` containing
`Release-As: 0.1.0` in the description.
Python pre-release versions should be formatted as `0.1.0a1` (or `b1`, `rc1`).

### Patch releases

Sometimes we need to release a patch version to fix a critical bug, but we don't want
to include all the changes that have been merged into the main branch. In this case,
you can create a new branch from the latest release tag and cherry-pick the commits
you want to include in the patch release.

You will need to modify the version and changelog manually in this case. Check
the existing release PRs for examples on how to do this. Once the branch is
ready, create a [github release](https://github.com/CQCL/hugr/releases/new).
The tag should follow the format used in the previous releases, e.g. `hugr-py-v0.1.1`.

For rust crates, you will need someone from the release team to manually
publish the new version to crates.io by running `cargo release`.
4 changes: 2 additions & 2 deletions hugr-py/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
# Changelog

## [0.2.0a1](https://github.com/CQCL/hugr/compare/hugr-py-v0.1.0...hugr-py-v0.2.0a1) (2024-05-13)

## [0.2.1](https://github.com/CQCL/hugr/compare/hugr-py-v0.2.0...hugr-py-v0.2.1) (2024-05-20)

### ⚠ BREAKING CHANGES

Expand All @@ -11,6 +10,7 @@

### Features

* Add serialization schema for metadata ([#1038](https://github.com/CQCL/hugr/issues/1038)) ([19bac62](https://github.com/CQCL/hugr/commit/19bac6210aa8c495679bd7c783751e9cde744c61))
* Add LoadFunction node ([#947](https://github.com/CQCL/hugr/issues/947)) ([81e9602](https://github.com/CQCL/hugr/commit/81e9602a47eddadc1c11d74ca7bda3b194d24f00))
* Encoder metadata in serialized hugr ([#955](https://github.com/CQCL/hugr/issues/955)) ([0a44d48](https://github.com/CQCL/hugr/commit/0a44d487b73f58674eb5884c72479a03e924bef0))
* Implement `CustomConst` serialization ([#1005](https://github.com/CQCL/hugr/issues/1005)) ([c45e6fc](https://github.com/CQCL/hugr/commit/c45e6fc67334768ea55c4bd5223af0b7b0cc47ec))
Expand Down
2 changes: 1 addition & 1 deletion hugr-py/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ classifiers = [
"Topic :: Scientific/Engineering",
]
name = "hugr"
version = "0.2.0a1"
version = "0.2.1"
description = "Quantinuum's common representation for quantum programs"
#keywords = []
authors = ["TKET development team <[email protected]>"]
Expand Down
4 changes: 3 additions & 1 deletion hugr-py/src/hugr/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@
representation.
"""

__version__ = "0.2.0a1"
# This is updated by our release-please workflow, triggered by this
# annotation: x-release-please-version
__version__ = "0.2.1"


def it_works() -> str:
Expand Down
36 changes: 19 additions & 17 deletions hugr-py/src/hugr/serialization/ops.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
from abc import ABC
from typing import Any, Literal

from pydantic import Field, RootModel
from pydantic import Field, RootModel, ConfigDict

from . import tys
from .tys import (
Expand Down Expand Up @@ -108,15 +108,14 @@ class SumValue(ConfiguredBaseModel):
tag: int
typ: SumType
vs: list["Value"]

class Config:
# Needed to avoid random '\n's in the pydantic description
json_schema_extra = {
model_config = ConfigDict(
json_schema_extra={
"description": (
"A Sum variant For any Sum type where this value meets the type "
"of the variant indicated by the tag."
),
}
)


class Value(RootModel):
Expand All @@ -126,8 +125,7 @@ class Value(RootModel):
discriminator="v"
)

class Config:
json_schema_extra = {"required": ["v"]}
model_config = ConfigDict(json_schema_extra={"required": ["v"]})


class Const(BaseOp):
Expand Down Expand Up @@ -168,11 +166,13 @@ def insert_child_dfg_signature(self, inputs: TypeRow, outputs: TypeRow) -> None:
self.sum_rows.append(variant)
self.other_outputs = outputs[1:]

class Config:
# Needed to avoid random '\n's in the pydantic description
json_schema_extra = {

model_config = ConfigDict(
json_schema_extra={
"description": "A CFG basic block node. The signature is that of the internal Dataflow graph.",
}
)


class ExitBlock(BaseOp):
Expand All @@ -182,11 +182,12 @@ class ExitBlock(BaseOp):
op: Literal["ExitBlock"] = "ExitBlock"
cfg_outputs: TypeRow

class Config:
json_schema_extra = {
model_config = ConfigDict(
json_schema_extra={
# Needed to avoid random '\n's in the pydantic description
"description": "The single exit node of the CFG, has no children, stores the types of the CFG node output.",
}
)


# ---------------------------------------------
Expand Down Expand Up @@ -234,16 +235,17 @@ class Call(DataflowOp):
type_args: list[tys.TypeArg]
instantiation: FunctionType

class Config:
model_config = ConfigDict(
# Needed to avoid random '\n's in the pydantic description
json_schema_extra = {
json_schema_extra={
"description": (
"Operation to call a function directly. The first port is "
"connected to the def/declare of the function being called directly, "
"with a `Static<FunctionType>` edge. The signature of the remaining "
"ports matches the function being called."
)
}
)


class CallIndirect(DataflowOp):
Expand Down Expand Up @@ -386,14 +388,15 @@ def insert_port_types(self, in_types: TypeRow, out_types: TypeRow) -> None:
def display_name(self) -> str:
return self.op_name

class Config:
model_config = ConfigDict(
# Needed to avoid random '\n's in the pydantic description
json_schema_extra = {
json_schema_extra={
"description": (
"A user-defined operation that can be downcasted by the extensions that "
"define it."
)
}
)


class Noop(DataflowOp):
Expand Down Expand Up @@ -491,8 +494,7 @@ class OpType(RootModel):
| AliasDefn
) = Field(discriminator="op")

class Config:
json_schema_extra = {"required": ["parent", "op"]}
model_config = ConfigDict(json_schema_extra={"required": ["parent", "op"]})


# --------------------------------------
Expand Down
9 changes: 5 additions & 4 deletions hugr-py/src/hugr/serialization/serial_hugr.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,9 @@ def _pydantic_rebuild(cls, config: ConfigDict = ConfigDict(), **kwargs):
my_classes[cls.__name__] = cls
model_rebuild(my_classes, config=config, **kwargs)

class Config:
title = "Hugr"
json_schema_extra = {
model_config = ConfigDict(
title="Hugr",
json_schema_extra={
"required": ["version", "nodes", "edges"],
}
},
)
22 changes: 10 additions & 12 deletions hugr-py/src/hugr/serialization/tys.py
Original file line number Diff line number Diff line change
Expand Up @@ -99,8 +99,7 @@ class TypeParam(RootModel):
WrapValidator(_json_custom_error_validator),
] = Field(discriminator="tp")

class Config:
json_schema_extra = {"required": ["tp"]}
model_config = ConfigDict(json_schema_extra={"required": ["tp"]})


# ------------------------------------------
Expand Down Expand Up @@ -153,8 +152,7 @@ class TypeArg(RootModel):
WrapValidator(_json_custom_error_validator),
] = Field(discriminator="tya")

class Config:
json_schema_extra = {"required": ["tya"]}
model_config = ConfigDict(json_schema_extra={"required": ["tya"]})


# --------------------------------------------
Expand Down Expand Up @@ -197,8 +195,7 @@ class SumType(RootModel):
def t(self) -> str:
return self.root.t

class Config:
json_schema_extra = {"required": ["s"]}
model_config = ConfigDict(json_schema_extra={"required": ["s"]})


# ----------------------------------------------
Expand Down Expand Up @@ -235,14 +232,15 @@ class FunctionType(ConfiguredBaseModel):
def empty(cls) -> "FunctionType":
return FunctionType(input=[], output=[], extension_reqs=[])

class Config:
model_config = ConfigDict(
# Needed to avoid random '\n's in the pydantic description
json_schema_extra = {
json_schema_extra={
"description": (
"A graph encoded as a value. It contains a concrete signature and "
"a set of required resources."
)
}
)


class PolyFuncType(ConfiguredBaseModel):
Expand All @@ -261,14 +259,15 @@ class PolyFuncType(ConfiguredBaseModel):
def empty(cls) -> "PolyFuncType":
return PolyFuncType(params=[], body=FunctionType.empty())

class Config:
model_config = ConfigDict(
# Needed to avoid random '\n's in the pydantic description
json_schema_extra = {
json_schema_extra={
"description": (
"A polymorphic type scheme, i.e. of a FuncDecl, FuncDefn or OpDef. "
"(Nodes/operations in the Hugr are not polymorphic.)"
)
}
)


class TypeBound(Enum):
Expand Down Expand Up @@ -326,8 +325,7 @@ class Type(RootModel):
Field(discriminator="t"),
]

class Config:
json_schema_extra = {"required": ["t"]}
model_config = ConfigDict(json_schema_extra={"required": ["t"]})


# -------------------------------------------
Expand Down
15 changes: 12 additions & 3 deletions hugr-py/tests/serialization/test_basic.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,12 @@
def test_it_works():
"""TODO: Replace this with a real test."""
assert 2 + 2 != "🐟"
from hugr.serialization import SerialHugr


def test_empty():
h = SerialHugr(nodes=[], edges=[])
assert h.model_dump() == {
"version": "v1",
"nodes": [],
"edges": [],
"metadata": None,
"encoder": None,
}
16 changes: 16 additions & 0 deletions hugr-py/tests/test_version.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# from https://github.com/python-poetry/poetry/issues/144#issuecomment-877835259
import toml # type: ignore[import-untyped]
from pathlib import Path
import hugr


def test_versions_are_in_sync():
"""Checks if the pyproject.toml and package.__init__.py __version__ are in sync."""

path = Path(__file__).resolve().parents[1] / "pyproject.toml"
pyproject = toml.loads(open(str(path)).read())
pyproject_version = pyproject["tool"]["poetry"]["version"]

package_init_version = hugr.__version__

assert package_init_version == pyproject_version
11 changes: 10 additions & 1 deletion hugr/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
# Changelog

## 0.4.0-alpha.1 (2024-05-13)
## 0.4.0 (2024-05-20)

### Bug Fixes

- Disallow non-finite values for `ConstF64` ([#1075](https://github.com/CQCL/hugr/pull/1075))
- Serialization round-trips ([#948](https://github.com/CQCL/hugr/pull/948))
- [**breaking**] Combine `ConstIntU` and `ConstIntS` ([#974](https://github.com/CQCL/hugr/pull/974))
- Disable serialisation tests when miri is active ([#977](https://github.com/CQCL/hugr/pull/977))
Expand All @@ -15,6 +16,9 @@

### Features

- Add verification to constant folding ([#1030](https://github.com/CQCL/hugr/pull/1030))
- Add `Const::get_custom_value` ([#1037](https://github.com/CQCL/hugr/pull/1037))
- Add serialization schema for metadata ([#1038](https://github.com/CQCL/hugr/pull/1038))
- 'Replace' rewrite returns node map ([#929](https://github.com/CQCL/hugr/pull/929))
- `new` methods for leaf ops ([#940](https://github.com/CQCL/hugr/pull/940))
- Add `string` type and `print` function to `prelude` ([#942](https://github.com/CQCL/hugr/pull/942))
Expand All @@ -31,13 +35,18 @@

### Refactor

- [**breaking**] Rename `crate::ops::constant::ExtensionValue` => `OpaqueValue` ([#1036](https://github.com/CQCL/hugr/pull/1036))
- Outline hugr::serialize::test ([#976](https://github.com/CQCL/hugr/pull/976))
- [**breaking**] Replace SmolStr identifiers with wrapper types. ([#959](https://github.com/CQCL/hugr/pull/959))
- Separate extension validation from the rest ([#1011](https://github.com/CQCL/hugr/pull/1011))
- Remove "trait TypeParametrised" ([#1019](https://github.com/CQCL/hugr/pull/1019))

### Testing

- Reorg OutlineCfg/nest_cfgs tests so hugr doesn't depend on algorithm ([#1007](https://github.com/CQCL/hugr/pull/1007))
- Ignore tests which depend on typetag when cfg(miri) ([#1051](https://github.com/CQCL/hugr/pull/1051))
- Really ignore tests which depend on typetag when cfg(miri) ([#1058](https://github.com/CQCL/hugr/pull/1058))
- Proptests for round trip serialisation of `Type`s and `Op`s. ([#981](https://github.com/CQCL/hugr/pull/981))
- Add a test of instantiating an extension set ([#939](https://github.com/CQCL/hugr/pull/939))
- Ignore serialisation tests when using miri ([#975](https://github.com/CQCL/hugr/pull/975))
- [**breaking**] Test roundtrip serialisation against strict + lax schema ([#982](https://github.com/CQCL/hugr/pull/982))
Expand Down
4 changes: 2 additions & 2 deletions hugr/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "hugr"
version = "0.4.0-alpha.1"
version = "0.4.0"
edition = { workspace = true }
rust-version = { workspace = true }

Expand Down Expand Up @@ -40,7 +40,7 @@ serde_yaml = "0.9.19"
typetag = "0.2.7"
smol_str = { version = "0.2.0", features = ["serde"] }
derive_more = "0.99.17"
itertools = "0.12.0"
itertools = "0.13.0"
html-escape = "0.2.13"
bitvec = { version = "1.0.1", features = ["serde"] }
enum_dispatch = "0.3.11"
Expand Down
Loading

0 comments on commit 979103a

Please sign in to comment.