* [PR PATCH] WIP: anki: update to 2.1.26
@ 2020-05-23 6:18 fosslinux
2020-05-23 7:07 ` [PR PATCH] [Updated] " fosslinux
` (12 more replies)
0 siblings, 13 replies; 14+ messages in thread
From: fosslinux @ 2020-05-23 6:18 UTC (permalink / raw)
To: ml
[-- Attachment #1: Type: text/plain, Size: 1565 bytes --]
There is a new pull request by fosslinux against master on the void-packages repository
https://github.com/fosslinux/void-packages anki-2.1.26
https://github.com/void-linux/void-packages/pull/22219
WIP: anki: update to 2.1.26
This has a wide variety of changes as if you have heard my ranting in #xbps it has turned into a Bad Build System - there is rust (nightly!), nodejs, python, etc etc, no proper install target...
A few things to note:
- python3-mypy is updated as mypy-protobuf needs the new version, otherwise the build failed.
- maturin is some weird build system at the intersection of rust and python.
- mypy-protobuf-python is what anki uses for binding python and rust together, partly.
- mypy-protobuf-go is the go implementation of mypy-protobuf-python that I thought should be packaged anywway.
- python-stringcase is a new dependency.
- anki is an archd package (not nocross), because the rust code is obviously platform specific.
- anki uses rustup. This is because it and some of its dependencies require archd code (notably pyo3). This is unavoidable, afaict.
Still todo:
- [ ] Apply archlinux's aqt_build patch, which stops it from polluting /usr directly (:vomiting_face:)
- [ ] More extensive runtime testing. It opens, but seems to have weird icon issues?
- [ ] Runtime test on musl.
Questions:
- Is there any problems with removing `arch=nocross`?
- Does the rustup stuff look (somewhat) sane?
- Are the patches sane?
A patch file from https://github.com/void-linux/void-packages/pull/22219.patch is attached
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: github-pr-anki-2.1.26-22219.patch --]
[-- Type: text/x-diff, Size: 16588 bytes --]
From e88132a875c981abbac9216cce895b2b034d8ed0 Mon Sep 17 00:00:00 2001
From: fosslinux <fosslinux@aussies.space>
Date: Sat, 23 May 2020 14:33:01 +1000
Subject: [PATCH 1/6] python3-mypy: update to 0.770, claim maintainership
---
srcpkgs/python3-mypy/template | 7 +++----
1 file changed, 3 insertions(+), 4 deletions(-)
diff --git a/srcpkgs/python3-mypy/template b/srcpkgs/python3-mypy/template
index 5d7f93d5772..bde1e7f4be6 100644
--- a/srcpkgs/python3-mypy/template
+++ b/srcpkgs/python3-mypy/template
@@ -1,19 +1,18 @@
# Template file for 'python3-mypy'
pkgname=python3-mypy
-version=0.761
+version=0.770
revision=1
archs=noarch
wrksrc="mypy-${version}"
build_style=python3-module
-pycompile_module="mypy"
hostmakedepends="python3-setuptools"
depends="python3-mypy_extensions python3-typed-ast python3-typing_extensions"
short_desc="Optional static typing for Python3"
-maintainer="Orphaned <orphan@voidlinux.org>"
+maintainer="fosslinux <fosslinux@aussies.space>"
license="MIT"
homepage="https://github.com/python/mypy"
distfiles="${PYPI_SITE}/m/mypy/mypy-${version}.tar.gz"
-checksum=85baab8d74ec601e86134afe2bcccd87820f79d2f8d5798c889507d1088287bf
+checksum=8a627507ef9b307b46a1fea9513d5c98680ba09591253082b4c48697ba05a4ae
post_install() {
vlicense LICENSE
From ae580c7dcc5fa9ee6c2040b185773341a8fdda2b Mon Sep 17 00:00:00 2001
From: fosslinux <fosslinux@aussies.space>
Date: Sat, 23 May 2020 14:34:38 +1000
Subject: [PATCH 2/6] New package: maturin-0.8.1
---
.../patches/cross-compile-setup-py.patch | 14 +++++++++++++
srcpkgs/maturin/template | 21 +++++++++++++++++++
2 files changed, 35 insertions(+)
create mode 100644 srcpkgs/maturin/patches/cross-compile-setup-py.patch
create mode 100644 srcpkgs/maturin/template
diff --git a/srcpkgs/maturin/patches/cross-compile-setup-py.patch b/srcpkgs/maturin/patches/cross-compile-setup-py.patch
new file mode 100644
index 00000000000..e57189cb7ab
--- /dev/null
+++ b/srcpkgs/maturin/patches/cross-compile-setup-py.patch
@@ -0,0 +1,14 @@
+--- setup.py 2020-04-30 22:36:01.000000000 +1000
++++ setup.py 2020-05-20 14:31:40.404994499 +1000
+@@ -56,9 +56,9 @@
+ "(https://www.rust-lang.org/tools/install) and try again"
+ )
+ subprocess.check_call(
+- ["cargo", "rustc", "--bin", "maturin", "--", "-C", "link-arg=-s"]
++ ["cargo", "rustc", "--bin", "maturin", "--release", "--target", os.environ["RUST_TARGET"], "--", "-C", "link-arg=-s", "-C", "linker=" + os.environ["CC"].split(" ", 1)[0]]
+ )
+- source = os.path.join(source_dir, "target", "debug", executable_name)
++ source = os.path.join(source_dir, "target", os.environ["RUST_TARGET"], "release", executable_name)
+ # run this after trying to build with cargo (as otherwise this leaves
+ # venv in a bad state: https://github.com/benfred/py-spy/issues/69)
+ install.run(self)
diff --git a/srcpkgs/maturin/template b/srcpkgs/maturin/template
new file mode 100644
index 00000000000..7eba36204f9
--- /dev/null
+++ b/srcpkgs/maturin/template
@@ -0,0 +1,21 @@
+# Template file for 'maturin'
+pkgname=maturin
+version=0.8.1
+revision=1
+build_style=python3-module
+hostmakedepends="cargo python3-setuptools python3-toml"
+makedepends="rust rust-std llvm9"
+short_desc="Build and publish crates with python bindings"
+maintainer="fosslinux <fosslinux@aussies.space>"
+license="Apache-2.0, MIT"
+homepage="https://github.com/PyO3/maturin"
+distfiles="https://github.com/PyO3/maturin/archive/v${version}.tar.gz"
+checksum=b72a9885cda3ba4e53906a43aab101acb790622218ade6405b2ddf1ef1461f8f
+
+post_install() {
+ # Dynamic detection of python version
+ PYTHON_VERSION=$(python3 --version | sed "s/^Python //" | rev | sed "s/^[0-9]*.//" | rev)
+ mkdir -p "${DESTDIR}/usr/lib/python${PYTHON_VERSION}/site-packages/"
+ mv "${DESTDIR}/maturin" "${DESTDIR}/usr/lib/python${PYTHON_VERSION}/site-packages/"
+ vlicense license-mit
+}
From 1bd1177a01ea7ce37e08a382eed7597a764ae457 Mon Sep 17 00:00:00 2001
From: fosslinux <fosslinux@aussies.space>
Date: Sat, 23 May 2020 14:35:25 +1000
Subject: [PATCH 3/6] New package: mypy-protobuf-python-1.13
---
srcpkgs/mypy-protobuf-python/template | 23 +++++++++++++++++++++++
1 file changed, 23 insertions(+)
create mode 100644 srcpkgs/mypy-protobuf-python/template
diff --git a/srcpkgs/mypy-protobuf-python/template b/srcpkgs/mypy-protobuf-python/template
new file mode 100644
index 00000000000..391d75f0c9e
--- /dev/null
+++ b/srcpkgs/mypy-protobuf-python/template
@@ -0,0 +1,23 @@
+# Template file for 'mypy-protobuf-python'
+#
+# WARNING: THIS TEMPLATE SHOULD BE SYNCRONISED WITH mypy-protobuf-go
+#
+pkgname=mypy-protobuf-python
+version=1.13
+revision=1
+wrksrc="mypy-protobuf-${version}"
+build_wrksrc=python
+build_style=python3-module
+hostmakedepends="python3-setuptools"
+depends="python3-mypy python3-typing_extensions python3-protobuf protobuf"
+short_desc="Generate mypy stubs from protobufs - Python implementation"
+maintainer="fosslinux <fosslinux@aussies.space>"
+license="Apache-2.0"
+homepage="https://github.com/dropbox/mypy-protobuf"
+distfiles="https://github.com/dropbox/mypy-protobuf/archive/v${version}.tar.gz"
+checksum=7d86dfc076f8b51814fbfd3a66998a0b570fd1b82ebeda68ae6728cd538adb74
+
+post_install() {
+ # We are not windows, remove the batch file
+ rm "${DESTDIR}/usr/bin/protoc_gen_mypy.bat"
+}
From 2005df10d61b46933f28eea0b17e701a09af437b Mon Sep 17 00:00:00 2001
From: fosslinux <fosslinux@aussies.space>
Date: Sat, 23 May 2020 14:35:37 +1000
Subject: [PATCH 4/6] New package: mypy-protobuf-go-1.13
---
.../patches/remote-go-improt.patch | 11 +++++++++++
srcpkgs/mypy-protobuf-go/template | 19 +++++++++++++++++++
2 files changed, 30 insertions(+)
create mode 100644 srcpkgs/mypy-protobuf-go/patches/remote-go-improt.patch
create mode 100644 srcpkgs/mypy-protobuf-go/template
diff --git a/srcpkgs/mypy-protobuf-go/patches/remote-go-improt.patch b/srcpkgs/mypy-protobuf-go/patches/remote-go-improt.patch
new file mode 100644
index 00000000000..300504bc70d
--- /dev/null
+++ b/srcpkgs/mypy-protobuf-go/patches/remote-go-improt.patch
@@ -0,0 +1,11 @@
+--- go/src/protoc-gen-mypy/main.go.orig 2020-05-22 11:58:07.760761664 +1000
++++ go/src/protoc-gen-mypy/main.go 2020-05-22 11:58:00.595762190 +1000
+@@ -6,7 +6,7 @@
+ "sort"
+ "strings"
+
+- "proto/mypy"
++ "github.com/dropbox/mypy-protobuf/go/src/proto/mypy"
+
+ "github.com/gogo/protobuf/proto"
+ "github.com/gogo/protobuf/protoc-gen-gogo/descriptor"
diff --git a/srcpkgs/mypy-protobuf-go/template b/srcpkgs/mypy-protobuf-go/template
new file mode 100644
index 00000000000..8f00e43d8a8
--- /dev/null
+++ b/srcpkgs/mypy-protobuf-go/template
@@ -0,0 +1,19 @@
+# Template file for 'mypy-protobuf-go'
+#
+# WARNING: THIS TEMPLATE SHOULD BE SYNCRONISED WITH mypy-protobuf-python
+#
+pkgname=mypy-protobuf-go
+version=1.13
+revision=1
+wrksrc="mypy-protobuf-${version}"
+build_style=go
+go_import_path="github.com/dropbox/mypy-protobuf"
+go_package="${go_import_path}/go/src/protoc-gen-mypy"
+hostmakedepends="git"
+depends="protobuf"
+short_desc="Generate mypy stubs from protobufs - go implementation"
+maintainer="fosslinux <fosslinux@aussies.space>"
+license="Apache-2.0"
+homepage="https://github.com/dropbox/mypy-protobuf"
+distfiles="https://github.com/dropbox/mypy-protobuf/archive/v${version}.tar.gz"
+checksum=7d86dfc076f8b51814fbfd3a66998a0b570fd1b82ebeda68ae6728cd538adb74
From db650873d45635b6983c2d24717e827309303092 Mon Sep 17 00:00:00 2001
From: fosslinux <fosslinux@aussies.space>
Date: Sat, 23 May 2020 14:33:36 +1000
Subject: [PATCH 5/6] New package: python-stringcase-1.2.0
---
srcpkgs/python-stringcase/template | 28 ++++++++++++++++++++++++++++
srcpkgs/python3-stringcase | 1 +
2 files changed, 29 insertions(+)
create mode 100644 srcpkgs/python-stringcase/template
create mode 120000 srcpkgs/python3-stringcase
diff --git a/srcpkgs/python-stringcase/template b/srcpkgs/python-stringcase/template
new file mode 100644
index 00000000000..849e677c784
--- /dev/null
+++ b/srcpkgs/python-stringcase/template
@@ -0,0 +1,28 @@
+# Template file for 'python-stringcase'
+pkgname=python-stringcase
+version=1.2.0
+revision=1
+wrksrc="stringcase-${version}"
+build_style=python-module
+hostmakedepends="python-devel python3-devel"
+makedepends="${hostmakedepends}"
+depends="python"
+short_desc="String case converter for Python2"
+maintainer="fosslinux <fosslinux@aussies.space>"
+license="MIT"
+homepage="https://github.com/okunishinishi/python-stringcase"
+distfiles="${PYPI_SITE}/s/stringcase/stringcase-${version}.tar.gz"
+checksum=48a06980661908efe8d9d34eab2b6c13aefa2163b3ced26972902e3bdfd87008
+
+post_install() {
+ vlicense LICENSE
+}
+
+python3-stringcase_package() {
+ depends="python3"
+ short_desc="${short_desc/Python2/Python3}"
+ pkg_install() {
+ vmove usr/lib/python3*
+ vlicense LICENSE
+ }
+}
diff --git a/srcpkgs/python3-stringcase b/srcpkgs/python3-stringcase
new file mode 120000
index 00000000000..53938bd1f0c
--- /dev/null
+++ b/srcpkgs/python3-stringcase
@@ -0,0 +1 @@
+python-stringcase
\ No newline at end of file
From 7b045648ba4caa04579616dff5022d9c65af8114 Mon Sep 17 00:00:00 2001
From: fosslinux <fosslinux@aussies.space>
Date: Sat, 23 May 2020 14:36:21 +1000
Subject: [PATCH 6/6] anki: update to 2.1.26
Has turned into a Bad Build System. Now uses rust nightly, python
(with bindings!), qt5, nodejs... the list goes on. There are quite
a few hacks and the like.
---
.../anki/patches/rustc-cross-compile.patch | 11 +++
srcpkgs/anki/patches/vendored-deps.patch | 94 +++++++++++++++++++
srcpkgs/anki/template | 58 ++++++++++--
3 files changed, 157 insertions(+), 6 deletions(-)
create mode 100644 srcpkgs/anki/patches/rustc-cross-compile.patch
create mode 100644 srcpkgs/anki/patches/vendored-deps.patch
diff --git a/srcpkgs/anki/patches/rustc-cross-compile.patch b/srcpkgs/anki/patches/rustc-cross-compile.patch
new file mode 100644
index 00000000000..15239ea4cf1
--- /dev/null
+++ b/srcpkgs/anki/patches/rustc-cross-compile.patch
@@ -0,0 +1,11 @@
+--- rspy/Makefile 2020-05-23 12:02:29.758286838 +1000
++++ rspy/Makefile 2020-05-08 18:17:57.000000000 +1000
+@@ -69,7 +69,7 @@
+ .build/build: $(DEPS)
+ touch ../proto/backend.proto
+ ${BUILD_VARIABLES} \
+- maturin build -i "${PYTHON_FILE}" -o "$(OUTDIR)" $(BUILDFLAGS)
++ maturin build -i "${PYTHON_FILE}" -o "$(OUTDIR)" $(BUILDFLAGS) --target $(RUST_TARGET)
+ touch $@
+
+ check: .build/check
diff --git a/srcpkgs/anki/patches/vendored-deps.patch b/srcpkgs/anki/patches/vendored-deps.patch
new file mode 100644
index 00000000000..1d2bc90ffb1
--- /dev/null
+++ b/srcpkgs/anki/patches/vendored-deps.patch
@@ -0,0 +1,94 @@
+diff -u -r Makefile Makefile
+--- Makefile 2020-05-08 18:17:57.000000000 +1000
++++ Makefile 2020-05-19 18:40:54.345223164 +1000
+@@ -92,7 +92,7 @@
+ fi
+
+ .PHONY: develop
+-develop: pyenv buildhash prepare
++develop: buildhash prepare
+ @set -eu -o pipefail ${SHELLFLAGS}; \
+ . "${ACTIVATE_SCRIPT}"; \
+ for dir in $(DEVEL); do \
+diff -u -r pylib/Makefile pylib/Makefile
+--- pylib/Makefile 2020-05-08 18:17:57.000000000 +1000
++++ pylib/Makefile 2020-05-19 18:50:01.075182994 +1000
+@@ -52,7 +52,7 @@
+ python -m black anki/hooks.py
+ @touch $@
+
+-BUILD_STEPS := .build/vernum .build/run-deps .build/dev-deps .build/py-proto anki/buildinfo.py .build/hooks
++BUILD_STEPS := .build/vernum .build/py-proto anki/buildinfo.py .build/hooks
+
+ # Checking
+ ######################
+diff -u -r qt/Makefile qt/Makefile
+--- qt/Makefile 2020-05-08 18:17:57.000000000 +1000
++++ qt/Makefile 2020-05-19 18:50:17.520181786 +1000
+@@ -64,7 +64,7 @@
+ python -m black aqt/gui_hooks.py
+ @touch $@
+
+-BUILD_STEPS := .build/vernum .build/run-deps .build/dev-deps .build/js .build/ui aqt/buildinfo.py .build/hooks .build/i18n
++BUILD_STEPS := .build/vernum .build/js .build/ui aqt/buildinfo.py .build/hooks .build/i18n
+
+ # Checking
+ ######################
+--- Makefile 2020-05-08 18:17:57.000000000 +1000
++++ Makefile 2020-05-19 19:01:35.602131965 +1000
+@@ -122,7 +122,7 @@
+ @echo "Build complete."
+
+ .PHONY: build-rspy
+-build-rspy: pyenv buildhash
++build-rspy: buildhash
+ @set -eu -o pipefail ${SHELLFLAGS}; \
+ . "${ACTIVATE_SCRIPT}"; \
+ $(SUBMAKE) -C rspy build BUILDFLAGS="$(BUILDFLAGS)"
+--- Makefile 2020-05-19 19:41:44.191955000 +1000
++++ Makefile 2020-05-19 19:42:21.423952264 +1000
+@@ -124,19 +124,16 @@
+ .PHONY: build-rspy
+ build-rspy: buildhash
+ @set -eu -o pipefail ${SHELLFLAGS}; \
+- . "${ACTIVATE_SCRIPT}"; \
+ $(SUBMAKE) -C rspy build BUILDFLAGS="$(BUILDFLAGS)"
+
+ .PHONY: build-pylib
+ build-pylib:
+ @set -eu -o pipefail ${SHELLFLAGS}; \
+- . "${ACTIVATE_SCRIPT}"; \
+ $(SUBMAKE) -C pylib build
+
+ .PHONY: build-qt
+ build-qt:
+ @set -eu -o pipefail ${SHELLFLAGS}; \
+- . "${ACTIVATE_SCRIPT}"; \
+ $(SUBMAKE) -C qt build
+
+ .PHONY: clean
+--- rspy/Makefile 2020-05-21 20:06:35.945720983 +1000
++++ rspy/Makefile 2020-05-21 20:07:54.295720504 +1000
+@@ -86,10 +86,10 @@
+ RUST_TOOLCHAIN := $(shell cat rust-toolchain)
+
+ .build/tools: requirements.txt rust-toolchain
+- python -m pip install -r requirements.txt
+ rustup toolchain install $(RUST_TOOLCHAIN)
+ rustup component add rustfmt-preview --toolchain $(RUST_TOOLCHAIN)
+ rustup component add clippy-preview --toolchain $(RUST_TOOLCHAIN)
++ rustup target add $(RUST_TARGET)
+ @touch $@
+
+ # we should not call clippy because it break things when running make check Mac OS
+--- pylib/Makefile 2020-05-22 08:46:14.988607539 +1000
++++ pylib/Makefile 2020-05-22 08:46:38.376605821 +1000
+@@ -41,7 +41,7 @@
+
+ PROTODEPS := $(wildcard ../proto/*.proto)
+
+-.build/py-proto: .build/dev-deps $(PROTODEPS)
++.build/py-proto: $(PROTODEPS)
+ protoc --proto_path=../proto --python_out=anki --mypy_out=anki $(PROTODEPS)
+ perl -i'' -pe 's/from fluent_pb2/from anki.fluent_pb2/' anki/backend_pb2.pyi
+ perl -i'' -pe 's/import fluent_pb2/import anki.fluent_pb2/' anki/backend_pb2.py
diff --git a/srcpkgs/anki/template b/srcpkgs/anki/template
index 680e008a9d4..d900ec19ce2 100644
--- a/srcpkgs/anki/template
+++ b/srcpkgs/anki/template
@@ -1,10 +1,14 @@
# Template file for 'anki'
pkgname=anki
-version=2.1.15
-revision=2
-archs=noarch
+version=2.1.26
+revision=1
build_style=gnu-makefile
pycompile_dirs="/usr/share/anki/anki /usr/share/anki/aqt"
+# rustup: anki needs nightly ... :(
+hostmakedepends="git python3 rustup maturin which protobuf
+ mypy-protobuf-python python3-stringcase black python3-wheel
+ rsync nodejs python3-PyQt5-devel-tools gettext
+ qt5-translations"
depends="python3-PyQt5-webengine python3-requests python3-SQLAlchemy
python3-PyAudio python3-mpv python3-Markdown python3-send2trash
python3-BeautifulSoup4 python3-decorator python3-jsonschema"
@@ -13,11 +17,53 @@ maintainer="Steve Prybylski <sa.prybylx@gmail.com>"
license="AGPL-3.0-or-later"
homepage="https://apps.ankiweb.net"
changelog="https://apps.ankiweb.net/docs/changes.html"
-distfiles="https://apps.ankiweb.net/downloads/current/anki-${version}-source.tgz"
-checksum=5a53760164c77d619f55107a13099cffe620566a7f610b61b6c4b52487f3bb89
-
+distfiles="https://github.com/ankitects/anki/archive/${version}.tar.gz"
+checksum=f5a0c41f3eebe0e77de9d46f2a5cbbe20f7c3a4787f0f02e1d33f298428acbdf
python_version=3
+# When a non-clean masterdir is used, rust is often left over from a
+# previous rust-enabled build. Unfortunatly, xbps-src dosen't seem
+# to clean out rust -.- So, use /usr/rustup, to avoid this issue.
+export PATH=/usr/rustup/bin:${PATH}
+export LD_LIBRARY_PATH=/usr/rustup/lib:${LD_LIBRARY_PATH}
+export CARGO_HOME=/usr/rustup
+export RUSTUP_HOME=/usr/rustup
+
+pre_configure() {
+ # If do_clean didn't run last time, we are stuffed. Run do_clean now.
+ do_clean || true
+ printf "1\\n" | rustup-init
+}
+
+pre_build() {
+ mkdir -p dist
+ make prepare
+}
+
+do_build() {
+ RUSTFLAGS="-C target-feature=-crt-static" make build
+}
+
+do_install() {
+ pushd pylib
+ python3 setup.py install --prefix=/usr --root=${DESTDIR}
+ popd
+
+ pushd qt
+ python3 setup.py install --prefix=/usr --root=${DESTDIR}
+ popd
+
+ # Copied from arch's PKGBUILD
+ install -Dm755 qt/runanki "${DESTDIR}/usr/bin/anki"
+ install -Dm644 qt/anki.desktop "${DESTDIR}/usr/share/applications/anki.desktop"
+ install -Dm644 qt/anki.png "${DESTDIR}/usr/share/pixmaps/anki.png"
+}
+
post_install() {
vlicense LICENSE
}
+
+# Remove rustup
+do_clean() {
+ rm -rf /usr/rustup
+}
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PR PATCH] [Updated] WIP: anki: update to 2.1.26
2020-05-23 6:18 [PR PATCH] WIP: anki: update to 2.1.26 fosslinux
@ 2020-05-23 7:07 ` fosslinux
2020-05-24 5:37 ` fosslinux
` (11 subsequent siblings)
12 siblings, 0 replies; 14+ messages in thread
From: fosslinux @ 2020-05-23 7:07 UTC (permalink / raw)
To: ml
[-- Attachment #1: Type: text/plain, Size: 1570 bytes --]
There is an updated pull request by fosslinux against master on the void-packages repository
https://github.com/fosslinux/void-packages anki-2.1.26
https://github.com/void-linux/void-packages/pull/22219
WIP: anki: update to 2.1.26
This has a wide variety of changes as if you have heard my ranting in #xbps it has turned into a Bad Build System - there is rust (nightly!), nodejs, python, etc etc, no proper install target...
A few things to note:
- python3-mypy is updated as mypy-protobuf needs the new version, otherwise the build failed.
- maturin is some weird build system at the intersection of rust and python.
- mypy-protobuf-python is what anki uses for binding python and rust together, partly.
- mypy-protobuf-go is the go implementation of mypy-protobuf-python that I thought should be packaged anywway.
- python-stringcase is a new dependency.
- anki is an archd package (not nocross), because the rust code is obviously platform specific.
- anki uses rustup. This is because it and some of its dependencies require archd code (notably pyo3). This is unavoidable, afaict.
Still todo:
- [ ] Apply archlinux's aqt_build patch, which stops it from polluting /usr directly (:vomiting_face:)
- [ ] More extensive runtime testing. It opens, but seems to have weird icon issues?
- [ ] Runtime test on musl.
Questions:
- Is there any problems with removing `arch=nocross`?
- Does the rustup stuff look (somewhat) sane?
- Are the patches sane?
A patch file from https://github.com/void-linux/void-packages/pull/22219.patch is attached
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: github-pr-anki-2.1.26-22219.patch --]
[-- Type: text/x-diff, Size: 18460 bytes --]
From e88132a875c981abbac9216cce895b2b034d8ed0 Mon Sep 17 00:00:00 2001
From: fosslinux <fosslinux@aussies.space>
Date: Sat, 23 May 2020 14:33:01 +1000
Subject: [PATCH 1/6] python3-mypy: update to 0.770, claim maintainership
---
srcpkgs/python3-mypy/template | 7 +++----
1 file changed, 3 insertions(+), 4 deletions(-)
diff --git a/srcpkgs/python3-mypy/template b/srcpkgs/python3-mypy/template
index 5d7f93d5772..bde1e7f4be6 100644
--- a/srcpkgs/python3-mypy/template
+++ b/srcpkgs/python3-mypy/template
@@ -1,19 +1,18 @@
# Template file for 'python3-mypy'
pkgname=python3-mypy
-version=0.761
+version=0.770
revision=1
archs=noarch
wrksrc="mypy-${version}"
build_style=python3-module
-pycompile_module="mypy"
hostmakedepends="python3-setuptools"
depends="python3-mypy_extensions python3-typed-ast python3-typing_extensions"
short_desc="Optional static typing for Python3"
-maintainer="Orphaned <orphan@voidlinux.org>"
+maintainer="fosslinux <fosslinux@aussies.space>"
license="MIT"
homepage="https://github.com/python/mypy"
distfiles="${PYPI_SITE}/m/mypy/mypy-${version}.tar.gz"
-checksum=85baab8d74ec601e86134afe2bcccd87820f79d2f8d5798c889507d1088287bf
+checksum=8a627507ef9b307b46a1fea9513d5c98680ba09591253082b4c48697ba05a4ae
post_install() {
vlicense LICENSE
From ae580c7dcc5fa9ee6c2040b185773341a8fdda2b Mon Sep 17 00:00:00 2001
From: fosslinux <fosslinux@aussies.space>
Date: Sat, 23 May 2020 14:34:38 +1000
Subject: [PATCH 2/6] New package: maturin-0.8.1
---
.../patches/cross-compile-setup-py.patch | 14 +++++++++++++
srcpkgs/maturin/template | 21 +++++++++++++++++++
2 files changed, 35 insertions(+)
create mode 100644 srcpkgs/maturin/patches/cross-compile-setup-py.patch
create mode 100644 srcpkgs/maturin/template
diff --git a/srcpkgs/maturin/patches/cross-compile-setup-py.patch b/srcpkgs/maturin/patches/cross-compile-setup-py.patch
new file mode 100644
index 00000000000..e57189cb7ab
--- /dev/null
+++ b/srcpkgs/maturin/patches/cross-compile-setup-py.patch
@@ -0,0 +1,14 @@
+--- setup.py 2020-04-30 22:36:01.000000000 +1000
++++ setup.py 2020-05-20 14:31:40.404994499 +1000
+@@ -56,9 +56,9 @@
+ "(https://www.rust-lang.org/tools/install) and try again"
+ )
+ subprocess.check_call(
+- ["cargo", "rustc", "--bin", "maturin", "--", "-C", "link-arg=-s"]
++ ["cargo", "rustc", "--bin", "maturin", "--release", "--target", os.environ["RUST_TARGET"], "--", "-C", "link-arg=-s", "-C", "linker=" + os.environ["CC"].split(" ", 1)[0]]
+ )
+- source = os.path.join(source_dir, "target", "debug", executable_name)
++ source = os.path.join(source_dir, "target", os.environ["RUST_TARGET"], "release", executable_name)
+ # run this after trying to build with cargo (as otherwise this leaves
+ # venv in a bad state: https://github.com/benfred/py-spy/issues/69)
+ install.run(self)
diff --git a/srcpkgs/maturin/template b/srcpkgs/maturin/template
new file mode 100644
index 00000000000..7eba36204f9
--- /dev/null
+++ b/srcpkgs/maturin/template
@@ -0,0 +1,21 @@
+# Template file for 'maturin'
+pkgname=maturin
+version=0.8.1
+revision=1
+build_style=python3-module
+hostmakedepends="cargo python3-setuptools python3-toml"
+makedepends="rust rust-std llvm9"
+short_desc="Build and publish crates with python bindings"
+maintainer="fosslinux <fosslinux@aussies.space>"
+license="Apache-2.0, MIT"
+homepage="https://github.com/PyO3/maturin"
+distfiles="https://github.com/PyO3/maturin/archive/v${version}.tar.gz"
+checksum=b72a9885cda3ba4e53906a43aab101acb790622218ade6405b2ddf1ef1461f8f
+
+post_install() {
+ # Dynamic detection of python version
+ PYTHON_VERSION=$(python3 --version | sed "s/^Python //" | rev | sed "s/^[0-9]*.//" | rev)
+ mkdir -p "${DESTDIR}/usr/lib/python${PYTHON_VERSION}/site-packages/"
+ mv "${DESTDIR}/maturin" "${DESTDIR}/usr/lib/python${PYTHON_VERSION}/site-packages/"
+ vlicense license-mit
+}
From 1bd1177a01ea7ce37e08a382eed7597a764ae457 Mon Sep 17 00:00:00 2001
From: fosslinux <fosslinux@aussies.space>
Date: Sat, 23 May 2020 14:35:25 +1000
Subject: [PATCH 3/6] New package: mypy-protobuf-python-1.13
---
srcpkgs/mypy-protobuf-python/template | 23 +++++++++++++++++++++++
1 file changed, 23 insertions(+)
create mode 100644 srcpkgs/mypy-protobuf-python/template
diff --git a/srcpkgs/mypy-protobuf-python/template b/srcpkgs/mypy-protobuf-python/template
new file mode 100644
index 00000000000..391d75f0c9e
--- /dev/null
+++ b/srcpkgs/mypy-protobuf-python/template
@@ -0,0 +1,23 @@
+# Template file for 'mypy-protobuf-python'
+#
+# WARNING: THIS TEMPLATE SHOULD BE SYNCRONISED WITH mypy-protobuf-go
+#
+pkgname=mypy-protobuf-python
+version=1.13
+revision=1
+wrksrc="mypy-protobuf-${version}"
+build_wrksrc=python
+build_style=python3-module
+hostmakedepends="python3-setuptools"
+depends="python3-mypy python3-typing_extensions python3-protobuf protobuf"
+short_desc="Generate mypy stubs from protobufs - Python implementation"
+maintainer="fosslinux <fosslinux@aussies.space>"
+license="Apache-2.0"
+homepage="https://github.com/dropbox/mypy-protobuf"
+distfiles="https://github.com/dropbox/mypy-protobuf/archive/v${version}.tar.gz"
+checksum=7d86dfc076f8b51814fbfd3a66998a0b570fd1b82ebeda68ae6728cd538adb74
+
+post_install() {
+ # We are not windows, remove the batch file
+ rm "${DESTDIR}/usr/bin/protoc_gen_mypy.bat"
+}
From 2005df10d61b46933f28eea0b17e701a09af437b Mon Sep 17 00:00:00 2001
From: fosslinux <fosslinux@aussies.space>
Date: Sat, 23 May 2020 14:35:37 +1000
Subject: [PATCH 4/6] New package: mypy-protobuf-go-1.13
---
.../patches/remote-go-improt.patch | 11 +++++++++++
srcpkgs/mypy-protobuf-go/template | 19 +++++++++++++++++++
2 files changed, 30 insertions(+)
create mode 100644 srcpkgs/mypy-protobuf-go/patches/remote-go-improt.patch
create mode 100644 srcpkgs/mypy-protobuf-go/template
diff --git a/srcpkgs/mypy-protobuf-go/patches/remote-go-improt.patch b/srcpkgs/mypy-protobuf-go/patches/remote-go-improt.patch
new file mode 100644
index 00000000000..300504bc70d
--- /dev/null
+++ b/srcpkgs/mypy-protobuf-go/patches/remote-go-improt.patch
@@ -0,0 +1,11 @@
+--- go/src/protoc-gen-mypy/main.go.orig 2020-05-22 11:58:07.760761664 +1000
++++ go/src/protoc-gen-mypy/main.go 2020-05-22 11:58:00.595762190 +1000
+@@ -6,7 +6,7 @@
+ "sort"
+ "strings"
+
+- "proto/mypy"
++ "github.com/dropbox/mypy-protobuf/go/src/proto/mypy"
+
+ "github.com/gogo/protobuf/proto"
+ "github.com/gogo/protobuf/protoc-gen-gogo/descriptor"
diff --git a/srcpkgs/mypy-protobuf-go/template b/srcpkgs/mypy-protobuf-go/template
new file mode 100644
index 00000000000..8f00e43d8a8
--- /dev/null
+++ b/srcpkgs/mypy-protobuf-go/template
@@ -0,0 +1,19 @@
+# Template file for 'mypy-protobuf-go'
+#
+# WARNING: THIS TEMPLATE SHOULD BE SYNCRONISED WITH mypy-protobuf-python
+#
+pkgname=mypy-protobuf-go
+version=1.13
+revision=1
+wrksrc="mypy-protobuf-${version}"
+build_style=go
+go_import_path="github.com/dropbox/mypy-protobuf"
+go_package="${go_import_path}/go/src/protoc-gen-mypy"
+hostmakedepends="git"
+depends="protobuf"
+short_desc="Generate mypy stubs from protobufs - go implementation"
+maintainer="fosslinux <fosslinux@aussies.space>"
+license="Apache-2.0"
+homepage="https://github.com/dropbox/mypy-protobuf"
+distfiles="https://github.com/dropbox/mypy-protobuf/archive/v${version}.tar.gz"
+checksum=7d86dfc076f8b51814fbfd3a66998a0b570fd1b82ebeda68ae6728cd538adb74
From db650873d45635b6983c2d24717e827309303092 Mon Sep 17 00:00:00 2001
From: fosslinux <fosslinux@aussies.space>
Date: Sat, 23 May 2020 14:33:36 +1000
Subject: [PATCH 5/6] New package: python-stringcase-1.2.0
---
srcpkgs/python-stringcase/template | 28 ++++++++++++++++++++++++++++
srcpkgs/python3-stringcase | 1 +
2 files changed, 29 insertions(+)
create mode 100644 srcpkgs/python-stringcase/template
create mode 120000 srcpkgs/python3-stringcase
diff --git a/srcpkgs/python-stringcase/template b/srcpkgs/python-stringcase/template
new file mode 100644
index 00000000000..849e677c784
--- /dev/null
+++ b/srcpkgs/python-stringcase/template
@@ -0,0 +1,28 @@
+# Template file for 'python-stringcase'
+pkgname=python-stringcase
+version=1.2.0
+revision=1
+wrksrc="stringcase-${version}"
+build_style=python-module
+hostmakedepends="python-devel python3-devel"
+makedepends="${hostmakedepends}"
+depends="python"
+short_desc="String case converter for Python2"
+maintainer="fosslinux <fosslinux@aussies.space>"
+license="MIT"
+homepage="https://github.com/okunishinishi/python-stringcase"
+distfiles="${PYPI_SITE}/s/stringcase/stringcase-${version}.tar.gz"
+checksum=48a06980661908efe8d9d34eab2b6c13aefa2163b3ced26972902e3bdfd87008
+
+post_install() {
+ vlicense LICENSE
+}
+
+python3-stringcase_package() {
+ depends="python3"
+ short_desc="${short_desc/Python2/Python3}"
+ pkg_install() {
+ vmove usr/lib/python3*
+ vlicense LICENSE
+ }
+}
diff --git a/srcpkgs/python3-stringcase b/srcpkgs/python3-stringcase
new file mode 120000
index 00000000000..53938bd1f0c
--- /dev/null
+++ b/srcpkgs/python3-stringcase
@@ -0,0 +1 @@
+python-stringcase
\ No newline at end of file
From cb9978037d8ed6df1277d8c405978b9f9d9692cd Mon Sep 17 00:00:00 2001
From: fosslinux <fosslinux@aussies.space>
Date: Sat, 23 May 2020 14:36:21 +1000
Subject: [PATCH 6/6] anki: update to 2.1.26
Has turned into a Bad Build System. Now uses rust nightly, python
(with bindings!), qt5, nodejs... the list goes on. There are quite
a few hacks and the like.
---
srcpkgs/anki/patches/aqt_data-fhs.patch | 45 +++++++++
.../anki/patches/rustc-cross-compile.patch | 11 +++
srcpkgs/anki/patches/vendored-deps.patch | 94 +++++++++++++++++++
srcpkgs/anki/template | 58 ++++++++++--
4 files changed, 202 insertions(+), 6 deletions(-)
create mode 100644 srcpkgs/anki/patches/aqt_data-fhs.patch
create mode 100644 srcpkgs/anki/patches/rustc-cross-compile.patch
create mode 100644 srcpkgs/anki/patches/vendored-deps.patch
diff --git a/srcpkgs/anki/patches/aqt_data-fhs.patch b/srcpkgs/anki/patches/aqt_data-fhs.patch
new file mode 100644
index 00000000000..ac0d29ec082
--- /dev/null
+++ b/srcpkgs/anki/patches/aqt_data-fhs.patch
@@ -0,0 +1,45 @@
+From a0a9ac1aeb8b8678f1102aed81010a901ad8d9e1 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Johannes=20L=C3=B6thberg?= <johannes@kyriasis.com>
+Date: Sun, 29 Mar 2020 06:24:43 +0200
+Subject: [PATCH 1/4] Move aqt_data to sys.prefix/share
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+These files do _not_ belong right under sys.prefix.
+
+Signed-off-by: Johannes Löthberg <johannes@kyriasis.com>
+---
+ qt/aqt/utils.py | 2 +-
+ qt/setup.py | 2 +-
+ 2 files changed, 2 insertions(+), 2 deletions(-)
+
+diff --git qt/aqt/utils.py qt/aqt/utils.py
+index a0e12362..4d8c8c34 100644
+--- qt/aqt/utils.py
++++ qt/aqt/utils.py
+@@ -21,7 +21,7 @@ from aqt.theme import theme_manager
+
+ def aqt_data_folder() -> str:
+ # wheel install?
+- dir = os.path.join(sys.prefix, "aqt_data")
++ dir = os.path.join(sys.prefix,"share", "aqt_data")
+ if not os.path.exists(dir) or not os.listdir(dir):
+ # running in place?
+ dir = os.path.join(os.path.dirname(__file__), "..", "aqt_data")
+diff --git qt/setup.py qt/setup.py
+index 38f4e2b7..bdda3baa 100644
+--- qt/setup.py
++++ qt/setup.py
+@@ -8,7 +8,7 @@ import setuptools
+ def package_files(directory):
+ entries = []
+ for (path, directories, filenames) in os.walk(directory):
+- entries.append((path, [os.path.join(path, f) for f in filenames]))
++ entries.append((os.path.join("share", path), [os.path.join(path, f) for f in filenames]))
+ return entries
+
+
+--
+2.26.2
+
diff --git a/srcpkgs/anki/patches/rustc-cross-compile.patch b/srcpkgs/anki/patches/rustc-cross-compile.patch
new file mode 100644
index 00000000000..15239ea4cf1
--- /dev/null
+++ b/srcpkgs/anki/patches/rustc-cross-compile.patch
@@ -0,0 +1,11 @@
+--- rspy/Makefile 2020-05-23 12:02:29.758286838 +1000
++++ rspy/Makefile 2020-05-08 18:17:57.000000000 +1000
+@@ -69,7 +69,7 @@
+ .build/build: $(DEPS)
+ touch ../proto/backend.proto
+ ${BUILD_VARIABLES} \
+- maturin build -i "${PYTHON_FILE}" -o "$(OUTDIR)" $(BUILDFLAGS)
++ maturin build -i "${PYTHON_FILE}" -o "$(OUTDIR)" $(BUILDFLAGS) --target $(RUST_TARGET)
+ touch $@
+
+ check: .build/check
diff --git a/srcpkgs/anki/patches/vendored-deps.patch b/srcpkgs/anki/patches/vendored-deps.patch
new file mode 100644
index 00000000000..1d2bc90ffb1
--- /dev/null
+++ b/srcpkgs/anki/patches/vendored-deps.patch
@@ -0,0 +1,94 @@
+diff -u -r Makefile Makefile
+--- Makefile 2020-05-08 18:17:57.000000000 +1000
++++ Makefile 2020-05-19 18:40:54.345223164 +1000
+@@ -92,7 +92,7 @@
+ fi
+
+ .PHONY: develop
+-develop: pyenv buildhash prepare
++develop: buildhash prepare
+ @set -eu -o pipefail ${SHELLFLAGS}; \
+ . "${ACTIVATE_SCRIPT}"; \
+ for dir in $(DEVEL); do \
+diff -u -r pylib/Makefile pylib/Makefile
+--- pylib/Makefile 2020-05-08 18:17:57.000000000 +1000
++++ pylib/Makefile 2020-05-19 18:50:01.075182994 +1000
+@@ -52,7 +52,7 @@
+ python -m black anki/hooks.py
+ @touch $@
+
+-BUILD_STEPS := .build/vernum .build/run-deps .build/dev-deps .build/py-proto anki/buildinfo.py .build/hooks
++BUILD_STEPS := .build/vernum .build/py-proto anki/buildinfo.py .build/hooks
+
+ # Checking
+ ######################
+diff -u -r qt/Makefile qt/Makefile
+--- qt/Makefile 2020-05-08 18:17:57.000000000 +1000
++++ qt/Makefile 2020-05-19 18:50:17.520181786 +1000
+@@ -64,7 +64,7 @@
+ python -m black aqt/gui_hooks.py
+ @touch $@
+
+-BUILD_STEPS := .build/vernum .build/run-deps .build/dev-deps .build/js .build/ui aqt/buildinfo.py .build/hooks .build/i18n
++BUILD_STEPS := .build/vernum .build/js .build/ui aqt/buildinfo.py .build/hooks .build/i18n
+
+ # Checking
+ ######################
+--- Makefile 2020-05-08 18:17:57.000000000 +1000
++++ Makefile 2020-05-19 19:01:35.602131965 +1000
+@@ -122,7 +122,7 @@
+ @echo "Build complete."
+
+ .PHONY: build-rspy
+-build-rspy: pyenv buildhash
++build-rspy: buildhash
+ @set -eu -o pipefail ${SHELLFLAGS}; \
+ . "${ACTIVATE_SCRIPT}"; \
+ $(SUBMAKE) -C rspy build BUILDFLAGS="$(BUILDFLAGS)"
+--- Makefile 2020-05-19 19:41:44.191955000 +1000
++++ Makefile 2020-05-19 19:42:21.423952264 +1000
+@@ -124,19 +124,16 @@
+ .PHONY: build-rspy
+ build-rspy: buildhash
+ @set -eu -o pipefail ${SHELLFLAGS}; \
+- . "${ACTIVATE_SCRIPT}"; \
+ $(SUBMAKE) -C rspy build BUILDFLAGS="$(BUILDFLAGS)"
+
+ .PHONY: build-pylib
+ build-pylib:
+ @set -eu -o pipefail ${SHELLFLAGS}; \
+- . "${ACTIVATE_SCRIPT}"; \
+ $(SUBMAKE) -C pylib build
+
+ .PHONY: build-qt
+ build-qt:
+ @set -eu -o pipefail ${SHELLFLAGS}; \
+- . "${ACTIVATE_SCRIPT}"; \
+ $(SUBMAKE) -C qt build
+
+ .PHONY: clean
+--- rspy/Makefile 2020-05-21 20:06:35.945720983 +1000
++++ rspy/Makefile 2020-05-21 20:07:54.295720504 +1000
+@@ -86,10 +86,10 @@
+ RUST_TOOLCHAIN := $(shell cat rust-toolchain)
+
+ .build/tools: requirements.txt rust-toolchain
+- python -m pip install -r requirements.txt
+ rustup toolchain install $(RUST_TOOLCHAIN)
+ rustup component add rustfmt-preview --toolchain $(RUST_TOOLCHAIN)
+ rustup component add clippy-preview --toolchain $(RUST_TOOLCHAIN)
++ rustup target add $(RUST_TARGET)
+ @touch $@
+
+ # we should not call clippy because it break things when running make check Mac OS
+--- pylib/Makefile 2020-05-22 08:46:14.988607539 +1000
++++ pylib/Makefile 2020-05-22 08:46:38.376605821 +1000
+@@ -41,7 +41,7 @@
+
+ PROTODEPS := $(wildcard ../proto/*.proto)
+
+-.build/py-proto: .build/dev-deps $(PROTODEPS)
++.build/py-proto: $(PROTODEPS)
+ protoc --proto_path=../proto --python_out=anki --mypy_out=anki $(PROTODEPS)
+ perl -i'' -pe 's/from fluent_pb2/from anki.fluent_pb2/' anki/backend_pb2.pyi
+ perl -i'' -pe 's/import fluent_pb2/import anki.fluent_pb2/' anki/backend_pb2.py
diff --git a/srcpkgs/anki/template b/srcpkgs/anki/template
index 680e008a9d4..7e4e2dcf916 100644
--- a/srcpkgs/anki/template
+++ b/srcpkgs/anki/template
@@ -1,10 +1,14 @@
# Template file for 'anki'
pkgname=anki
-version=2.1.15
-revision=2
-archs=noarch
+version=2.1.26
+revision=1
build_style=gnu-makefile
pycompile_dirs="/usr/share/anki/anki /usr/share/anki/aqt"
+# rustup: anki needs nightly ... :(
+hostmakedepends="git python3 rustup maturin which protobuf
+ mypy-protobuf-python python3-stringcase black python3-wheel
+ rsync nodejs python3-PyQt5-devel-tools gettext
+ qt5-translations"
depends="python3-PyQt5-webengine python3-requests python3-SQLAlchemy
python3-PyAudio python3-mpv python3-Markdown python3-send2trash
python3-BeautifulSoup4 python3-decorator python3-jsonschema"
@@ -13,11 +17,53 @@ maintainer="Steve Prybylski <sa.prybylx@gmail.com>"
license="AGPL-3.0-or-later"
homepage="https://apps.ankiweb.net"
changelog="https://apps.ankiweb.net/docs/changes.html"
-distfiles="https://apps.ankiweb.net/downloads/current/anki-${version}-source.tgz"
-checksum=5a53760164c77d619f55107a13099cffe620566a7f610b61b6c4b52487f3bb89
-
+distfiles="https://github.com/ankitects/anki/archive/${version}.tar.gz"
+checksum=f5a0c41f3eebe0e77de9d46f2a5cbbe20f7c3a4787f0f02e1d33f298428acbdf
python_version=3
+# When a non-clean masterdir is used, rust is often left over from a
+# previous rust-enabled build. Unfortunatly, xbps-src dosen't seem
+# to clean out rust -.- So, use /usr/rustup, to avoid this issue.
+export PATH=/usr/rustup/bin:${PATH}
+export LD_LIBRARY_PATH=/usr/rustup/lib:${LD_LIBRARY_PATH}
+export CARGO_HOME=/usr/rustup
+export RUSTUP_HOME=/usr/rustup
+
+pre_configure() {
+ # If do_clean didn't run last time, we are stuffed. Run do_clean now.
+ do_clean || true
+ printf "1\\n" | rustup-init -y
+}
+
+pre_build() {
+ mkdir -p dist
+ make prepare
+}
+
+do_build() {
+ RUSTFLAGS="-C target-feature=-crt-static" make build
+}
+
+do_install() {
+ pushd pylib
+ python3 setup.py install --prefix=/usr --root=${DESTDIR}
+ popd
+
+ pushd qt
+ python3 setup.py install --prefix=/usr --root=${DESTDIR}
+ popd
+
+ # Copied from arch's PKGBUILD
+ install -Dm755 qt/runanki "${DESTDIR}/usr/bin/anki"
+ install -Dm644 qt/anki.desktop "${DESTDIR}/usr/share/applications/anki.desktop"
+ install -Dm644 qt/anki.png "${DESTDIR}/usr/share/pixmaps/anki.png"
+}
+
post_install() {
vlicense LICENSE
}
+
+# Remove rustup
+do_clean() {
+ rm -rf /usr/rustup
+}
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PR PATCH] [Updated] WIP: anki: update to 2.1.26
2020-05-23 6:18 [PR PATCH] WIP: anki: update to 2.1.26 fosslinux
2020-05-23 7:07 ` [PR PATCH] [Updated] " fosslinux
@ 2020-05-24 5:37 ` fosslinux
2020-05-24 5:39 ` fosslinux
` (10 subsequent siblings)
12 siblings, 0 replies; 14+ messages in thread
From: fosslinux @ 2020-05-24 5:37 UTC (permalink / raw)
To: ml
[-- Attachment #1: Type: text/plain, Size: 2045 bytes --]
There is an updated pull request by fosslinux against master on the void-packages repository
https://github.com/fosslinux/void-packages anki-2.1.26
https://github.com/void-linux/void-packages/pull/22219
WIP: anki: update to 2.1.26
This has a wide variety of changes as if you have heard my ranting in #xbps it has turned into a Bad Build System - there is rust (nightly!), nodejs, python, etc etc, no proper install target...
A few things to note:
- python3-mypy is updated as mypy-protobuf needs the new version, otherwise the build failed.
- maturin is some weird build system at the intersection of rust and python.
- mypy-protobuf-python is what anki uses for binding python and rust together, partly.
- mypy-protobuf-go is the go implementation of mypy-protobuf-python that I thought should be packaged anywway.
- python-stringcase is a new dependency.
- anki is an archd package (not nocross), because the rust code is obviously platform specific.
- anki uses rustup. This is because it and some of its dependencies require archd code (notably pyo3). This is unavoidable, afaict.
Still todo:
- [x] Apply archlinux's aqt_build patch, which stops it from polluting /usr directly (:vomiting_face:)
- [x] Update python3-protobuf - hopefully will fix `AttributeError: module 'google.protobuf.descriptor' has no attribute '_internal_create_key'`.
- [ ] Look into travis musl error. https://github.com/rust-lang/rust/issues/40174. Hopefully, using rust 1.44 as the rust version *should* fix this. What a PITA. I understand that this is because it works when I cross-compile to x86_64-musl from x86_64 but we need it to work native build from x86_64-musl for the builders...
- [ ] Travis wth on i686?
- [x] Make it open.
- [ ] More extensive runtime testing.
- [ ] Runtime test on musl.
Questions:
- Is there any problems with removing `arch=nocross`?
- Does the rustup stuff look (somewhat) sane?
- Are the patches sane?
A patch file from https://github.com/void-linux/void-packages/pull/22219.patch is attached
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: github-pr-anki-2.1.26-22219.patch --]
[-- Type: text/x-diff, Size: 20502 bytes --]
From 78816216511379aa1b82f106aeffe9266c10ca18 Mon Sep 17 00:00:00 2001
From: fosslinux <fosslinux@aussies.space>
Date: Sun, 24 May 2020 15:37:00 +1000
Subject: [PATCH 1/7] python-protobuf: update to 3.12.1
---
srcpkgs/python-protobuf/template | 13 ++++++-------
1 file changed, 6 insertions(+), 7 deletions(-)
diff --git a/srcpkgs/python-protobuf/template b/srcpkgs/python-protobuf/template
index 1a2d37a0a1e..a96fd539894 100644
--- a/srcpkgs/python-protobuf/template
+++ b/srcpkgs/python-protobuf/template
@@ -1,19 +1,19 @@
# Template file for 'python-protobuf'
pkgname=python-protobuf
-version=3.10.0
-revision=2
+version=3.12.1
+revision=1
archs=noarch
wrksrc="protobuf-${version}"
+build_wrksrc="python"
build_style=python-module
-pycompile_module="google/protobuf"
-hostmakedepends="python-setuptools python3-setuptools"
+hostmakedepends="python-setuptools python3-setuptools protobuf"
depends="python-setuptools python-six"
short_desc="Python2 bindings for Google Protocol Buffers"
maintainer="Charles E. Lehner <cel@celehner.com>"
license="BSD-3-Clause"
homepage="https://developers.google.com/protocol-buffers/"
-distfiles="${PYPI_SITE}/p/protobuf/protobuf-${version}.tar.gz"
-checksum=db83b5c12c0cd30150bb568e6feb2435c49ce4e68fe2d7b903113f0e221e58fe
+distfiles="https://github.com/protocolbuffers/protobuf/archive/v${version}.tar.gz"
+checksum=cb9b3f9d625b5739a358268eb3421de11cacd90025f5f7672c3930553eca810e
post_install() {
sed -n 1,29p google/protobuf/__init__.py >LICENSE
@@ -22,7 +22,6 @@ post_install() {
python3-protobuf_package() {
archs=noarch
- pycompile_module="google/protobuf"
depends="python3-setuptools python3-six"
short_desc="${short_desc/Python2/Python3}"
pkg_install() {
From 7712eb76d5743a2c0c3d75747bc3ea0f5f2e4e0b Mon Sep 17 00:00:00 2001
From: fosslinux <fosslinux@aussies.space>
Date: Sat, 23 May 2020 14:33:01 +1000
Subject: [PATCH 2/7] python3-mypy: update to 0.770, claim maintainership
---
srcpkgs/python3-mypy/template | 7 +++----
1 file changed, 3 insertions(+), 4 deletions(-)
diff --git a/srcpkgs/python3-mypy/template b/srcpkgs/python3-mypy/template
index 5d7f93d5772..bde1e7f4be6 100644
--- a/srcpkgs/python3-mypy/template
+++ b/srcpkgs/python3-mypy/template
@@ -1,19 +1,18 @@
# Template file for 'python3-mypy'
pkgname=python3-mypy
-version=0.761
+version=0.770
revision=1
archs=noarch
wrksrc="mypy-${version}"
build_style=python3-module
-pycompile_module="mypy"
hostmakedepends="python3-setuptools"
depends="python3-mypy_extensions python3-typed-ast python3-typing_extensions"
short_desc="Optional static typing for Python3"
-maintainer="Orphaned <orphan@voidlinux.org>"
+maintainer="fosslinux <fosslinux@aussies.space>"
license="MIT"
homepage="https://github.com/python/mypy"
distfiles="${PYPI_SITE}/m/mypy/mypy-${version}.tar.gz"
-checksum=85baab8d74ec601e86134afe2bcccd87820f79d2f8d5798c889507d1088287bf
+checksum=8a627507ef9b307b46a1fea9513d5c98680ba09591253082b4c48697ba05a4ae
post_install() {
vlicense LICENSE
From 6efdf584b76652d8f2df4ea2130474e3b1576340 Mon Sep 17 00:00:00 2001
From: fosslinux <fosslinux@aussies.space>
Date: Sat, 23 May 2020 14:34:38 +1000
Subject: [PATCH 3/7] New package: maturin-0.8.1
---
.../patches/cross-compile-setup-py.patch | 14 +++++++++++++
srcpkgs/maturin/template | 21 +++++++++++++++++++
2 files changed, 35 insertions(+)
create mode 100644 srcpkgs/maturin/patches/cross-compile-setup-py.patch
create mode 100644 srcpkgs/maturin/template
diff --git a/srcpkgs/maturin/patches/cross-compile-setup-py.patch b/srcpkgs/maturin/patches/cross-compile-setup-py.patch
new file mode 100644
index 00000000000..e57189cb7ab
--- /dev/null
+++ b/srcpkgs/maturin/patches/cross-compile-setup-py.patch
@@ -0,0 +1,14 @@
+--- setup.py 2020-04-30 22:36:01.000000000 +1000
++++ setup.py 2020-05-20 14:31:40.404994499 +1000
+@@ -56,9 +56,9 @@
+ "(https://www.rust-lang.org/tools/install) and try again"
+ )
+ subprocess.check_call(
+- ["cargo", "rustc", "--bin", "maturin", "--", "-C", "link-arg=-s"]
++ ["cargo", "rustc", "--bin", "maturin", "--release", "--target", os.environ["RUST_TARGET"], "--", "-C", "link-arg=-s", "-C", "linker=" + os.environ["CC"].split(" ", 1)[0]]
+ )
+- source = os.path.join(source_dir, "target", "debug", executable_name)
++ source = os.path.join(source_dir, "target", os.environ["RUST_TARGET"], "release", executable_name)
+ # run this after trying to build with cargo (as otherwise this leaves
+ # venv in a bad state: https://github.com/benfred/py-spy/issues/69)
+ install.run(self)
diff --git a/srcpkgs/maturin/template b/srcpkgs/maturin/template
new file mode 100644
index 00000000000..7eba36204f9
--- /dev/null
+++ b/srcpkgs/maturin/template
@@ -0,0 +1,21 @@
+# Template file for 'maturin'
+pkgname=maturin
+version=0.8.1
+revision=1
+build_style=python3-module
+hostmakedepends="cargo python3-setuptools python3-toml"
+makedepends="rust rust-std llvm9"
+short_desc="Build and publish crates with python bindings"
+maintainer="fosslinux <fosslinux@aussies.space>"
+license="Apache-2.0, MIT"
+homepage="https://github.com/PyO3/maturin"
+distfiles="https://github.com/PyO3/maturin/archive/v${version}.tar.gz"
+checksum=b72a9885cda3ba4e53906a43aab101acb790622218ade6405b2ddf1ef1461f8f
+
+post_install() {
+ # Dynamic detection of python version
+ PYTHON_VERSION=$(python3 --version | sed "s/^Python //" | rev | sed "s/^[0-9]*.//" | rev)
+ mkdir -p "${DESTDIR}/usr/lib/python${PYTHON_VERSION}/site-packages/"
+ mv "${DESTDIR}/maturin" "${DESTDIR}/usr/lib/python${PYTHON_VERSION}/site-packages/"
+ vlicense license-mit
+}
From bf0b313f13c558529acb46ef74b3841997b9d5d9 Mon Sep 17 00:00:00 2001
From: fosslinux <fosslinux@aussies.space>
Date: Sat, 23 May 2020 14:35:25 +1000
Subject: [PATCH 4/7] New package: mypy-protobuf-python-1.13
---
srcpkgs/mypy-protobuf-python/template | 23 +++++++++++++++++++++++
1 file changed, 23 insertions(+)
create mode 100644 srcpkgs/mypy-protobuf-python/template
diff --git a/srcpkgs/mypy-protobuf-python/template b/srcpkgs/mypy-protobuf-python/template
new file mode 100644
index 00000000000..391d75f0c9e
--- /dev/null
+++ b/srcpkgs/mypy-protobuf-python/template
@@ -0,0 +1,23 @@
+# Template file for 'mypy-protobuf-python'
+#
+# WARNING: THIS TEMPLATE SHOULD BE SYNCRONISED WITH mypy-protobuf-go
+#
+pkgname=mypy-protobuf-python
+version=1.13
+revision=1
+wrksrc="mypy-protobuf-${version}"
+build_wrksrc=python
+build_style=python3-module
+hostmakedepends="python3-setuptools"
+depends="python3-mypy python3-typing_extensions python3-protobuf protobuf"
+short_desc="Generate mypy stubs from protobufs - Python implementation"
+maintainer="fosslinux <fosslinux@aussies.space>"
+license="Apache-2.0"
+homepage="https://github.com/dropbox/mypy-protobuf"
+distfiles="https://github.com/dropbox/mypy-protobuf/archive/v${version}.tar.gz"
+checksum=7d86dfc076f8b51814fbfd3a66998a0b570fd1b82ebeda68ae6728cd538adb74
+
+post_install() {
+ # We are not windows, remove the batch file
+ rm "${DESTDIR}/usr/bin/protoc_gen_mypy.bat"
+}
From 0e9530bdee8b9d76ea8bfd4e50087eac4294e2af Mon Sep 17 00:00:00 2001
From: fosslinux <fosslinux@aussies.space>
Date: Sat, 23 May 2020 14:35:37 +1000
Subject: [PATCH 5/7] New package: mypy-protobuf-go-1.13
---
.../patches/remote-go-improt.patch | 11 +++++++++++
srcpkgs/mypy-protobuf-go/template | 19 +++++++++++++++++++
2 files changed, 30 insertions(+)
create mode 100644 srcpkgs/mypy-protobuf-go/patches/remote-go-improt.patch
create mode 100644 srcpkgs/mypy-protobuf-go/template
diff --git a/srcpkgs/mypy-protobuf-go/patches/remote-go-improt.patch b/srcpkgs/mypy-protobuf-go/patches/remote-go-improt.patch
new file mode 100644
index 00000000000..300504bc70d
--- /dev/null
+++ b/srcpkgs/mypy-protobuf-go/patches/remote-go-improt.patch
@@ -0,0 +1,11 @@
+--- go/src/protoc-gen-mypy/main.go.orig 2020-05-22 11:58:07.760761664 +1000
++++ go/src/protoc-gen-mypy/main.go 2020-05-22 11:58:00.595762190 +1000
+@@ -6,7 +6,7 @@
+ "sort"
+ "strings"
+
+- "proto/mypy"
++ "github.com/dropbox/mypy-protobuf/go/src/proto/mypy"
+
+ "github.com/gogo/protobuf/proto"
+ "github.com/gogo/protobuf/protoc-gen-gogo/descriptor"
diff --git a/srcpkgs/mypy-protobuf-go/template b/srcpkgs/mypy-protobuf-go/template
new file mode 100644
index 00000000000..8f00e43d8a8
--- /dev/null
+++ b/srcpkgs/mypy-protobuf-go/template
@@ -0,0 +1,19 @@
+# Template file for 'mypy-protobuf-go'
+#
+# WARNING: THIS TEMPLATE SHOULD BE SYNCRONISED WITH mypy-protobuf-python
+#
+pkgname=mypy-protobuf-go
+version=1.13
+revision=1
+wrksrc="mypy-protobuf-${version}"
+build_style=go
+go_import_path="github.com/dropbox/mypy-protobuf"
+go_package="${go_import_path}/go/src/protoc-gen-mypy"
+hostmakedepends="git"
+depends="protobuf"
+short_desc="Generate mypy stubs from protobufs - go implementation"
+maintainer="fosslinux <fosslinux@aussies.space>"
+license="Apache-2.0"
+homepage="https://github.com/dropbox/mypy-protobuf"
+distfiles="https://github.com/dropbox/mypy-protobuf/archive/v${version}.tar.gz"
+checksum=7d86dfc076f8b51814fbfd3a66998a0b570fd1b82ebeda68ae6728cd538adb74
From 7dbe4213090b5647b997d079f3a7823e15cfba0d Mon Sep 17 00:00:00 2001
From: fosslinux <fosslinux@aussies.space>
Date: Sat, 23 May 2020 14:33:36 +1000
Subject: [PATCH 6/7] New package: python-stringcase-1.2.0
---
srcpkgs/python-stringcase/template | 28 ++++++++++++++++++++++++++++
srcpkgs/python3-stringcase | 1 +
2 files changed, 29 insertions(+)
create mode 100644 srcpkgs/python-stringcase/template
create mode 120000 srcpkgs/python3-stringcase
diff --git a/srcpkgs/python-stringcase/template b/srcpkgs/python-stringcase/template
new file mode 100644
index 00000000000..849e677c784
--- /dev/null
+++ b/srcpkgs/python-stringcase/template
@@ -0,0 +1,28 @@
+# Template file for 'python-stringcase'
+pkgname=python-stringcase
+version=1.2.0
+revision=1
+wrksrc="stringcase-${version}"
+build_style=python-module
+hostmakedepends="python-devel python3-devel"
+makedepends="${hostmakedepends}"
+depends="python"
+short_desc="String case converter for Python2"
+maintainer="fosslinux <fosslinux@aussies.space>"
+license="MIT"
+homepage="https://github.com/okunishinishi/python-stringcase"
+distfiles="${PYPI_SITE}/s/stringcase/stringcase-${version}.tar.gz"
+checksum=48a06980661908efe8d9d34eab2b6c13aefa2163b3ced26972902e3bdfd87008
+
+post_install() {
+ vlicense LICENSE
+}
+
+python3-stringcase_package() {
+ depends="python3"
+ short_desc="${short_desc/Python2/Python3}"
+ pkg_install() {
+ vmove usr/lib/python3*
+ vlicense LICENSE
+ }
+}
diff --git a/srcpkgs/python3-stringcase b/srcpkgs/python3-stringcase
new file mode 120000
index 00000000000..53938bd1f0c
--- /dev/null
+++ b/srcpkgs/python3-stringcase
@@ -0,0 +1 @@
+python-stringcase
\ No newline at end of file
From 54e29ba6eac77f6e6ef6895ef1823c9595a3153a Mon Sep 17 00:00:00 2001
From: fosslinux <fosslinux@aussies.space>
Date: Sat, 23 May 2020 14:36:21 +1000
Subject: [PATCH 7/7] anki: update to 2.1.26
Has turned into a Bad Build System. Now uses rust nightly, python
(with bindings!), qt5, nodejs... the list goes on. There are quite
a few hacks and the like.
---
srcpkgs/anki/patches/aqt_data-fhs.patch | 45 +++++++++
.../anki/patches/rustc-cross-compile.patch | 11 +++
srcpkgs/anki/patches/vendored-deps.patch | 94 +++++++++++++++++++
srcpkgs/anki/template | 64 +++++++++++--
4 files changed, 207 insertions(+), 7 deletions(-)
create mode 100644 srcpkgs/anki/patches/aqt_data-fhs.patch
create mode 100644 srcpkgs/anki/patches/rustc-cross-compile.patch
create mode 100644 srcpkgs/anki/patches/vendored-deps.patch
diff --git a/srcpkgs/anki/patches/aqt_data-fhs.patch b/srcpkgs/anki/patches/aqt_data-fhs.patch
new file mode 100644
index 00000000000..ac0d29ec082
--- /dev/null
+++ b/srcpkgs/anki/patches/aqt_data-fhs.patch
@@ -0,0 +1,45 @@
+From a0a9ac1aeb8b8678f1102aed81010a901ad8d9e1 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Johannes=20L=C3=B6thberg?= <johannes@kyriasis.com>
+Date: Sun, 29 Mar 2020 06:24:43 +0200
+Subject: [PATCH 1/4] Move aqt_data to sys.prefix/share
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+These files do _not_ belong right under sys.prefix.
+
+Signed-off-by: Johannes Löthberg <johannes@kyriasis.com>
+---
+ qt/aqt/utils.py | 2 +-
+ qt/setup.py | 2 +-
+ 2 files changed, 2 insertions(+), 2 deletions(-)
+
+diff --git qt/aqt/utils.py qt/aqt/utils.py
+index a0e12362..4d8c8c34 100644
+--- qt/aqt/utils.py
++++ qt/aqt/utils.py
+@@ -21,7 +21,7 @@ from aqt.theme import theme_manager
+
+ def aqt_data_folder() -> str:
+ # wheel install?
+- dir = os.path.join(sys.prefix, "aqt_data")
++ dir = os.path.join(sys.prefix,"share", "aqt_data")
+ if not os.path.exists(dir) or not os.listdir(dir):
+ # running in place?
+ dir = os.path.join(os.path.dirname(__file__), "..", "aqt_data")
+diff --git qt/setup.py qt/setup.py
+index 38f4e2b7..bdda3baa 100644
+--- qt/setup.py
++++ qt/setup.py
+@@ -8,7 +8,7 @@ import setuptools
+ def package_files(directory):
+ entries = []
+ for (path, directories, filenames) in os.walk(directory):
+- entries.append((path, [os.path.join(path, f) for f in filenames]))
++ entries.append((os.path.join("share", path), [os.path.join(path, f) for f in filenames]))
+ return entries
+
+
+--
+2.26.2
+
diff --git a/srcpkgs/anki/patches/rustc-cross-compile.patch b/srcpkgs/anki/patches/rustc-cross-compile.patch
new file mode 100644
index 00000000000..15239ea4cf1
--- /dev/null
+++ b/srcpkgs/anki/patches/rustc-cross-compile.patch
@@ -0,0 +1,11 @@
+--- rspy/Makefile 2020-05-23 12:02:29.758286838 +1000
++++ rspy/Makefile 2020-05-08 18:17:57.000000000 +1000
+@@ -69,7 +69,7 @@
+ .build/build: $(DEPS)
+ touch ../proto/backend.proto
+ ${BUILD_VARIABLES} \
+- maturin build -i "${PYTHON_FILE}" -o "$(OUTDIR)" $(BUILDFLAGS)
++ maturin build -i "${PYTHON_FILE}" -o "$(OUTDIR)" $(BUILDFLAGS) --target $(RUST_TARGET)
+ touch $@
+
+ check: .build/check
diff --git a/srcpkgs/anki/patches/vendored-deps.patch b/srcpkgs/anki/patches/vendored-deps.patch
new file mode 100644
index 00000000000..1d2bc90ffb1
--- /dev/null
+++ b/srcpkgs/anki/patches/vendored-deps.patch
@@ -0,0 +1,94 @@
+diff -u -r Makefile Makefile
+--- Makefile 2020-05-08 18:17:57.000000000 +1000
++++ Makefile 2020-05-19 18:40:54.345223164 +1000
+@@ -92,7 +92,7 @@
+ fi
+
+ .PHONY: develop
+-develop: pyenv buildhash prepare
++develop: buildhash prepare
+ @set -eu -o pipefail ${SHELLFLAGS}; \
+ . "${ACTIVATE_SCRIPT}"; \
+ for dir in $(DEVEL); do \
+diff -u -r pylib/Makefile pylib/Makefile
+--- pylib/Makefile 2020-05-08 18:17:57.000000000 +1000
++++ pylib/Makefile 2020-05-19 18:50:01.075182994 +1000
+@@ -52,7 +52,7 @@
+ python -m black anki/hooks.py
+ @touch $@
+
+-BUILD_STEPS := .build/vernum .build/run-deps .build/dev-deps .build/py-proto anki/buildinfo.py .build/hooks
++BUILD_STEPS := .build/vernum .build/py-proto anki/buildinfo.py .build/hooks
+
+ # Checking
+ ######################
+diff -u -r qt/Makefile qt/Makefile
+--- qt/Makefile 2020-05-08 18:17:57.000000000 +1000
++++ qt/Makefile 2020-05-19 18:50:17.520181786 +1000
+@@ -64,7 +64,7 @@
+ python -m black aqt/gui_hooks.py
+ @touch $@
+
+-BUILD_STEPS := .build/vernum .build/run-deps .build/dev-deps .build/js .build/ui aqt/buildinfo.py .build/hooks .build/i18n
++BUILD_STEPS := .build/vernum .build/js .build/ui aqt/buildinfo.py .build/hooks .build/i18n
+
+ # Checking
+ ######################
+--- Makefile 2020-05-08 18:17:57.000000000 +1000
++++ Makefile 2020-05-19 19:01:35.602131965 +1000
+@@ -122,7 +122,7 @@
+ @echo "Build complete."
+
+ .PHONY: build-rspy
+-build-rspy: pyenv buildhash
++build-rspy: buildhash
+ @set -eu -o pipefail ${SHELLFLAGS}; \
+ . "${ACTIVATE_SCRIPT}"; \
+ $(SUBMAKE) -C rspy build BUILDFLAGS="$(BUILDFLAGS)"
+--- Makefile 2020-05-19 19:41:44.191955000 +1000
++++ Makefile 2020-05-19 19:42:21.423952264 +1000
+@@ -124,19 +124,16 @@
+ .PHONY: build-rspy
+ build-rspy: buildhash
+ @set -eu -o pipefail ${SHELLFLAGS}; \
+- . "${ACTIVATE_SCRIPT}"; \
+ $(SUBMAKE) -C rspy build BUILDFLAGS="$(BUILDFLAGS)"
+
+ .PHONY: build-pylib
+ build-pylib:
+ @set -eu -o pipefail ${SHELLFLAGS}; \
+- . "${ACTIVATE_SCRIPT}"; \
+ $(SUBMAKE) -C pylib build
+
+ .PHONY: build-qt
+ build-qt:
+ @set -eu -o pipefail ${SHELLFLAGS}; \
+- . "${ACTIVATE_SCRIPT}"; \
+ $(SUBMAKE) -C qt build
+
+ .PHONY: clean
+--- rspy/Makefile 2020-05-21 20:06:35.945720983 +1000
++++ rspy/Makefile 2020-05-21 20:07:54.295720504 +1000
+@@ -86,10 +86,10 @@
+ RUST_TOOLCHAIN := $(shell cat rust-toolchain)
+
+ .build/tools: requirements.txt rust-toolchain
+- python -m pip install -r requirements.txt
+ rustup toolchain install $(RUST_TOOLCHAIN)
+ rustup component add rustfmt-preview --toolchain $(RUST_TOOLCHAIN)
+ rustup component add clippy-preview --toolchain $(RUST_TOOLCHAIN)
++ rustup target add $(RUST_TARGET)
+ @touch $@
+
+ # we should not call clippy because it break things when running make check Mac OS
+--- pylib/Makefile 2020-05-22 08:46:14.988607539 +1000
++++ pylib/Makefile 2020-05-22 08:46:38.376605821 +1000
+@@ -41,7 +41,7 @@
+
+ PROTODEPS := $(wildcard ../proto/*.proto)
+
+-.build/py-proto: .build/dev-deps $(PROTODEPS)
++.build/py-proto: $(PROTODEPS)
+ protoc --proto_path=../proto --python_out=anki --mypy_out=anki $(PROTODEPS)
+ perl -i'' -pe 's/from fluent_pb2/from anki.fluent_pb2/' anki/backend_pb2.pyi
+ perl -i'' -pe 's/import fluent_pb2/import anki.fluent_pb2/' anki/backend_pb2.py
diff --git a/srcpkgs/anki/template b/srcpkgs/anki/template
index 680e008a9d4..89e28d11b05 100644
--- a/srcpkgs/anki/template
+++ b/srcpkgs/anki/template
@@ -1,23 +1,73 @@
# Template file for 'anki'
pkgname=anki
-version=2.1.15
-revision=2
-archs=noarch
+version=2.1.26
+revision=1
build_style=gnu-makefile
pycompile_dirs="/usr/share/anki/anki /usr/share/anki/aqt"
+# rustup: anki needs nightly ... :(
+hostmakedepends="git python3 rustup maturin which protobuf
+ mypy-protobuf-python python3-stringcase black python3-wheel
+ rsync nodejs python3-PyQt5-devel-tools gettext
+ qt5-translations python3-pip"
depends="python3-PyQt5-webengine python3-requests python3-SQLAlchemy
python3-PyAudio python3-mpv python3-Markdown python3-send2trash
- python3-BeautifulSoup4 python3-decorator python3-jsonschema"
+ python3-BeautifulSoup4 python3-decorator python3-jsonschema
+ python3-protobuf"
short_desc="Spaced repetition flashcard program"
maintainer="Steve Prybylski <sa.prybylx@gmail.com>"
license="AGPL-3.0-or-later"
homepage="https://apps.ankiweb.net"
changelog="https://apps.ankiweb.net/docs/changes.html"
-distfiles="https://apps.ankiweb.net/downloads/current/anki-${version}-source.tgz"
-checksum=5a53760164c77d619f55107a13099cffe620566a7f610b61b6c4b52487f3bb89
-
+distfiles="https://github.com/ankitects/anki/archive/${version}.tar.gz"
+checksum=f5a0c41f3eebe0e77de9d46f2a5cbbe20f7c3a4787f0f02e1d33f298428acbdf
python_version=3
+# When a non-clean masterdir is used, rust is often left over from a
+# previous rust-enabled build. Unfortunatly, xbps-src dosen't seem
+# to clean out rust -.- So, use /usr/rustup, to avoid this issue.
+export PATH=/usr/rustup/bin:${PATH}
+export LD_LIBRARY_PATH=/usr/rustup/lib:${LD_LIBRARY_PATH}
+export CARGO_HOME=/usr/rustup
+export RUSTUP_HOME=/usr/rustup
+
+pre_configure() {
+ # If do_clean didn't run last time, we are stuffed. Run do_clean now.
+ do_clean || true
+ printf "1\\n" | rustup-init -y
+}
+
+pre_build() {
+ mkdir -p dist
+ make prepare
+}
+
+do_build() {
+ RUSTFLAGS="-C target-feature=-crt-static" make build
+}
+
+do_install() {
+ pushd pylib
+ python3 setup.py install --prefix=/usr --root=${DESTDIR}
+ popd
+
+ pushd qt
+ python3 setup.py install --prefix=/usr --root=${DESTDIR}
+ popd
+
+ # maturin generates a .whl, this is all we can do
+ PIP_CONFIG_FILE=/dev/null pip3 install --isolated --root=${DESTDIR} --prefix=/usr --ignore-installed --no-deps dist/ankirspy*.whl
+
+ # Copied from arch's PKGBUILD
+ install -Dm755 qt/runanki "${DESTDIR}/usr/bin/anki"
+ install -Dm644 qt/anki.desktop "${DESTDIR}/usr/share/applications/anki.desktop"
+ install -Dm644 qt/anki.png "${DESTDIR}/usr/share/pixmaps/anki.png"
+}
+
post_install() {
vlicense LICENSE
}
+
+# Remove rustup
+do_clean() {
+ rm -rf /usr/rustup
+}
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: WIP: anki: update to 2.1.26
2020-05-23 6:18 [PR PATCH] WIP: anki: update to 2.1.26 fosslinux
2020-05-23 7:07 ` [PR PATCH] [Updated] " fosslinux
2020-05-24 5:37 ` fosslinux
@ 2020-05-24 5:39 ` fosslinux
2020-05-28 7:38 ` [PR PATCH] [Updated] " fosslinux
` (9 subsequent siblings)
12 siblings, 0 replies; 14+ messages in thread
From: fosslinux @ 2020-05-24 5:39 UTC (permalink / raw)
To: ml
[-- Attachment #1: Type: text/plain, Size: 374 bytes --]
New comment by fosslinux on void-packages repository
https://github.com/void-linux/void-packages/pull/22219#issuecomment-633182822
Comment:
I have been using this for the past few hours, it now runs. Don't know if musl will work this time, if it dosen't I'll need to go through nightlys into I find one that builds, one of the crates doesn't build for the newest nightly.
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PR PATCH] [Updated] WIP: anki: update to 2.1.26
2020-05-23 6:18 [PR PATCH] WIP: anki: update to 2.1.26 fosslinux
` (2 preceding siblings ...)
2020-05-24 5:39 ` fosslinux
@ 2020-05-28 7:38 ` fosslinux
2020-05-30 1:53 ` fosslinux
` (8 subsequent siblings)
12 siblings, 0 replies; 14+ messages in thread
From: fosslinux @ 2020-05-28 7:38 UTC (permalink / raw)
To: ml
[-- Attachment #1: Type: text/plain, Size: 2109 bytes --]
There is an updated pull request by fosslinux against master on the void-packages repository
https://github.com/fosslinux/void-packages anki-2.1.26
https://github.com/void-linux/void-packages/pull/22219
WIP: anki: update to 2.1.26
This has a wide variety of changes as if you have heard my ranting in #xbps it has turned into a Bad Build System - there is rust (nightly!), nodejs, python, etc etc, no proper install target...
A few things to note:
- python3-mypy is updated as mypy-protobuf needs the new version, otherwise the build failed.
- same thing with python-protobuf, but for anki and at runtime
- maturin is some weird build system at the intersection of rust and python.
- mypy-protobuf-python is what anki uses for binding python and rust together, partly.
- mypy-protobuf-go is the go implementation of mypy-protobuf-python that I thought should be packaged anywway.
- python-stringcase is a new dependency.
- anki is an archd package (not nocross), because the rust code is obviously platform specific.
- anki uses rustup. This is because it and some of its dependencies require archd code (notably pyo3). This is unavoidable, afaict.
Still todo:
- [x] Apply archlinux's aqt_build patch, which stops it from polluting /usr directly (:vomiting_face:)
- [x] Update python3-protobuf - hopefully will fix `AttributeError: module 'google.protobuf.descriptor' has no attribute '_internal_create_key'`.
- [ ] Look into travis musl error. https://github.com/rust-lang/rust/issues/40174. Hopefully, using rust 1.44 as the rust version *should* fix this. What a PITA. I understand that this is because it works when I cross-compile to x86_64-musl from x86_64 but we need it to work native build from x86_64-musl for the builders...
- [ ] Travis wth on i686?
- [x] Make it open.
- [ ] More extensive runtime testing.
- [ ] Runtime test on musl.
Questions:
- Is there any problems with removing `arch=nocross`?
- Does the rustup stuff look (somewhat) sane?
- Are the patches sane?
A patch file from https://github.com/void-linux/void-packages/pull/22219.patch is attached
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: github-pr-anki-2.1.26-22219.patch --]
[-- Type: text/x-diff, Size: 31841 bytes --]
From 78816216511379aa1b82f106aeffe9266c10ca18 Mon Sep 17 00:00:00 2001
From: fosslinux <fosslinux@aussies.space>
Date: Sun, 24 May 2020 15:37:00 +1000
Subject: [PATCH 1/7] python-protobuf: update to 3.12.1
---
srcpkgs/python-protobuf/template | 13 ++++++-------
1 file changed, 6 insertions(+), 7 deletions(-)
diff --git a/srcpkgs/python-protobuf/template b/srcpkgs/python-protobuf/template
index 1a2d37a0a1e..a96fd539894 100644
--- a/srcpkgs/python-protobuf/template
+++ b/srcpkgs/python-protobuf/template
@@ -1,19 +1,19 @@
# Template file for 'python-protobuf'
pkgname=python-protobuf
-version=3.10.0
-revision=2
+version=3.12.1
+revision=1
archs=noarch
wrksrc="protobuf-${version}"
+build_wrksrc="python"
build_style=python-module
-pycompile_module="google/protobuf"
-hostmakedepends="python-setuptools python3-setuptools"
+hostmakedepends="python-setuptools python3-setuptools protobuf"
depends="python-setuptools python-six"
short_desc="Python2 bindings for Google Protocol Buffers"
maintainer="Charles E. Lehner <cel@celehner.com>"
license="BSD-3-Clause"
homepage="https://developers.google.com/protocol-buffers/"
-distfiles="${PYPI_SITE}/p/protobuf/protobuf-${version}.tar.gz"
-checksum=db83b5c12c0cd30150bb568e6feb2435c49ce4e68fe2d7b903113f0e221e58fe
+distfiles="https://github.com/protocolbuffers/protobuf/archive/v${version}.tar.gz"
+checksum=cb9b3f9d625b5739a358268eb3421de11cacd90025f5f7672c3930553eca810e
post_install() {
sed -n 1,29p google/protobuf/__init__.py >LICENSE
@@ -22,7 +22,6 @@ post_install() {
python3-protobuf_package() {
archs=noarch
- pycompile_module="google/protobuf"
depends="python3-setuptools python3-six"
short_desc="${short_desc/Python2/Python3}"
pkg_install() {
From 7712eb76d5743a2c0c3d75747bc3ea0f5f2e4e0b Mon Sep 17 00:00:00 2001
From: fosslinux <fosslinux@aussies.space>
Date: Sat, 23 May 2020 14:33:01 +1000
Subject: [PATCH 2/7] python3-mypy: update to 0.770, claim maintainership
---
srcpkgs/python3-mypy/template | 7 +++----
1 file changed, 3 insertions(+), 4 deletions(-)
diff --git a/srcpkgs/python3-mypy/template b/srcpkgs/python3-mypy/template
index 5d7f93d5772..bde1e7f4be6 100644
--- a/srcpkgs/python3-mypy/template
+++ b/srcpkgs/python3-mypy/template
@@ -1,19 +1,18 @@
# Template file for 'python3-mypy'
pkgname=python3-mypy
-version=0.761
+version=0.770
revision=1
archs=noarch
wrksrc="mypy-${version}"
build_style=python3-module
-pycompile_module="mypy"
hostmakedepends="python3-setuptools"
depends="python3-mypy_extensions python3-typed-ast python3-typing_extensions"
short_desc="Optional static typing for Python3"
-maintainer="Orphaned <orphan@voidlinux.org>"
+maintainer="fosslinux <fosslinux@aussies.space>"
license="MIT"
homepage="https://github.com/python/mypy"
distfiles="${PYPI_SITE}/m/mypy/mypy-${version}.tar.gz"
-checksum=85baab8d74ec601e86134afe2bcccd87820f79d2f8d5798c889507d1088287bf
+checksum=8a627507ef9b307b46a1fea9513d5c98680ba09591253082b4c48697ba05a4ae
post_install() {
vlicense LICENSE
From 6efdf584b76652d8f2df4ea2130474e3b1576340 Mon Sep 17 00:00:00 2001
From: fosslinux <fosslinux@aussies.space>
Date: Sat, 23 May 2020 14:34:38 +1000
Subject: [PATCH 3/7] New package: maturin-0.8.1
---
.../patches/cross-compile-setup-py.patch | 14 +++++++++++++
srcpkgs/maturin/template | 21 +++++++++++++++++++
2 files changed, 35 insertions(+)
create mode 100644 srcpkgs/maturin/patches/cross-compile-setup-py.patch
create mode 100644 srcpkgs/maturin/template
diff --git a/srcpkgs/maturin/patches/cross-compile-setup-py.patch b/srcpkgs/maturin/patches/cross-compile-setup-py.patch
new file mode 100644
index 00000000000..e57189cb7ab
--- /dev/null
+++ b/srcpkgs/maturin/patches/cross-compile-setup-py.patch
@@ -0,0 +1,14 @@
+--- setup.py 2020-04-30 22:36:01.000000000 +1000
++++ setup.py 2020-05-20 14:31:40.404994499 +1000
+@@ -56,9 +56,9 @@
+ "(https://www.rust-lang.org/tools/install) and try again"
+ )
+ subprocess.check_call(
+- ["cargo", "rustc", "--bin", "maturin", "--", "-C", "link-arg=-s"]
++ ["cargo", "rustc", "--bin", "maturin", "--release", "--target", os.environ["RUST_TARGET"], "--", "-C", "link-arg=-s", "-C", "linker=" + os.environ["CC"].split(" ", 1)[0]]
+ )
+- source = os.path.join(source_dir, "target", "debug", executable_name)
++ source = os.path.join(source_dir, "target", os.environ["RUST_TARGET"], "release", executable_name)
+ # run this after trying to build with cargo (as otherwise this leaves
+ # venv in a bad state: https://github.com/benfred/py-spy/issues/69)
+ install.run(self)
diff --git a/srcpkgs/maturin/template b/srcpkgs/maturin/template
new file mode 100644
index 00000000000..7eba36204f9
--- /dev/null
+++ b/srcpkgs/maturin/template
@@ -0,0 +1,21 @@
+# Template file for 'maturin'
+pkgname=maturin
+version=0.8.1
+revision=1
+build_style=python3-module
+hostmakedepends="cargo python3-setuptools python3-toml"
+makedepends="rust rust-std llvm9"
+short_desc="Build and publish crates with python bindings"
+maintainer="fosslinux <fosslinux@aussies.space>"
+license="Apache-2.0, MIT"
+homepage="https://github.com/PyO3/maturin"
+distfiles="https://github.com/PyO3/maturin/archive/v${version}.tar.gz"
+checksum=b72a9885cda3ba4e53906a43aab101acb790622218ade6405b2ddf1ef1461f8f
+
+post_install() {
+ # Dynamic detection of python version
+ PYTHON_VERSION=$(python3 --version | sed "s/^Python //" | rev | sed "s/^[0-9]*.//" | rev)
+ mkdir -p "${DESTDIR}/usr/lib/python${PYTHON_VERSION}/site-packages/"
+ mv "${DESTDIR}/maturin" "${DESTDIR}/usr/lib/python${PYTHON_VERSION}/site-packages/"
+ vlicense license-mit
+}
From bf0b313f13c558529acb46ef74b3841997b9d5d9 Mon Sep 17 00:00:00 2001
From: fosslinux <fosslinux@aussies.space>
Date: Sat, 23 May 2020 14:35:25 +1000
Subject: [PATCH 4/7] New package: mypy-protobuf-python-1.13
---
srcpkgs/mypy-protobuf-python/template | 23 +++++++++++++++++++++++
1 file changed, 23 insertions(+)
create mode 100644 srcpkgs/mypy-protobuf-python/template
diff --git a/srcpkgs/mypy-protobuf-python/template b/srcpkgs/mypy-protobuf-python/template
new file mode 100644
index 00000000000..391d75f0c9e
--- /dev/null
+++ b/srcpkgs/mypy-protobuf-python/template
@@ -0,0 +1,23 @@
+# Template file for 'mypy-protobuf-python'
+#
+# WARNING: THIS TEMPLATE SHOULD BE SYNCRONISED WITH mypy-protobuf-go
+#
+pkgname=mypy-protobuf-python
+version=1.13
+revision=1
+wrksrc="mypy-protobuf-${version}"
+build_wrksrc=python
+build_style=python3-module
+hostmakedepends="python3-setuptools"
+depends="python3-mypy python3-typing_extensions python3-protobuf protobuf"
+short_desc="Generate mypy stubs from protobufs - Python implementation"
+maintainer="fosslinux <fosslinux@aussies.space>"
+license="Apache-2.0"
+homepage="https://github.com/dropbox/mypy-protobuf"
+distfiles="https://github.com/dropbox/mypy-protobuf/archive/v${version}.tar.gz"
+checksum=7d86dfc076f8b51814fbfd3a66998a0b570fd1b82ebeda68ae6728cd538adb74
+
+post_install() {
+ # We are not windows, remove the batch file
+ rm "${DESTDIR}/usr/bin/protoc_gen_mypy.bat"
+}
From 0e9530bdee8b9d76ea8bfd4e50087eac4294e2af Mon Sep 17 00:00:00 2001
From: fosslinux <fosslinux@aussies.space>
Date: Sat, 23 May 2020 14:35:37 +1000
Subject: [PATCH 5/7] New package: mypy-protobuf-go-1.13
---
.../patches/remote-go-improt.patch | 11 +++++++++++
srcpkgs/mypy-protobuf-go/template | 19 +++++++++++++++++++
2 files changed, 30 insertions(+)
create mode 100644 srcpkgs/mypy-protobuf-go/patches/remote-go-improt.patch
create mode 100644 srcpkgs/mypy-protobuf-go/template
diff --git a/srcpkgs/mypy-protobuf-go/patches/remote-go-improt.patch b/srcpkgs/mypy-protobuf-go/patches/remote-go-improt.patch
new file mode 100644
index 00000000000..300504bc70d
--- /dev/null
+++ b/srcpkgs/mypy-protobuf-go/patches/remote-go-improt.patch
@@ -0,0 +1,11 @@
+--- go/src/protoc-gen-mypy/main.go.orig 2020-05-22 11:58:07.760761664 +1000
++++ go/src/protoc-gen-mypy/main.go 2020-05-22 11:58:00.595762190 +1000
+@@ -6,7 +6,7 @@
+ "sort"
+ "strings"
+
+- "proto/mypy"
++ "github.com/dropbox/mypy-protobuf/go/src/proto/mypy"
+
+ "github.com/gogo/protobuf/proto"
+ "github.com/gogo/protobuf/protoc-gen-gogo/descriptor"
diff --git a/srcpkgs/mypy-protobuf-go/template b/srcpkgs/mypy-protobuf-go/template
new file mode 100644
index 00000000000..8f00e43d8a8
--- /dev/null
+++ b/srcpkgs/mypy-protobuf-go/template
@@ -0,0 +1,19 @@
+# Template file for 'mypy-protobuf-go'
+#
+# WARNING: THIS TEMPLATE SHOULD BE SYNCRONISED WITH mypy-protobuf-python
+#
+pkgname=mypy-protobuf-go
+version=1.13
+revision=1
+wrksrc="mypy-protobuf-${version}"
+build_style=go
+go_import_path="github.com/dropbox/mypy-protobuf"
+go_package="${go_import_path}/go/src/protoc-gen-mypy"
+hostmakedepends="git"
+depends="protobuf"
+short_desc="Generate mypy stubs from protobufs - go implementation"
+maintainer="fosslinux <fosslinux@aussies.space>"
+license="Apache-2.0"
+homepage="https://github.com/dropbox/mypy-protobuf"
+distfiles="https://github.com/dropbox/mypy-protobuf/archive/v${version}.tar.gz"
+checksum=7d86dfc076f8b51814fbfd3a66998a0b570fd1b82ebeda68ae6728cd538adb74
From 7dbe4213090b5647b997d079f3a7823e15cfba0d Mon Sep 17 00:00:00 2001
From: fosslinux <fosslinux@aussies.space>
Date: Sat, 23 May 2020 14:33:36 +1000
Subject: [PATCH 6/7] New package: python-stringcase-1.2.0
---
srcpkgs/python-stringcase/template | 28 ++++++++++++++++++++++++++++
srcpkgs/python3-stringcase | 1 +
2 files changed, 29 insertions(+)
create mode 100644 srcpkgs/python-stringcase/template
create mode 120000 srcpkgs/python3-stringcase
diff --git a/srcpkgs/python-stringcase/template b/srcpkgs/python-stringcase/template
new file mode 100644
index 00000000000..849e677c784
--- /dev/null
+++ b/srcpkgs/python-stringcase/template
@@ -0,0 +1,28 @@
+# Template file for 'python-stringcase'
+pkgname=python-stringcase
+version=1.2.0
+revision=1
+wrksrc="stringcase-${version}"
+build_style=python-module
+hostmakedepends="python-devel python3-devel"
+makedepends="${hostmakedepends}"
+depends="python"
+short_desc="String case converter for Python2"
+maintainer="fosslinux <fosslinux@aussies.space>"
+license="MIT"
+homepage="https://github.com/okunishinishi/python-stringcase"
+distfiles="${PYPI_SITE}/s/stringcase/stringcase-${version}.tar.gz"
+checksum=48a06980661908efe8d9d34eab2b6c13aefa2163b3ced26972902e3bdfd87008
+
+post_install() {
+ vlicense LICENSE
+}
+
+python3-stringcase_package() {
+ depends="python3"
+ short_desc="${short_desc/Python2/Python3}"
+ pkg_install() {
+ vmove usr/lib/python3*
+ vlicense LICENSE
+ }
+}
diff --git a/srcpkgs/python3-stringcase b/srcpkgs/python3-stringcase
new file mode 120000
index 00000000000..53938bd1f0c
--- /dev/null
+++ b/srcpkgs/python3-stringcase
@@ -0,0 +1 @@
+python-stringcase
\ No newline at end of file
From 0bb7feb6288a612ac0dd22879440c25fb227ed2d Mon Sep 17 00:00:00 2001
From: fosslinux <fosslinux@aussies.space>
Date: Sat, 23 May 2020 14:36:21 +1000
Subject: [PATCH 7/7] anki: update to 2.1.26
Has turned into a Bad Build System. Now uses rust nightly, python
(with bindings!), qt5, nodejs... the list goes on. There are quite
a few hacks and the like.
---
srcpkgs/anki/patches/aqt_data-fhs.patch | 45 +++
srcpkgs/anki/patches/rust-nightly-fix.patch | 274 ++++++++++++++++++
.../anki/patches/rustc-cross-compile.patch | 11 +
.../patches/update-rust-nightly-version.patch | 5 +
srcpkgs/anki/patches/vendored-deps.patch | 94 ++++++
srcpkgs/anki/template | 64 +++-
6 files changed, 486 insertions(+), 7 deletions(-)
create mode 100644 srcpkgs/anki/patches/aqt_data-fhs.patch
create mode 100644 srcpkgs/anki/patches/rust-nightly-fix.patch
create mode 100644 srcpkgs/anki/patches/rustc-cross-compile.patch
create mode 100644 srcpkgs/anki/patches/update-rust-nightly-version.patch
create mode 100644 srcpkgs/anki/patches/vendored-deps.patch
diff --git a/srcpkgs/anki/patches/aqt_data-fhs.patch b/srcpkgs/anki/patches/aqt_data-fhs.patch
new file mode 100644
index 00000000000..ac0d29ec082
--- /dev/null
+++ b/srcpkgs/anki/patches/aqt_data-fhs.patch
@@ -0,0 +1,45 @@
+From a0a9ac1aeb8b8678f1102aed81010a901ad8d9e1 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Johannes=20L=C3=B6thberg?= <johannes@kyriasis.com>
+Date: Sun, 29 Mar 2020 06:24:43 +0200
+Subject: [PATCH 1/4] Move aqt_data to sys.prefix/share
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+These files do _not_ belong right under sys.prefix.
+
+Signed-off-by: Johannes Löthberg <johannes@kyriasis.com>
+---
+ qt/aqt/utils.py | 2 +-
+ qt/setup.py | 2 +-
+ 2 files changed, 2 insertions(+), 2 deletions(-)
+
+diff --git qt/aqt/utils.py qt/aqt/utils.py
+index a0e12362..4d8c8c34 100644
+--- qt/aqt/utils.py
++++ qt/aqt/utils.py
+@@ -21,7 +21,7 @@ from aqt.theme import theme_manager
+
+ def aqt_data_folder() -> str:
+ # wheel install?
+- dir = os.path.join(sys.prefix, "aqt_data")
++ dir = os.path.join(sys.prefix,"share", "aqt_data")
+ if not os.path.exists(dir) or not os.listdir(dir):
+ # running in place?
+ dir = os.path.join(os.path.dirname(__file__), "..", "aqt_data")
+diff --git qt/setup.py qt/setup.py
+index 38f4e2b7..bdda3baa 100644
+--- qt/setup.py
++++ qt/setup.py
+@@ -8,7 +8,7 @@ import setuptools
+ def package_files(directory):
+ entries = []
+ for (path, directories, filenames) in os.walk(directory):
+- entries.append((path, [os.path.join(path, f) for f in filenames]))
++ entries.append((os.path.join("share", path), [os.path.join(path, f) for f in filenames]))
+ return entries
+
+
+--
+2.26.2
+
diff --git a/srcpkgs/anki/patches/rust-nightly-fix.patch b/srcpkgs/anki/patches/rust-nightly-fix.patch
new file mode 100644
index 00000000000..3d70aa36aad
--- /dev/null
+++ b/srcpkgs/anki/patches/rust-nightly-fix.patch
@@ -0,0 +1,274 @@
+From fb578a0c2dc391f37de7cb6969c40f34d0de845c Mon Sep 17 00:00:00 2001
+From: Damien Elmes <gpg@ankiweb.net>
+Date: Fri, 24 Apr 2020 13:39:14 +1000
+Subject: [PATCH] switch to owned strings in ParsedTemplate
+
+will make it easier to cache the parsed results in the future,
+and handle field renames & other transformations
+---
+ rslib/src/notetype/cardgen.rs | 6 +-
+ rslib/src/notetype/templates.rs | 2 +-
+ rslib/src/template.rs | 98 +++++++++++++++++----------------
+ 3 files changed, 56 insertions(+), 50 deletions(-)
+
+Backported by fossy to stable. notetype patch is not needed.
+
+diff --git rslib/src/template.rs rslib/src/template.rs
+index 4479899009..ed5fe7e916 100644
+--- rslib/src/template.rs
++++ rslib/src/template.rs
+@@ -147,26 +147,26 @@ fn legacy_tokens(mut data: &str) -> impl Iterator<Item = TemplateResult<Token>>
+ //----------------------------------------
+
+ #[derive(Debug, PartialEq)]
+-enum ParsedNode<'a> {
+- Text(&'a str),
++enum ParsedNode {
++ Text(String),
+ Replacement {
+- key: &'a str,
+- filters: Vec<&'a str>,
++ key: String,
++ filters: Vec<String>,
+ },
+ Conditional {
+- key: &'a str,
+- children: Vec<ParsedNode<'a>>,
++ key: String,
++ children: Vec<ParsedNode>,
+ },
+ NegatedConditional {
+- key: &'a str,
+- children: Vec<ParsedNode<'a>>,
++ key: String,
++ children: Vec<ParsedNode>,
+ },
+ }
+
+ #[derive(Debug)]
+-pub struct ParsedTemplate<'a>(Vec<ParsedNode<'a>>);
++pub struct ParsedTemplate(Vec<ParsedNode>);
+
+-impl ParsedTemplate<'_> {
++impl ParsedTemplate {
+ /// Create a template from the provided text.
+ pub fn from_text(template: &str) -> TemplateResult<ParsedTemplate> {
+ let mut iter = tokens(template);
+@@ -177,26 +177,26 @@ impl ParsedTemplate<'_> {
+ fn parse_inner<'a, I: Iterator<Item = TemplateResult<Token<'a>>>>(
+ iter: &mut I,
+ open_tag: Option<&'a str>,
+-) -> TemplateResult<Vec<ParsedNode<'a>>> {
++) -> TemplateResult<Vec<ParsedNode>> {
+ let mut nodes = vec![];
+
+ while let Some(token) = iter.next() {
+ use Token::*;
+ nodes.push(match token? {
+- Text(t) => ParsedNode::Text(t),
++ Text(t) => ParsedNode::Text(t.into()),
+ Replacement(t) => {
+ let mut it = t.rsplit(':');
+ ParsedNode::Replacement {
+- key: it.next().unwrap(),
+- filters: it.collect(),
++ key: it.next().unwrap().into(),
++ filters: it.map(Into::into).collect(),
+ }
+ }
+ OpenConditional(t) => ParsedNode::Conditional {
+- key: t,
++ key: t.into(),
+ children: parse_inner(iter, Some(t))?,
+ },
+ OpenNegated(t) => ParsedNode::NegatedConditional {
+- key: t,
++ key: t.into(),
+ children: parse_inner(iter, Some(t))?,
+ },
+ CloseConditional(t) => {
+@@ -285,27 +285,27 @@ fn localized_template_error(i18n: &I18n, err: TemplateError) -> String {
+ // Checking if template is empty
+ //----------------------------------------
+
+-impl ParsedTemplate<'_> {
++impl ParsedTemplate {
+ /// true if provided fields are sufficient to render the template
+ pub fn renders_with_fields(&self, nonempty_fields: &HashSet<&str>) -> bool {
+ !template_is_empty(nonempty_fields, &self.0)
+ }
+ }
+
+-fn template_is_empty<'a>(nonempty_fields: &HashSet<&str>, nodes: &[ParsedNode<'a>]) -> bool {
++fn template_is_empty(nonempty_fields: &HashSet<&str>, nodes: &[ParsedNode]) -> bool {
+ use ParsedNode::*;
+ for node in nodes {
+ match node {
+ // ignore normal text
+ Text(_) => (),
+ Replacement { key, .. } => {
+- if nonempty_fields.contains(*key) {
++ if nonempty_fields.contains(key.as_str()) {
+ // a single replacement is enough
+ return false;
+ }
+ }
+ Conditional { key, children } => {
+- if !nonempty_fields.contains(*key) {
++ if !nonempty_fields.contains(key.as_str()) {
+ continue;
+ }
+ if !template_is_empty(nonempty_fields, children) {
+@@ -347,7 +347,7 @@ pub(crate) struct RenderContext<'a> {
+ pub card_ord: u16,
+ }
+
+-impl ParsedTemplate<'_> {
++impl ParsedTemplate {
+ /// Render the template with the provided fields.
+ ///
+ /// Replacements that use only standard filters will become part of
+@@ -373,10 +373,7 @@ fn render_into(
+ Text(text) => {
+ append_str_to_nodes(rendered_nodes, text);
+ }
+- Replacement {
+- key: key @ "FrontSide",
+- ..
+- } => {
++ Replacement { key, .. } if key == "FrontSide" => {
+ // defer FrontSide rendering to Python, as extra
+ // filters may be required
+ rendered_nodes.push(RenderedNode::Replacement {
+@@ -385,27 +382,36 @@ fn render_into(
+ current_text: "".into(),
+ });
+ }
+- Replacement { key: "", filters } if !filters.is_empty() => {
++ Replacement { key, filters } if key == "" && !filters.is_empty() => {
+ // if a filter is provided, we accept an empty field name to
+ // mean 'pass an empty string to the filter, and it will add
+ // its own text'
+ rendered_nodes.push(RenderedNode::Replacement {
+ field_name: "".to_string(),
+ current_text: "".to_string(),
+- filters: filters.iter().map(|&f| f.to_string()).collect(),
++ filters: filters.clone(),
+ })
+ }
+ Replacement { key, filters } => {
+ // apply built in filters if field exists
+- let (text, remaining_filters) = match context.fields.get(key) {
+- Some(text) => apply_filters(text, filters, key, context),
++ let (text, remaining_filters) = match context.fields.get(key.as_str()) {
++ Some(text) => apply_filters(
++ text,
++ filters
++ .iter()
++ .map(|s| s.as_str())
++ .collect::<Vec<_>>()
++ .as_slice(),
++ key,
++ context,
++ ),
+ None => {
+ // unknown field encountered
+ let filters_str = filters
+ .iter()
+ .rev()
+ .cloned()
+- .chain(iter::once(""))
++ .chain(iter::once("".into()))
+ .collect::<Vec<_>>()
+ .join(":");
+ return Err(TemplateError::FieldNotFound {
+@@ -427,12 +433,12 @@ fn render_into(
+ }
+ }
+ Conditional { key, children } => {
+- if context.nonempty_fields.contains(key) {
++ if context.nonempty_fields.contains(key.as_str()) {
+ render_into(rendered_nodes, children.as_ref(), context)?;
+ }
+ }
+ NegatedConditional { key, children } => {
+- if !context.nonempty_fields.contains(key) {
++ if !context.nonempty_fields.contains(key.as_str()) {
+ render_into(rendered_nodes, children.as_ref(), context)?;
+ }
+ }
+@@ -542,7 +548,7 @@ pub enum FieldRequirements {
+ None,
+ }
+
+-impl ParsedTemplate<'_> {
++impl ParsedTemplate {
+ /// Return fields required by template.
+ ///
+ /// This is not able to represent negated expressions or combinations of
+@@ -613,11 +619,11 @@
+ vec![
+- Text("foo "),
++ Text("foo ".into()),
+ Replacement {
+- key: "bar",
++ key: "bar".into(),
+ filters: vec![]
+ },
+- Text(" "),
++ Text(" ".into()),
+ Conditional {
+- key: "baz",
+- children: vec![Text(" quux ")]
++ key: "baz".into(),
++ children: vec![Text(" quux ".into())]
+ }
+ ]
+@@ -630,7 +636,7 @@ mod test {
+ assert_eq!(
+ tmpl.0,
+ vec![NegatedConditional {
+- key: "baz",
++ key: "baz".into(),
+ children: vec![]
+ }]
+ );
+@@ -643,7 +649,7 @@ mod test {
+ assert_eq!(
+ PT::from_text("{{ tag }}").unwrap().0,
+ vec![Replacement {
+- key: "tag",
++ key: "tag".into(),
+ filters: vec![]
+ }]
+ );
+@@ -651,7 +657,7 @@ mod test {
+ // stray closing characters (like in javascript) are ignored
+ assert_eq!(
+ PT::from_text("text }} more").unwrap().0,
+- vec![Text("text }} more")]
++ vec![Text("text }} more".into())]
+ );
+
+ PT::from_text("{{").unwrap_err();
+@@ -737,15 +743,15 @@ mod test {
+ assert_eq!(
+ PT::from_text(input).unwrap().0,
+ vec![
+- Text("\n"),
++ Text("\n".into()),
+ Replacement {
+- key: "Front",
++ key: "Front".into(),
+ filters: vec![]
+ },
+- Text("\n"),
++ Text("\n".into()),
+ Conditional {
+- key: "Back",
+- children: vec![Text("\n")]
++ key: "Back".into(),
++ children: vec![Text("\n".into())]
+ }
+ ]
+ );
diff --git a/srcpkgs/anki/patches/rustc-cross-compile.patch b/srcpkgs/anki/patches/rustc-cross-compile.patch
new file mode 100644
index 00000000000..15239ea4cf1
--- /dev/null
+++ b/srcpkgs/anki/patches/rustc-cross-compile.patch
@@ -0,0 +1,11 @@
+--- rspy/Makefile 2020-05-23 12:02:29.758286838 +1000
++++ rspy/Makefile 2020-05-08 18:17:57.000000000 +1000
+@@ -69,7 +69,7 @@
+ .build/build: $(DEPS)
+ touch ../proto/backend.proto
+ ${BUILD_VARIABLES} \
+- maturin build -i "${PYTHON_FILE}" -o "$(OUTDIR)" $(BUILDFLAGS)
++ maturin build -i "${PYTHON_FILE}" -o "$(OUTDIR)" $(BUILDFLAGS) --target $(RUST_TARGET)
+ touch $@
+
+ check: .build/check
diff --git a/srcpkgs/anki/patches/update-rust-nightly-version.patch b/srcpkgs/anki/patches/update-rust-nightly-version.patch
new file mode 100644
index 00000000000..51e8afa7cf0
--- /dev/null
+++ b/srcpkgs/anki/patches/update-rust-nightly-version.patch
@@ -0,0 +1,5 @@
+--- rspy/rust-toolchain 2020-05-24 08:54:25.130010169 +1000
++++ rspy/rust-toolchain 2020-05-24 18:02:34.496636771 +1000
+@@ -1 +1 @@
+-nightly-2020-02-27
++nightly-2020-05-15
diff --git a/srcpkgs/anki/patches/vendored-deps.patch b/srcpkgs/anki/patches/vendored-deps.patch
new file mode 100644
index 00000000000..1d2bc90ffb1
--- /dev/null
+++ b/srcpkgs/anki/patches/vendored-deps.patch
@@ -0,0 +1,94 @@
+diff -u -r Makefile Makefile
+--- Makefile 2020-05-08 18:17:57.000000000 +1000
++++ Makefile 2020-05-19 18:40:54.345223164 +1000
+@@ -92,7 +92,7 @@
+ fi
+
+ .PHONY: develop
+-develop: pyenv buildhash prepare
++develop: buildhash prepare
+ @set -eu -o pipefail ${SHELLFLAGS}; \
+ . "${ACTIVATE_SCRIPT}"; \
+ for dir in $(DEVEL); do \
+diff -u -r pylib/Makefile pylib/Makefile
+--- pylib/Makefile 2020-05-08 18:17:57.000000000 +1000
++++ pylib/Makefile 2020-05-19 18:50:01.075182994 +1000
+@@ -52,7 +52,7 @@
+ python -m black anki/hooks.py
+ @touch $@
+
+-BUILD_STEPS := .build/vernum .build/run-deps .build/dev-deps .build/py-proto anki/buildinfo.py .build/hooks
++BUILD_STEPS := .build/vernum .build/py-proto anki/buildinfo.py .build/hooks
+
+ # Checking
+ ######################
+diff -u -r qt/Makefile qt/Makefile
+--- qt/Makefile 2020-05-08 18:17:57.000000000 +1000
++++ qt/Makefile 2020-05-19 18:50:17.520181786 +1000
+@@ -64,7 +64,7 @@
+ python -m black aqt/gui_hooks.py
+ @touch $@
+
+-BUILD_STEPS := .build/vernum .build/run-deps .build/dev-deps .build/js .build/ui aqt/buildinfo.py .build/hooks .build/i18n
++BUILD_STEPS := .build/vernum .build/js .build/ui aqt/buildinfo.py .build/hooks .build/i18n
+
+ # Checking
+ ######################
+--- Makefile 2020-05-08 18:17:57.000000000 +1000
++++ Makefile 2020-05-19 19:01:35.602131965 +1000
+@@ -122,7 +122,7 @@
+ @echo "Build complete."
+
+ .PHONY: build-rspy
+-build-rspy: pyenv buildhash
++build-rspy: buildhash
+ @set -eu -o pipefail ${SHELLFLAGS}; \
+ . "${ACTIVATE_SCRIPT}"; \
+ $(SUBMAKE) -C rspy build BUILDFLAGS="$(BUILDFLAGS)"
+--- Makefile 2020-05-19 19:41:44.191955000 +1000
++++ Makefile 2020-05-19 19:42:21.423952264 +1000
+@@ -124,19 +124,16 @@
+ .PHONY: build-rspy
+ build-rspy: buildhash
+ @set -eu -o pipefail ${SHELLFLAGS}; \
+- . "${ACTIVATE_SCRIPT}"; \
+ $(SUBMAKE) -C rspy build BUILDFLAGS="$(BUILDFLAGS)"
+
+ .PHONY: build-pylib
+ build-pylib:
+ @set -eu -o pipefail ${SHELLFLAGS}; \
+- . "${ACTIVATE_SCRIPT}"; \
+ $(SUBMAKE) -C pylib build
+
+ .PHONY: build-qt
+ build-qt:
+ @set -eu -o pipefail ${SHELLFLAGS}; \
+- . "${ACTIVATE_SCRIPT}"; \
+ $(SUBMAKE) -C qt build
+
+ .PHONY: clean
+--- rspy/Makefile 2020-05-21 20:06:35.945720983 +1000
++++ rspy/Makefile 2020-05-21 20:07:54.295720504 +1000
+@@ -86,10 +86,10 @@
+ RUST_TOOLCHAIN := $(shell cat rust-toolchain)
+
+ .build/tools: requirements.txt rust-toolchain
+- python -m pip install -r requirements.txt
+ rustup toolchain install $(RUST_TOOLCHAIN)
+ rustup component add rustfmt-preview --toolchain $(RUST_TOOLCHAIN)
+ rustup component add clippy-preview --toolchain $(RUST_TOOLCHAIN)
++ rustup target add $(RUST_TARGET)
+ @touch $@
+
+ # we should not call clippy because it break things when running make check Mac OS
+--- pylib/Makefile 2020-05-22 08:46:14.988607539 +1000
++++ pylib/Makefile 2020-05-22 08:46:38.376605821 +1000
+@@ -41,7 +41,7 @@
+
+ PROTODEPS := $(wildcard ../proto/*.proto)
+
+-.build/py-proto: .build/dev-deps $(PROTODEPS)
++.build/py-proto: $(PROTODEPS)
+ protoc --proto_path=../proto --python_out=anki --mypy_out=anki $(PROTODEPS)
+ perl -i'' -pe 's/from fluent_pb2/from anki.fluent_pb2/' anki/backend_pb2.pyi
+ perl -i'' -pe 's/import fluent_pb2/import anki.fluent_pb2/' anki/backend_pb2.py
diff --git a/srcpkgs/anki/template b/srcpkgs/anki/template
index 680e008a9d4..89e28d11b05 100644
--- a/srcpkgs/anki/template
+++ b/srcpkgs/anki/template
@@ -1,23 +1,73 @@
# Template file for 'anki'
pkgname=anki
-version=2.1.15
-revision=2
-archs=noarch
+version=2.1.26
+revision=1
build_style=gnu-makefile
pycompile_dirs="/usr/share/anki/anki /usr/share/anki/aqt"
+# rustup: anki needs nightly ... :(
+hostmakedepends="git python3 rustup maturin which protobuf
+ mypy-protobuf-python python3-stringcase black python3-wheel
+ rsync nodejs python3-PyQt5-devel-tools gettext
+ qt5-translations python3-pip"
depends="python3-PyQt5-webengine python3-requests python3-SQLAlchemy
python3-PyAudio python3-mpv python3-Markdown python3-send2trash
- python3-BeautifulSoup4 python3-decorator python3-jsonschema"
+ python3-BeautifulSoup4 python3-decorator python3-jsonschema
+ python3-protobuf"
short_desc="Spaced repetition flashcard program"
maintainer="Steve Prybylski <sa.prybylx@gmail.com>"
license="AGPL-3.0-or-later"
homepage="https://apps.ankiweb.net"
changelog="https://apps.ankiweb.net/docs/changes.html"
-distfiles="https://apps.ankiweb.net/downloads/current/anki-${version}-source.tgz"
-checksum=5a53760164c77d619f55107a13099cffe620566a7f610b61b6c4b52487f3bb89
-
+distfiles="https://github.com/ankitects/anki/archive/${version}.tar.gz"
+checksum=f5a0c41f3eebe0e77de9d46f2a5cbbe20f7c3a4787f0f02e1d33f298428acbdf
python_version=3
+# When a non-clean masterdir is used, rust is often left over from a
+# previous rust-enabled build. Unfortunatly, xbps-src dosen't seem
+# to clean out rust -.- So, use /usr/rustup, to avoid this issue.
+export PATH=/usr/rustup/bin:${PATH}
+export LD_LIBRARY_PATH=/usr/rustup/lib:${LD_LIBRARY_PATH}
+export CARGO_HOME=/usr/rustup
+export RUSTUP_HOME=/usr/rustup
+
+pre_configure() {
+ # If do_clean didn't run last time, we are stuffed. Run do_clean now.
+ do_clean || true
+ printf "1\\n" | rustup-init -y
+}
+
+pre_build() {
+ mkdir -p dist
+ make prepare
+}
+
+do_build() {
+ RUSTFLAGS="-C target-feature=-crt-static" make build
+}
+
+do_install() {
+ pushd pylib
+ python3 setup.py install --prefix=/usr --root=${DESTDIR}
+ popd
+
+ pushd qt
+ python3 setup.py install --prefix=/usr --root=${DESTDIR}
+ popd
+
+ # maturin generates a .whl, this is all we can do
+ PIP_CONFIG_FILE=/dev/null pip3 install --isolated --root=${DESTDIR} --prefix=/usr --ignore-installed --no-deps dist/ankirspy*.whl
+
+ # Copied from arch's PKGBUILD
+ install -Dm755 qt/runanki "${DESTDIR}/usr/bin/anki"
+ install -Dm644 qt/anki.desktop "${DESTDIR}/usr/share/applications/anki.desktop"
+ install -Dm644 qt/anki.png "${DESTDIR}/usr/share/pixmaps/anki.png"
+}
+
post_install() {
vlicense LICENSE
}
+
+# Remove rustup
+do_clean() {
+ rm -rf /usr/rustup
+}
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PR PATCH] [Updated] WIP: anki: update to 2.1.26
2020-05-23 6:18 [PR PATCH] WIP: anki: update to 2.1.26 fosslinux
` (3 preceding siblings ...)
2020-05-28 7:38 ` [PR PATCH] [Updated] " fosslinux
@ 2020-05-30 1:53 ` fosslinux
2020-06-01 9:58 ` fosslinux
` (7 subsequent siblings)
12 siblings, 0 replies; 14+ messages in thread
From: fosslinux @ 2020-05-30 1:53 UTC (permalink / raw)
To: ml
[-- Attachment #1: Type: text/plain, Size: 2109 bytes --]
There is an updated pull request by fosslinux against master on the void-packages repository
https://github.com/fosslinux/void-packages anki-2.1.26
https://github.com/void-linux/void-packages/pull/22219
WIP: anki: update to 2.1.26
This has a wide variety of changes as if you have heard my ranting in #xbps it has turned into a Bad Build System - there is rust (nightly!), nodejs, python, etc etc, no proper install target...
A few things to note:
- python3-mypy is updated as mypy-protobuf needs the new version, otherwise the build failed.
- same thing with python-protobuf, but for anki and at runtime
- maturin is some weird build system at the intersection of rust and python.
- mypy-protobuf-python is what anki uses for binding python and rust together, partly.
- mypy-protobuf-go is the go implementation of mypy-protobuf-python that I thought should be packaged anywway.
- python-stringcase is a new dependency.
- anki is an archd package (not nocross), because the rust code is obviously platform specific.
- anki uses rustup. This is because it and some of its dependencies require archd code (notably pyo3). This is unavoidable, afaict.
Still todo:
- [x] Apply archlinux's aqt_build patch, which stops it from polluting /usr directly (:vomiting_face:)
- [x] Update python3-protobuf - hopefully will fix `AttributeError: module 'google.protobuf.descriptor' has no attribute '_internal_create_key'`.
- [ ] Look into travis musl error. https://github.com/rust-lang/rust/issues/40174. Hopefully, using rust 1.44 as the rust version *should* fix this. What a PITA. I understand that this is because it works when I cross-compile to x86_64-musl from x86_64 but we need it to work native build from x86_64-musl for the builders...
- [ ] Travis wth on i686?
- [x] Make it open.
- [ ] More extensive runtime testing.
- [ ] Runtime test on musl.
Questions:
- Is there any problems with removing `arch=nocross`?
- Does the rustup stuff look (somewhat) sane?
- Are the patches sane?
A patch file from https://github.com/void-linux/void-packages/pull/22219.patch is attached
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: github-pr-anki-2.1.26-22219.patch --]
[-- Type: text/x-diff, Size: 31713 bytes --]
From 78816216511379aa1b82f106aeffe9266c10ca18 Mon Sep 17 00:00:00 2001
From: fosslinux <fosslinux@aussies.space>
Date: Sun, 24 May 2020 15:37:00 +1000
Subject: [PATCH 1/7] python-protobuf: update to 3.12.1
---
srcpkgs/python-protobuf/template | 13 ++++++-------
1 file changed, 6 insertions(+), 7 deletions(-)
diff --git a/srcpkgs/python-protobuf/template b/srcpkgs/python-protobuf/template
index 1a2d37a0a1e..a96fd539894 100644
--- a/srcpkgs/python-protobuf/template
+++ b/srcpkgs/python-protobuf/template
@@ -1,19 +1,19 @@
# Template file for 'python-protobuf'
pkgname=python-protobuf
-version=3.10.0
-revision=2
+version=3.12.1
+revision=1
archs=noarch
wrksrc="protobuf-${version}"
+build_wrksrc="python"
build_style=python-module
-pycompile_module="google/protobuf"
-hostmakedepends="python-setuptools python3-setuptools"
+hostmakedepends="python-setuptools python3-setuptools protobuf"
depends="python-setuptools python-six"
short_desc="Python2 bindings for Google Protocol Buffers"
maintainer="Charles E. Lehner <cel@celehner.com>"
license="BSD-3-Clause"
homepage="https://developers.google.com/protocol-buffers/"
-distfiles="${PYPI_SITE}/p/protobuf/protobuf-${version}.tar.gz"
-checksum=db83b5c12c0cd30150bb568e6feb2435c49ce4e68fe2d7b903113f0e221e58fe
+distfiles="https://github.com/protocolbuffers/protobuf/archive/v${version}.tar.gz"
+checksum=cb9b3f9d625b5739a358268eb3421de11cacd90025f5f7672c3930553eca810e
post_install() {
sed -n 1,29p google/protobuf/__init__.py >LICENSE
@@ -22,7 +22,6 @@ post_install() {
python3-protobuf_package() {
archs=noarch
- pycompile_module="google/protobuf"
depends="python3-setuptools python3-six"
short_desc="${short_desc/Python2/Python3}"
pkg_install() {
From 7712eb76d5743a2c0c3d75747bc3ea0f5f2e4e0b Mon Sep 17 00:00:00 2001
From: fosslinux <fosslinux@aussies.space>
Date: Sat, 23 May 2020 14:33:01 +1000
Subject: [PATCH 2/7] python3-mypy: update to 0.770, claim maintainership
---
srcpkgs/python3-mypy/template | 7 +++----
1 file changed, 3 insertions(+), 4 deletions(-)
diff --git a/srcpkgs/python3-mypy/template b/srcpkgs/python3-mypy/template
index 5d7f93d5772..bde1e7f4be6 100644
--- a/srcpkgs/python3-mypy/template
+++ b/srcpkgs/python3-mypy/template
@@ -1,19 +1,18 @@
# Template file for 'python3-mypy'
pkgname=python3-mypy
-version=0.761
+version=0.770
revision=1
archs=noarch
wrksrc="mypy-${version}"
build_style=python3-module
-pycompile_module="mypy"
hostmakedepends="python3-setuptools"
depends="python3-mypy_extensions python3-typed-ast python3-typing_extensions"
short_desc="Optional static typing for Python3"
-maintainer="Orphaned <orphan@voidlinux.org>"
+maintainer="fosslinux <fosslinux@aussies.space>"
license="MIT"
homepage="https://github.com/python/mypy"
distfiles="${PYPI_SITE}/m/mypy/mypy-${version}.tar.gz"
-checksum=85baab8d74ec601e86134afe2bcccd87820f79d2f8d5798c889507d1088287bf
+checksum=8a627507ef9b307b46a1fea9513d5c98680ba09591253082b4c48697ba05a4ae
post_install() {
vlicense LICENSE
From 6efdf584b76652d8f2df4ea2130474e3b1576340 Mon Sep 17 00:00:00 2001
From: fosslinux <fosslinux@aussies.space>
Date: Sat, 23 May 2020 14:34:38 +1000
Subject: [PATCH 3/7] New package: maturin-0.8.1
---
.../patches/cross-compile-setup-py.patch | 14 +++++++++++++
srcpkgs/maturin/template | 21 +++++++++++++++++++
2 files changed, 35 insertions(+)
create mode 100644 srcpkgs/maturin/patches/cross-compile-setup-py.patch
create mode 100644 srcpkgs/maturin/template
diff --git a/srcpkgs/maturin/patches/cross-compile-setup-py.patch b/srcpkgs/maturin/patches/cross-compile-setup-py.patch
new file mode 100644
index 00000000000..e57189cb7ab
--- /dev/null
+++ b/srcpkgs/maturin/patches/cross-compile-setup-py.patch
@@ -0,0 +1,14 @@
+--- setup.py 2020-04-30 22:36:01.000000000 +1000
++++ setup.py 2020-05-20 14:31:40.404994499 +1000
+@@ -56,9 +56,9 @@
+ "(https://www.rust-lang.org/tools/install) and try again"
+ )
+ subprocess.check_call(
+- ["cargo", "rustc", "--bin", "maturin", "--", "-C", "link-arg=-s"]
++ ["cargo", "rustc", "--bin", "maturin", "--release", "--target", os.environ["RUST_TARGET"], "--", "-C", "link-arg=-s", "-C", "linker=" + os.environ["CC"].split(" ", 1)[0]]
+ )
+- source = os.path.join(source_dir, "target", "debug", executable_name)
++ source = os.path.join(source_dir, "target", os.environ["RUST_TARGET"], "release", executable_name)
+ # run this after trying to build with cargo (as otherwise this leaves
+ # venv in a bad state: https://github.com/benfred/py-spy/issues/69)
+ install.run(self)
diff --git a/srcpkgs/maturin/template b/srcpkgs/maturin/template
new file mode 100644
index 00000000000..7eba36204f9
--- /dev/null
+++ b/srcpkgs/maturin/template
@@ -0,0 +1,21 @@
+# Template file for 'maturin'
+pkgname=maturin
+version=0.8.1
+revision=1
+build_style=python3-module
+hostmakedepends="cargo python3-setuptools python3-toml"
+makedepends="rust rust-std llvm9"
+short_desc="Build and publish crates with python bindings"
+maintainer="fosslinux <fosslinux@aussies.space>"
+license="Apache-2.0, MIT"
+homepage="https://github.com/PyO3/maturin"
+distfiles="https://github.com/PyO3/maturin/archive/v${version}.tar.gz"
+checksum=b72a9885cda3ba4e53906a43aab101acb790622218ade6405b2ddf1ef1461f8f
+
+post_install() {
+ # Dynamic detection of python version
+ PYTHON_VERSION=$(python3 --version | sed "s/^Python //" | rev | sed "s/^[0-9]*.//" | rev)
+ mkdir -p "${DESTDIR}/usr/lib/python${PYTHON_VERSION}/site-packages/"
+ mv "${DESTDIR}/maturin" "${DESTDIR}/usr/lib/python${PYTHON_VERSION}/site-packages/"
+ vlicense license-mit
+}
From bf0b313f13c558529acb46ef74b3841997b9d5d9 Mon Sep 17 00:00:00 2001
From: fosslinux <fosslinux@aussies.space>
Date: Sat, 23 May 2020 14:35:25 +1000
Subject: [PATCH 4/7] New package: mypy-protobuf-python-1.13
---
srcpkgs/mypy-protobuf-python/template | 23 +++++++++++++++++++++++
1 file changed, 23 insertions(+)
create mode 100644 srcpkgs/mypy-protobuf-python/template
diff --git a/srcpkgs/mypy-protobuf-python/template b/srcpkgs/mypy-protobuf-python/template
new file mode 100644
index 00000000000..391d75f0c9e
--- /dev/null
+++ b/srcpkgs/mypy-protobuf-python/template
@@ -0,0 +1,23 @@
+# Template file for 'mypy-protobuf-python'
+#
+# WARNING: THIS TEMPLATE SHOULD BE SYNCRONISED WITH mypy-protobuf-go
+#
+pkgname=mypy-protobuf-python
+version=1.13
+revision=1
+wrksrc="mypy-protobuf-${version}"
+build_wrksrc=python
+build_style=python3-module
+hostmakedepends="python3-setuptools"
+depends="python3-mypy python3-typing_extensions python3-protobuf protobuf"
+short_desc="Generate mypy stubs from protobufs - Python implementation"
+maintainer="fosslinux <fosslinux@aussies.space>"
+license="Apache-2.0"
+homepage="https://github.com/dropbox/mypy-protobuf"
+distfiles="https://github.com/dropbox/mypy-protobuf/archive/v${version}.tar.gz"
+checksum=7d86dfc076f8b51814fbfd3a66998a0b570fd1b82ebeda68ae6728cd538adb74
+
+post_install() {
+ # We are not windows, remove the batch file
+ rm "${DESTDIR}/usr/bin/protoc_gen_mypy.bat"
+}
From 0e9530bdee8b9d76ea8bfd4e50087eac4294e2af Mon Sep 17 00:00:00 2001
From: fosslinux <fosslinux@aussies.space>
Date: Sat, 23 May 2020 14:35:37 +1000
Subject: [PATCH 5/7] New package: mypy-protobuf-go-1.13
---
.../patches/remote-go-improt.patch | 11 +++++++++++
srcpkgs/mypy-protobuf-go/template | 19 +++++++++++++++++++
2 files changed, 30 insertions(+)
create mode 100644 srcpkgs/mypy-protobuf-go/patches/remote-go-improt.patch
create mode 100644 srcpkgs/mypy-protobuf-go/template
diff --git a/srcpkgs/mypy-protobuf-go/patches/remote-go-improt.patch b/srcpkgs/mypy-protobuf-go/patches/remote-go-improt.patch
new file mode 100644
index 00000000000..300504bc70d
--- /dev/null
+++ b/srcpkgs/mypy-protobuf-go/patches/remote-go-improt.patch
@@ -0,0 +1,11 @@
+--- go/src/protoc-gen-mypy/main.go.orig 2020-05-22 11:58:07.760761664 +1000
++++ go/src/protoc-gen-mypy/main.go 2020-05-22 11:58:00.595762190 +1000
+@@ -6,7 +6,7 @@
+ "sort"
+ "strings"
+
+- "proto/mypy"
++ "github.com/dropbox/mypy-protobuf/go/src/proto/mypy"
+
+ "github.com/gogo/protobuf/proto"
+ "github.com/gogo/protobuf/protoc-gen-gogo/descriptor"
diff --git a/srcpkgs/mypy-protobuf-go/template b/srcpkgs/mypy-protobuf-go/template
new file mode 100644
index 00000000000..8f00e43d8a8
--- /dev/null
+++ b/srcpkgs/mypy-protobuf-go/template
@@ -0,0 +1,19 @@
+# Template file for 'mypy-protobuf-go'
+#
+# WARNING: THIS TEMPLATE SHOULD BE SYNCRONISED WITH mypy-protobuf-python
+#
+pkgname=mypy-protobuf-go
+version=1.13
+revision=1
+wrksrc="mypy-protobuf-${version}"
+build_style=go
+go_import_path="github.com/dropbox/mypy-protobuf"
+go_package="${go_import_path}/go/src/protoc-gen-mypy"
+hostmakedepends="git"
+depends="protobuf"
+short_desc="Generate mypy stubs from protobufs - go implementation"
+maintainer="fosslinux <fosslinux@aussies.space>"
+license="Apache-2.0"
+homepage="https://github.com/dropbox/mypy-protobuf"
+distfiles="https://github.com/dropbox/mypy-protobuf/archive/v${version}.tar.gz"
+checksum=7d86dfc076f8b51814fbfd3a66998a0b570fd1b82ebeda68ae6728cd538adb74
From 7dbe4213090b5647b997d079f3a7823e15cfba0d Mon Sep 17 00:00:00 2001
From: fosslinux <fosslinux@aussies.space>
Date: Sat, 23 May 2020 14:33:36 +1000
Subject: [PATCH 6/7] New package: python-stringcase-1.2.0
---
srcpkgs/python-stringcase/template | 28 ++++++++++++++++++++++++++++
srcpkgs/python3-stringcase | 1 +
2 files changed, 29 insertions(+)
create mode 100644 srcpkgs/python-stringcase/template
create mode 120000 srcpkgs/python3-stringcase
diff --git a/srcpkgs/python-stringcase/template b/srcpkgs/python-stringcase/template
new file mode 100644
index 00000000000..849e677c784
--- /dev/null
+++ b/srcpkgs/python-stringcase/template
@@ -0,0 +1,28 @@
+# Template file for 'python-stringcase'
+pkgname=python-stringcase
+version=1.2.0
+revision=1
+wrksrc="stringcase-${version}"
+build_style=python-module
+hostmakedepends="python-devel python3-devel"
+makedepends="${hostmakedepends}"
+depends="python"
+short_desc="String case converter for Python2"
+maintainer="fosslinux <fosslinux@aussies.space>"
+license="MIT"
+homepage="https://github.com/okunishinishi/python-stringcase"
+distfiles="${PYPI_SITE}/s/stringcase/stringcase-${version}.tar.gz"
+checksum=48a06980661908efe8d9d34eab2b6c13aefa2163b3ced26972902e3bdfd87008
+
+post_install() {
+ vlicense LICENSE
+}
+
+python3-stringcase_package() {
+ depends="python3"
+ short_desc="${short_desc/Python2/Python3}"
+ pkg_install() {
+ vmove usr/lib/python3*
+ vlicense LICENSE
+ }
+}
diff --git a/srcpkgs/python3-stringcase b/srcpkgs/python3-stringcase
new file mode 120000
index 00000000000..53938bd1f0c
--- /dev/null
+++ b/srcpkgs/python3-stringcase
@@ -0,0 +1 @@
+python-stringcase
\ No newline at end of file
From 0100907ae5898f4915af97f93030dca784dc4909 Mon Sep 17 00:00:00 2001
From: fosslinux <fosslinux@aussies.space>
Date: Sat, 23 May 2020 14:36:21 +1000
Subject: [PATCH 7/7] anki: update to 2.1.26
Has turned into a Bad Build System. Now uses rust nightly, python
(with bindings!), qt5, nodejs... the list goes on. There are quite
a few hacks and the like.
---
srcpkgs/anki/patches/aqt_data-fhs.patch | 45 +++
srcpkgs/anki/patches/rust-nightly-fix.patch | 274 ++++++++++++++++++
.../anki/patches/rustc-cross-compile.patch | 11 +
.../patches/update-rust-nightly-version.patch | 5 +
srcpkgs/anki/patches/vendored-deps.patch | 94 ++++++
srcpkgs/anki/template | 57 +++-
6 files changed, 479 insertions(+), 7 deletions(-)
create mode 100644 srcpkgs/anki/patches/aqt_data-fhs.patch
create mode 100644 srcpkgs/anki/patches/rust-nightly-fix.patch
create mode 100644 srcpkgs/anki/patches/rustc-cross-compile.patch
create mode 100644 srcpkgs/anki/patches/update-rust-nightly-version.patch
create mode 100644 srcpkgs/anki/patches/vendored-deps.patch
diff --git a/srcpkgs/anki/patches/aqt_data-fhs.patch b/srcpkgs/anki/patches/aqt_data-fhs.patch
new file mode 100644
index 00000000000..ac0d29ec082
--- /dev/null
+++ b/srcpkgs/anki/patches/aqt_data-fhs.patch
@@ -0,0 +1,45 @@
+From a0a9ac1aeb8b8678f1102aed81010a901ad8d9e1 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Johannes=20L=C3=B6thberg?= <johannes@kyriasis.com>
+Date: Sun, 29 Mar 2020 06:24:43 +0200
+Subject: [PATCH 1/4] Move aqt_data to sys.prefix/share
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+These files do _not_ belong right under sys.prefix.
+
+Signed-off-by: Johannes Löthberg <johannes@kyriasis.com>
+---
+ qt/aqt/utils.py | 2 +-
+ qt/setup.py | 2 +-
+ 2 files changed, 2 insertions(+), 2 deletions(-)
+
+diff --git qt/aqt/utils.py qt/aqt/utils.py
+index a0e12362..4d8c8c34 100644
+--- qt/aqt/utils.py
++++ qt/aqt/utils.py
+@@ -21,7 +21,7 @@ from aqt.theme import theme_manager
+
+ def aqt_data_folder() -> str:
+ # wheel install?
+- dir = os.path.join(sys.prefix, "aqt_data")
++ dir = os.path.join(sys.prefix,"share", "aqt_data")
+ if not os.path.exists(dir) or not os.listdir(dir):
+ # running in place?
+ dir = os.path.join(os.path.dirname(__file__), "..", "aqt_data")
+diff --git qt/setup.py qt/setup.py
+index 38f4e2b7..bdda3baa 100644
+--- qt/setup.py
++++ qt/setup.py
+@@ -8,7 +8,7 @@ import setuptools
+ def package_files(directory):
+ entries = []
+ for (path, directories, filenames) in os.walk(directory):
+- entries.append((path, [os.path.join(path, f) for f in filenames]))
++ entries.append((os.path.join("share", path), [os.path.join(path, f) for f in filenames]))
+ return entries
+
+
+--
+2.26.2
+
diff --git a/srcpkgs/anki/patches/rust-nightly-fix.patch b/srcpkgs/anki/patches/rust-nightly-fix.patch
new file mode 100644
index 00000000000..3d70aa36aad
--- /dev/null
+++ b/srcpkgs/anki/patches/rust-nightly-fix.patch
@@ -0,0 +1,274 @@
+From fb578a0c2dc391f37de7cb6969c40f34d0de845c Mon Sep 17 00:00:00 2001
+From: Damien Elmes <gpg@ankiweb.net>
+Date: Fri, 24 Apr 2020 13:39:14 +1000
+Subject: [PATCH] switch to owned strings in ParsedTemplate
+
+will make it easier to cache the parsed results in the future,
+and handle field renames & other transformations
+---
+ rslib/src/notetype/cardgen.rs | 6 +-
+ rslib/src/notetype/templates.rs | 2 +-
+ rslib/src/template.rs | 98 +++++++++++++++++----------------
+ 3 files changed, 56 insertions(+), 50 deletions(-)
+
+Backported by fossy to stable. notetype patch is not needed.
+
+diff --git rslib/src/template.rs rslib/src/template.rs
+index 4479899009..ed5fe7e916 100644
+--- rslib/src/template.rs
++++ rslib/src/template.rs
+@@ -147,26 +147,26 @@ fn legacy_tokens(mut data: &str) -> impl Iterator<Item = TemplateResult<Token>>
+ //----------------------------------------
+
+ #[derive(Debug, PartialEq)]
+-enum ParsedNode<'a> {
+- Text(&'a str),
++enum ParsedNode {
++ Text(String),
+ Replacement {
+- key: &'a str,
+- filters: Vec<&'a str>,
++ key: String,
++ filters: Vec<String>,
+ },
+ Conditional {
+- key: &'a str,
+- children: Vec<ParsedNode<'a>>,
++ key: String,
++ children: Vec<ParsedNode>,
+ },
+ NegatedConditional {
+- key: &'a str,
+- children: Vec<ParsedNode<'a>>,
++ key: String,
++ children: Vec<ParsedNode>,
+ },
+ }
+
+ #[derive(Debug)]
+-pub struct ParsedTemplate<'a>(Vec<ParsedNode<'a>>);
++pub struct ParsedTemplate(Vec<ParsedNode>);
+
+-impl ParsedTemplate<'_> {
++impl ParsedTemplate {
+ /// Create a template from the provided text.
+ pub fn from_text(template: &str) -> TemplateResult<ParsedTemplate> {
+ let mut iter = tokens(template);
+@@ -177,26 +177,26 @@ impl ParsedTemplate<'_> {
+ fn parse_inner<'a, I: Iterator<Item = TemplateResult<Token<'a>>>>(
+ iter: &mut I,
+ open_tag: Option<&'a str>,
+-) -> TemplateResult<Vec<ParsedNode<'a>>> {
++) -> TemplateResult<Vec<ParsedNode>> {
+ let mut nodes = vec![];
+
+ while let Some(token) = iter.next() {
+ use Token::*;
+ nodes.push(match token? {
+- Text(t) => ParsedNode::Text(t),
++ Text(t) => ParsedNode::Text(t.into()),
+ Replacement(t) => {
+ let mut it = t.rsplit(':');
+ ParsedNode::Replacement {
+- key: it.next().unwrap(),
+- filters: it.collect(),
++ key: it.next().unwrap().into(),
++ filters: it.map(Into::into).collect(),
+ }
+ }
+ OpenConditional(t) => ParsedNode::Conditional {
+- key: t,
++ key: t.into(),
+ children: parse_inner(iter, Some(t))?,
+ },
+ OpenNegated(t) => ParsedNode::NegatedConditional {
+- key: t,
++ key: t.into(),
+ children: parse_inner(iter, Some(t))?,
+ },
+ CloseConditional(t) => {
+@@ -285,27 +285,27 @@ fn localized_template_error(i18n: &I18n, err: TemplateError) -> String {
+ // Checking if template is empty
+ //----------------------------------------
+
+-impl ParsedTemplate<'_> {
++impl ParsedTemplate {
+ /// true if provided fields are sufficient to render the template
+ pub fn renders_with_fields(&self, nonempty_fields: &HashSet<&str>) -> bool {
+ !template_is_empty(nonempty_fields, &self.0)
+ }
+ }
+
+-fn template_is_empty<'a>(nonempty_fields: &HashSet<&str>, nodes: &[ParsedNode<'a>]) -> bool {
++fn template_is_empty(nonempty_fields: &HashSet<&str>, nodes: &[ParsedNode]) -> bool {
+ use ParsedNode::*;
+ for node in nodes {
+ match node {
+ // ignore normal text
+ Text(_) => (),
+ Replacement { key, .. } => {
+- if nonempty_fields.contains(*key) {
++ if nonempty_fields.contains(key.as_str()) {
+ // a single replacement is enough
+ return false;
+ }
+ }
+ Conditional { key, children } => {
+- if !nonempty_fields.contains(*key) {
++ if !nonempty_fields.contains(key.as_str()) {
+ continue;
+ }
+ if !template_is_empty(nonempty_fields, children) {
+@@ -347,7 +347,7 @@ pub(crate) struct RenderContext<'a> {
+ pub card_ord: u16,
+ }
+
+-impl ParsedTemplate<'_> {
++impl ParsedTemplate {
+ /// Render the template with the provided fields.
+ ///
+ /// Replacements that use only standard filters will become part of
+@@ -373,10 +373,7 @@ fn render_into(
+ Text(text) => {
+ append_str_to_nodes(rendered_nodes, text);
+ }
+- Replacement {
+- key: key @ "FrontSide",
+- ..
+- } => {
++ Replacement { key, .. } if key == "FrontSide" => {
+ // defer FrontSide rendering to Python, as extra
+ // filters may be required
+ rendered_nodes.push(RenderedNode::Replacement {
+@@ -385,27 +382,36 @@ fn render_into(
+ current_text: "".into(),
+ });
+ }
+- Replacement { key: "", filters } if !filters.is_empty() => {
++ Replacement { key, filters } if key == "" && !filters.is_empty() => {
+ // if a filter is provided, we accept an empty field name to
+ // mean 'pass an empty string to the filter, and it will add
+ // its own text'
+ rendered_nodes.push(RenderedNode::Replacement {
+ field_name: "".to_string(),
+ current_text: "".to_string(),
+- filters: filters.iter().map(|&f| f.to_string()).collect(),
++ filters: filters.clone(),
+ })
+ }
+ Replacement { key, filters } => {
+ // apply built in filters if field exists
+- let (text, remaining_filters) = match context.fields.get(key) {
+- Some(text) => apply_filters(text, filters, key, context),
++ let (text, remaining_filters) = match context.fields.get(key.as_str()) {
++ Some(text) => apply_filters(
++ text,
++ filters
++ .iter()
++ .map(|s| s.as_str())
++ .collect::<Vec<_>>()
++ .as_slice(),
++ key,
++ context,
++ ),
+ None => {
+ // unknown field encountered
+ let filters_str = filters
+ .iter()
+ .rev()
+ .cloned()
+- .chain(iter::once(""))
++ .chain(iter::once("".into()))
+ .collect::<Vec<_>>()
+ .join(":");
+ return Err(TemplateError::FieldNotFound {
+@@ -427,12 +433,12 @@ fn render_into(
+ }
+ }
+ Conditional { key, children } => {
+- if context.nonempty_fields.contains(key) {
++ if context.nonempty_fields.contains(key.as_str()) {
+ render_into(rendered_nodes, children.as_ref(), context)?;
+ }
+ }
+ NegatedConditional { key, children } => {
+- if !context.nonempty_fields.contains(key) {
++ if !context.nonempty_fields.contains(key.as_str()) {
+ render_into(rendered_nodes, children.as_ref(), context)?;
+ }
+ }
+@@ -542,7 +548,7 @@ pub enum FieldRequirements {
+ None,
+ }
+
+-impl ParsedTemplate<'_> {
++impl ParsedTemplate {
+ /// Return fields required by template.
+ ///
+ /// This is not able to represent negated expressions or combinations of
+@@ -613,11 +619,11 @@
+ vec![
+- Text("foo "),
++ Text("foo ".into()),
+ Replacement {
+- key: "bar",
++ key: "bar".into(),
+ filters: vec![]
+ },
+- Text(" "),
++ Text(" ".into()),
+ Conditional {
+- key: "baz",
+- children: vec![Text(" quux ")]
++ key: "baz".into(),
++ children: vec![Text(" quux ".into())]
+ }
+ ]
+@@ -630,7 +636,7 @@ mod test {
+ assert_eq!(
+ tmpl.0,
+ vec![NegatedConditional {
+- key: "baz",
++ key: "baz".into(),
+ children: vec![]
+ }]
+ );
+@@ -643,7 +649,7 @@ mod test {
+ assert_eq!(
+ PT::from_text("{{ tag }}").unwrap().0,
+ vec![Replacement {
+- key: "tag",
++ key: "tag".into(),
+ filters: vec![]
+ }]
+ );
+@@ -651,7 +657,7 @@ mod test {
+ // stray closing characters (like in javascript) are ignored
+ assert_eq!(
+ PT::from_text("text }} more").unwrap().0,
+- vec![Text("text }} more")]
++ vec![Text("text }} more".into())]
+ );
+
+ PT::from_text("{{").unwrap_err();
+@@ -737,15 +743,15 @@ mod test {
+ assert_eq!(
+ PT::from_text(input).unwrap().0,
+ vec![
+- Text("\n"),
++ Text("\n".into()),
+ Replacement {
+- key: "Front",
++ key: "Front".into(),
+ filters: vec![]
+ },
+- Text("\n"),
++ Text("\n".into()),
+ Conditional {
+- key: "Back",
+- children: vec![Text("\n")]
++ key: "Back".into(),
++ children: vec![Text("\n".into())]
+ }
+ ]
+ );
diff --git a/srcpkgs/anki/patches/rustc-cross-compile.patch b/srcpkgs/anki/patches/rustc-cross-compile.patch
new file mode 100644
index 00000000000..15239ea4cf1
--- /dev/null
+++ b/srcpkgs/anki/patches/rustc-cross-compile.patch
@@ -0,0 +1,11 @@
+--- rspy/Makefile 2020-05-23 12:02:29.758286838 +1000
++++ rspy/Makefile 2020-05-08 18:17:57.000000000 +1000
+@@ -69,7 +69,7 @@
+ .build/build: $(DEPS)
+ touch ../proto/backend.proto
+ ${BUILD_VARIABLES} \
+- maturin build -i "${PYTHON_FILE}" -o "$(OUTDIR)" $(BUILDFLAGS)
++ maturin build -i "${PYTHON_FILE}" -o "$(OUTDIR)" $(BUILDFLAGS) --target $(RUST_TARGET)
+ touch $@
+
+ check: .build/check
diff --git a/srcpkgs/anki/patches/update-rust-nightly-version.patch b/srcpkgs/anki/patches/update-rust-nightly-version.patch
new file mode 100644
index 00000000000..51e8afa7cf0
--- /dev/null
+++ b/srcpkgs/anki/patches/update-rust-nightly-version.patch
@@ -0,0 +1,5 @@
+--- rspy/rust-toolchain 2020-05-24 08:54:25.130010169 +1000
++++ rspy/rust-toolchain 2020-05-24 18:02:34.496636771 +1000
+@@ -1 +1 @@
+-nightly-2020-02-27
++nightly-2020-05-15
diff --git a/srcpkgs/anki/patches/vendored-deps.patch b/srcpkgs/anki/patches/vendored-deps.patch
new file mode 100644
index 00000000000..1d2bc90ffb1
--- /dev/null
+++ b/srcpkgs/anki/patches/vendored-deps.patch
@@ -0,0 +1,94 @@
+diff -u -r Makefile Makefile
+--- Makefile 2020-05-08 18:17:57.000000000 +1000
++++ Makefile 2020-05-19 18:40:54.345223164 +1000
+@@ -92,7 +92,7 @@
+ fi
+
+ .PHONY: develop
+-develop: pyenv buildhash prepare
++develop: buildhash prepare
+ @set -eu -o pipefail ${SHELLFLAGS}; \
+ . "${ACTIVATE_SCRIPT}"; \
+ for dir in $(DEVEL); do \
+diff -u -r pylib/Makefile pylib/Makefile
+--- pylib/Makefile 2020-05-08 18:17:57.000000000 +1000
++++ pylib/Makefile 2020-05-19 18:50:01.075182994 +1000
+@@ -52,7 +52,7 @@
+ python -m black anki/hooks.py
+ @touch $@
+
+-BUILD_STEPS := .build/vernum .build/run-deps .build/dev-deps .build/py-proto anki/buildinfo.py .build/hooks
++BUILD_STEPS := .build/vernum .build/py-proto anki/buildinfo.py .build/hooks
+
+ # Checking
+ ######################
+diff -u -r qt/Makefile qt/Makefile
+--- qt/Makefile 2020-05-08 18:17:57.000000000 +1000
++++ qt/Makefile 2020-05-19 18:50:17.520181786 +1000
+@@ -64,7 +64,7 @@
+ python -m black aqt/gui_hooks.py
+ @touch $@
+
+-BUILD_STEPS := .build/vernum .build/run-deps .build/dev-deps .build/js .build/ui aqt/buildinfo.py .build/hooks .build/i18n
++BUILD_STEPS := .build/vernum .build/js .build/ui aqt/buildinfo.py .build/hooks .build/i18n
+
+ # Checking
+ ######################
+--- Makefile 2020-05-08 18:17:57.000000000 +1000
++++ Makefile 2020-05-19 19:01:35.602131965 +1000
+@@ -122,7 +122,7 @@
+ @echo "Build complete."
+
+ .PHONY: build-rspy
+-build-rspy: pyenv buildhash
++build-rspy: buildhash
+ @set -eu -o pipefail ${SHELLFLAGS}; \
+ . "${ACTIVATE_SCRIPT}"; \
+ $(SUBMAKE) -C rspy build BUILDFLAGS="$(BUILDFLAGS)"
+--- Makefile 2020-05-19 19:41:44.191955000 +1000
++++ Makefile 2020-05-19 19:42:21.423952264 +1000
+@@ -124,19 +124,16 @@
+ .PHONY: build-rspy
+ build-rspy: buildhash
+ @set -eu -o pipefail ${SHELLFLAGS}; \
+- . "${ACTIVATE_SCRIPT}"; \
+ $(SUBMAKE) -C rspy build BUILDFLAGS="$(BUILDFLAGS)"
+
+ .PHONY: build-pylib
+ build-pylib:
+ @set -eu -o pipefail ${SHELLFLAGS}; \
+- . "${ACTIVATE_SCRIPT}"; \
+ $(SUBMAKE) -C pylib build
+
+ .PHONY: build-qt
+ build-qt:
+ @set -eu -o pipefail ${SHELLFLAGS}; \
+- . "${ACTIVATE_SCRIPT}"; \
+ $(SUBMAKE) -C qt build
+
+ .PHONY: clean
+--- rspy/Makefile 2020-05-21 20:06:35.945720983 +1000
++++ rspy/Makefile 2020-05-21 20:07:54.295720504 +1000
+@@ -86,10 +86,10 @@
+ RUST_TOOLCHAIN := $(shell cat rust-toolchain)
+
+ .build/tools: requirements.txt rust-toolchain
+- python -m pip install -r requirements.txt
+ rustup toolchain install $(RUST_TOOLCHAIN)
+ rustup component add rustfmt-preview --toolchain $(RUST_TOOLCHAIN)
+ rustup component add clippy-preview --toolchain $(RUST_TOOLCHAIN)
++ rustup target add $(RUST_TARGET)
+ @touch $@
+
+ # we should not call clippy because it break things when running make check Mac OS
+--- pylib/Makefile 2020-05-22 08:46:14.988607539 +1000
++++ pylib/Makefile 2020-05-22 08:46:38.376605821 +1000
+@@ -41,7 +41,7 @@
+
+ PROTODEPS := $(wildcard ../proto/*.proto)
+
+-.build/py-proto: .build/dev-deps $(PROTODEPS)
++.build/py-proto: $(PROTODEPS)
+ protoc --proto_path=../proto --python_out=anki --mypy_out=anki $(PROTODEPS)
+ perl -i'' -pe 's/from fluent_pb2/from anki.fluent_pb2/' anki/backend_pb2.pyi
+ perl -i'' -pe 's/import fluent_pb2/import anki.fluent_pb2/' anki/backend_pb2.py
diff --git a/srcpkgs/anki/template b/srcpkgs/anki/template
index 680e008a9d4..ebc5fa6b333 100644
--- a/srcpkgs/anki/template
+++ b/srcpkgs/anki/template
@@ -1,23 +1,66 @@
# Template file for 'anki'
pkgname=anki
-version=2.1.15
-revision=2
-archs=noarch
+version=2.1.26
+revision=1
build_style=gnu-makefile
pycompile_dirs="/usr/share/anki/anki /usr/share/anki/aqt"
+# rustup: anki needs nightly ... :(
+hostmakedepends="git python3 rustup maturin which protobuf
+ mypy-protobuf-python python3-stringcase black python3-wheel
+ rsync nodejs python3-PyQt5-devel-tools gettext
+qt5-translations python3-pip strace"
depends="python3-PyQt5-webengine python3-requests python3-SQLAlchemy
python3-PyAudio python3-mpv python3-Markdown python3-send2trash
- python3-BeautifulSoup4 python3-decorator python3-jsonschema"
+ python3-BeautifulSoup4 python3-decorator python3-jsonschema
+ python3-protobuf"
short_desc="Spaced repetition flashcard program"
maintainer="Steve Prybylski <sa.prybylx@gmail.com>"
license="AGPL-3.0-or-later"
homepage="https://apps.ankiweb.net"
changelog="https://apps.ankiweb.net/docs/changes.html"
-distfiles="https://apps.ankiweb.net/downloads/current/anki-${version}-source.tgz"
-checksum=5a53760164c77d619f55107a13099cffe620566a7f610b61b6c4b52487f3bb89
-
+distfiles="https://github.com/ankitects/anki/archive/${version}.tar.gz"
+checksum=f5a0c41f3eebe0e77de9d46f2a5cbbe20f7c3a4787f0f02e1d33f298428acbdf
python_version=3
+# When a non-clean masterdir is used, rust is often left over from a
+# previous rust-enabled build. Unfortunatly, xbps-src dosen't seem
+# to clean out rust -.- So, use /usr/rustup, to avoid this issue.
+export PATH=/usr/rustup/bin:${PATH}
+export LD_LIBRARY_PATH=/usr/rustup/lib:${LD_LIBRARY_PATH}
+export CARGO_HOME="${wrksrc}/rustup"
+export RUSTUP_HOME="${wrksrc}/rustup"
+
+pre_configure() {
+ printf "1\\n" | rustup-init -y
+}
+
+pre_build() {
+ mkdir -p dist
+ make prepare
+}
+
+do_build() {
+ RUSTFLAGS="-C target-feature=-crt-static" make build
+}
+
+do_install() {
+ pushd pylib
+ python3 setup.py install --prefix=/usr --root=${DESTDIR}
+ popd
+
+ pushd qt
+ python3 setup.py install --prefix=/usr --root=${DESTDIR}
+ popd
+
+ # maturin generates a .whl, this is all we can do
+ PIP_CONFIG_FILE=/dev/null pip3 install --isolated --root=${DESTDIR} --prefix=/usr --ignore-installed --no-deps dist/ankirspy*.whl
+
+ # Copied from arch's PKGBUILD
+ install -Dm755 qt/runanki "${DESTDIR}/usr/bin/anki"
+ install -Dm644 qt/anki.desktop "${DESTDIR}/usr/share/applications/anki.desktop"
+ install -Dm644 qt/anki.png "${DESTDIR}/usr/share/pixmaps/anki.png"
+}
+
post_install() {
vlicense LICENSE
}
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PR PATCH] [Updated] WIP: anki: update to 2.1.26
2020-05-23 6:18 [PR PATCH] WIP: anki: update to 2.1.26 fosslinux
` (4 preceding siblings ...)
2020-05-30 1:53 ` fosslinux
@ 2020-06-01 9:58 ` fosslinux
2020-06-01 9:59 ` fosslinux
` (6 subsequent siblings)
12 siblings, 0 replies; 14+ messages in thread
From: fosslinux @ 2020-06-01 9:58 UTC (permalink / raw)
To: ml
[-- Attachment #1: Type: text/plain, Size: 2262 bytes --]
There is an updated pull request by fosslinux against master on the void-packages repository
https://github.com/fosslinux/void-packages anki-2.1.26
https://github.com/void-linux/void-packages/pull/22219
WIP: anki: update to 2.1.26
This has a wide variety of changes as if you have heard my ranting in #xbps it has turned into a Bad Build System - there is rust (nightly!), nodejs, python, etc etc, no proper install target...
A few things to note:
- python3-mypy is updated as mypy-protobuf needs the new version, otherwise the build failed.
- same thing with python-protobuf, but for anki and at runtime
- maturin is some weird build system at the intersection of rust and python.
- mypy-protobuf-python is what anki uses for binding python and rust together, partly.
- mypy-protobuf-go is the go implementation of mypy-protobuf-python that I thought should be packaged anywway.
- python-stringcase is a new dependency.
- anki is an archd package (not nocross), because the rust code is obviously platform specific.
- anki uses rustup. This is because it and some of its dependencies require archd code (notably pyo3). This is unavoidable, afaict.
Still todo:
- [x] Apply archlinux's aqt_build patch, which stops it from polluting /usr directly (:vomiting_face:)
- [x] Update python3-protobuf - hopefully will fix `AttributeError: module 'google.protobuf.descriptor' has no attribute '_internal_create_key'`.
- [x] Look into travis musl error. https://github.com/rust-lang/rust/issues/40174. Hopefully, using rust 1.44 as the rust version *should* fix this. What a PITA. I understand that this is because it works when I cross-compile to x86_64-musl from x86_64 but we need it to work native build from x86_64-musl for the builders...
- [ ] Get off rustup and onto rust stable. Needs either a) pyo3 to work on stable or b) anki to be patched for rust-cpython. Also blocked by rust 1.44.
- [ ] Travis wth on i686?
- [x] Make it open.
- [ ] More extensive runtime testing.
- [ ] Runtime test on musl.
Questions:
- Is there any problems with removing `arch=nocross`?
- Does the rustup stuff look (somewhat) sane?
- Are the patches sane?
A patch file from https://github.com/void-linux/void-packages/pull/22219.patch is attached
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: github-pr-anki-2.1.26-22219.patch --]
[-- Type: text/x-diff, Size: 330225 bytes --]
From dc49d200c37f20e082261214f30c9f0ec0a316a3 Mon Sep 17 00:00:00 2001
From: fosslinux <fosslinux@aussies.space>
Date: Sat, 23 May 2020 14:33:01 +1000
Subject: [PATCH 1/6] python3-mypy: update to 0.770, claim maintainership
---
srcpkgs/python3-mypy/template | 7 +++----
1 file changed, 3 insertions(+), 4 deletions(-)
diff --git a/srcpkgs/python3-mypy/template b/srcpkgs/python3-mypy/template
index 5d7f93d5772..bde1e7f4be6 100644
--- a/srcpkgs/python3-mypy/template
+++ b/srcpkgs/python3-mypy/template
@@ -1,19 +1,18 @@
# Template file for 'python3-mypy'
pkgname=python3-mypy
-version=0.761
+version=0.770
revision=1
archs=noarch
wrksrc="mypy-${version}"
build_style=python3-module
-pycompile_module="mypy"
hostmakedepends="python3-setuptools"
depends="python3-mypy_extensions python3-typed-ast python3-typing_extensions"
short_desc="Optional static typing for Python3"
-maintainer="Orphaned <orphan@voidlinux.org>"
+maintainer="fosslinux <fosslinux@aussies.space>"
license="MIT"
homepage="https://github.com/python/mypy"
distfiles="${PYPI_SITE}/m/mypy/mypy-${version}.tar.gz"
-checksum=85baab8d74ec601e86134afe2bcccd87820f79d2f8d5798c889507d1088287bf
+checksum=8a627507ef9b307b46a1fea9513d5c98680ba09591253082b4c48697ba05a4ae
post_install() {
vlicense LICENSE
From 7c67feaeffb4ddbdef9fbe1a0459ac5ac5ecc439 Mon Sep 17 00:00:00 2001
From: fosslinux <fosslinux@aussies.space>
Date: Sat, 23 May 2020 14:34:38 +1000
Subject: [PATCH 2/6] New package: maturin-0.8.1
---
.../patches/cross-compile-setup-py.patch | 14 +++++++++++++
srcpkgs/maturin/template | 21 +++++++++++++++++++
2 files changed, 35 insertions(+)
create mode 100644 srcpkgs/maturin/patches/cross-compile-setup-py.patch
create mode 100644 srcpkgs/maturin/template
diff --git a/srcpkgs/maturin/patches/cross-compile-setup-py.patch b/srcpkgs/maturin/patches/cross-compile-setup-py.patch
new file mode 100644
index 00000000000..e57189cb7ab
--- /dev/null
+++ b/srcpkgs/maturin/patches/cross-compile-setup-py.patch
@@ -0,0 +1,14 @@
+--- setup.py 2020-04-30 22:36:01.000000000 +1000
++++ setup.py 2020-05-20 14:31:40.404994499 +1000
+@@ -56,9 +56,9 @@
+ "(https://www.rust-lang.org/tools/install) and try again"
+ )
+ subprocess.check_call(
+- ["cargo", "rustc", "--bin", "maturin", "--", "-C", "link-arg=-s"]
++ ["cargo", "rustc", "--bin", "maturin", "--release", "--target", os.environ["RUST_TARGET"], "--", "-C", "link-arg=-s", "-C", "linker=" + os.environ["CC"].split(" ", 1)[0]]
+ )
+- source = os.path.join(source_dir, "target", "debug", executable_name)
++ source = os.path.join(source_dir, "target", os.environ["RUST_TARGET"], "release", executable_name)
+ # run this after trying to build with cargo (as otherwise this leaves
+ # venv in a bad state: https://github.com/benfred/py-spy/issues/69)
+ install.run(self)
diff --git a/srcpkgs/maturin/template b/srcpkgs/maturin/template
new file mode 100644
index 00000000000..7eba36204f9
--- /dev/null
+++ b/srcpkgs/maturin/template
@@ -0,0 +1,21 @@
+# Template file for 'maturin'
+pkgname=maturin
+version=0.8.1
+revision=1
+build_style=python3-module
+hostmakedepends="cargo python3-setuptools python3-toml"
+makedepends="rust rust-std llvm9"
+short_desc="Build and publish crates with python bindings"
+maintainer="fosslinux <fosslinux@aussies.space>"
+license="Apache-2.0, MIT"
+homepage="https://github.com/PyO3/maturin"
+distfiles="https://github.com/PyO3/maturin/archive/v${version}.tar.gz"
+checksum=b72a9885cda3ba4e53906a43aab101acb790622218ade6405b2ddf1ef1461f8f
+
+post_install() {
+ # Dynamic detection of python version
+ PYTHON_VERSION=$(python3 --version | sed "s/^Python //" | rev | sed "s/^[0-9]*.//" | rev)
+ mkdir -p "${DESTDIR}/usr/lib/python${PYTHON_VERSION}/site-packages/"
+ mv "${DESTDIR}/maturin" "${DESTDIR}/usr/lib/python${PYTHON_VERSION}/site-packages/"
+ vlicense license-mit
+}
From 96de4dbb3c34bf4961ba0c1f601205b1215dc700 Mon Sep 17 00:00:00 2001
From: fosslinux <fosslinux@aussies.space>
Date: Sat, 23 May 2020 14:35:25 +1000
Subject: [PATCH 3/6] New package: mypy-protobuf-python-1.13
---
srcpkgs/mypy-protobuf-python/template | 23 +++++++++++++++++++++++
1 file changed, 23 insertions(+)
create mode 100644 srcpkgs/mypy-protobuf-python/template
diff --git a/srcpkgs/mypy-protobuf-python/template b/srcpkgs/mypy-protobuf-python/template
new file mode 100644
index 00000000000..391d75f0c9e
--- /dev/null
+++ b/srcpkgs/mypy-protobuf-python/template
@@ -0,0 +1,23 @@
+# Template file for 'mypy-protobuf-python'
+#
+# WARNING: THIS TEMPLATE SHOULD BE SYNCRONISED WITH mypy-protobuf-go
+#
+pkgname=mypy-protobuf-python
+version=1.13
+revision=1
+wrksrc="mypy-protobuf-${version}"
+build_wrksrc=python
+build_style=python3-module
+hostmakedepends="python3-setuptools"
+depends="python3-mypy python3-typing_extensions python3-protobuf protobuf"
+short_desc="Generate mypy stubs from protobufs - Python implementation"
+maintainer="fosslinux <fosslinux@aussies.space>"
+license="Apache-2.0"
+homepage="https://github.com/dropbox/mypy-protobuf"
+distfiles="https://github.com/dropbox/mypy-protobuf/archive/v${version}.tar.gz"
+checksum=7d86dfc076f8b51814fbfd3a66998a0b570fd1b82ebeda68ae6728cd538adb74
+
+post_install() {
+ # We are not windows, remove the batch file
+ rm "${DESTDIR}/usr/bin/protoc_gen_mypy.bat"
+}
From aeaa9e6a25d47eedecac921e56d647d93d3f46ad Mon Sep 17 00:00:00 2001
From: fosslinux <fosslinux@aussies.space>
Date: Sat, 23 May 2020 14:35:37 +1000
Subject: [PATCH 4/6] New package: mypy-protobuf-go-1.13
---
.../patches/remote-go-improt.patch | 11 +++++++++++
srcpkgs/mypy-protobuf-go/template | 19 +++++++++++++++++++
2 files changed, 30 insertions(+)
create mode 100644 srcpkgs/mypy-protobuf-go/patches/remote-go-improt.patch
create mode 100644 srcpkgs/mypy-protobuf-go/template
diff --git a/srcpkgs/mypy-protobuf-go/patches/remote-go-improt.patch b/srcpkgs/mypy-protobuf-go/patches/remote-go-improt.patch
new file mode 100644
index 00000000000..300504bc70d
--- /dev/null
+++ b/srcpkgs/mypy-protobuf-go/patches/remote-go-improt.patch
@@ -0,0 +1,11 @@
+--- go/src/protoc-gen-mypy/main.go.orig 2020-05-22 11:58:07.760761664 +1000
++++ go/src/protoc-gen-mypy/main.go 2020-05-22 11:58:00.595762190 +1000
+@@ -6,7 +6,7 @@
+ "sort"
+ "strings"
+
+- "proto/mypy"
++ "github.com/dropbox/mypy-protobuf/go/src/proto/mypy"
+
+ "github.com/gogo/protobuf/proto"
+ "github.com/gogo/protobuf/protoc-gen-gogo/descriptor"
diff --git a/srcpkgs/mypy-protobuf-go/template b/srcpkgs/mypy-protobuf-go/template
new file mode 100644
index 00000000000..8f00e43d8a8
--- /dev/null
+++ b/srcpkgs/mypy-protobuf-go/template
@@ -0,0 +1,19 @@
+# Template file for 'mypy-protobuf-go'
+#
+# WARNING: THIS TEMPLATE SHOULD BE SYNCRONISED WITH mypy-protobuf-python
+#
+pkgname=mypy-protobuf-go
+version=1.13
+revision=1
+wrksrc="mypy-protobuf-${version}"
+build_style=go
+go_import_path="github.com/dropbox/mypy-protobuf"
+go_package="${go_import_path}/go/src/protoc-gen-mypy"
+hostmakedepends="git"
+depends="protobuf"
+short_desc="Generate mypy stubs from protobufs - go implementation"
+maintainer="fosslinux <fosslinux@aussies.space>"
+license="Apache-2.0"
+homepage="https://github.com/dropbox/mypy-protobuf"
+distfiles="https://github.com/dropbox/mypy-protobuf/archive/v${version}.tar.gz"
+checksum=7d86dfc076f8b51814fbfd3a66998a0b570fd1b82ebeda68ae6728cd538adb74
From e6d8f76eeb38c0a55f56ca0c4800d1d6d3c71c75 Mon Sep 17 00:00:00 2001
From: fosslinux <fosslinux@aussies.space>
Date: Sat, 23 May 2020 14:33:36 +1000
Subject: [PATCH 5/6] New package: python-stringcase-1.2.0
---
srcpkgs/python-stringcase/template | 28 ++++++++++++++++++++++++++++
srcpkgs/python3-stringcase | 1 +
2 files changed, 29 insertions(+)
create mode 100644 srcpkgs/python-stringcase/template
create mode 120000 srcpkgs/python3-stringcase
diff --git a/srcpkgs/python-stringcase/template b/srcpkgs/python-stringcase/template
new file mode 100644
index 00000000000..849e677c784
--- /dev/null
+++ b/srcpkgs/python-stringcase/template
@@ -0,0 +1,28 @@
+# Template file for 'python-stringcase'
+pkgname=python-stringcase
+version=1.2.0
+revision=1
+wrksrc="stringcase-${version}"
+build_style=python-module
+hostmakedepends="python-devel python3-devel"
+makedepends="${hostmakedepends}"
+depends="python"
+short_desc="String case converter for Python2"
+maintainer="fosslinux <fosslinux@aussies.space>"
+license="MIT"
+homepage="https://github.com/okunishinishi/python-stringcase"
+distfiles="${PYPI_SITE}/s/stringcase/stringcase-${version}.tar.gz"
+checksum=48a06980661908efe8d9d34eab2b6c13aefa2163b3ced26972902e3bdfd87008
+
+post_install() {
+ vlicense LICENSE
+}
+
+python3-stringcase_package() {
+ depends="python3"
+ short_desc="${short_desc/Python2/Python3}"
+ pkg_install() {
+ vmove usr/lib/python3*
+ vlicense LICENSE
+ }
+}
diff --git a/srcpkgs/python3-stringcase b/srcpkgs/python3-stringcase
new file mode 120000
index 00000000000..53938bd1f0c
--- /dev/null
+++ b/srcpkgs/python3-stringcase
@@ -0,0 +1 @@
+python-stringcase
\ No newline at end of file
From 87202f92b8a4a31bc944b5e99e57220f76bcf8d2 Mon Sep 17 00:00:00 2001
From: fosslinux <fosslinux@aussies.space>
Date: Sat, 23 May 2020 14:36:21 +1000
Subject: [PATCH 6/6] anki: update to 2.1.26
Has turned into a Bad Build System. Now uses rust nightly, python
(with bindings!), qt5, nodejs... the list goes on. There are quite
a few hacks and the like.
---
...1da60c6c00fc8cd930efa34113a602a830e2.patch | 118 +
...2423c8e293f843115f617d04213f04f63a77.patch | 134 ++
...13bce9c80b0e7ff37c5317705ce0acf32c15.patch | 1209 ++++++++++
...28e23ab3dab4eaa2277734019f1b8e0210c1.patch | 1978 +++++++++++++++++
...fec729e00355bbd067e5770a9e8e889280cf.patch | 1659 ++++++++++++++
...1da60c6c00fc8cd930efa34113a602a830e2.patch | 69 +
...2948d9147689701a24de2fcdffafc32ebe62.patch | 93 +
...c30b15f467c9f5ab139564be0099fba5b27f.patch | 159 ++
...7c2ad89dad6be5cf454fe0012d9aba9e60b2.patch | 1387 ++++++++++++
...10fcd8932c3d83fe73b07412969cc42ff686.patch | 38 +
...2a4b93b16ba9b7b43a1c73614efbcb6e9814.patch | 732 ++++++
...58f18c02de6ab9dd9a6b96fd97a935d6f9b5.patch | 1321 +++++++++++
.../0020-remove-nightly-check.patch | 17 +
srcpkgs/anki/patches/0001-aqt_data-fhs.patch | 45 +
.../anki/patches/0002-rust-nightly-fix.patch | 274 +++
.../patches/0003-rustc-cross-compile.patch | 11 +
srcpkgs/anki/patches/0004-vendored-deps.patch | 91 +
srcpkgs/anki/patches/0005-patched-pyo3.patch | 11 +
srcpkgs/anki/template | 69 +-
19 files changed, 9408 insertions(+), 7 deletions(-)
create mode 100644 srcpkgs/anki/files/pyo3-patches/0001-stub-tests-b0561da60c6c00fc8cd930efa34113a602a830e2.patch
create mode 100644 srcpkgs/anki/files/pyo3-patches/0002-sequence-prepatch-d57f2423c8e293f843115f617d04213f04f63a77.patch
create mode 100644 srcpkgs/anki/files/pyo3-patches/0010-specialization-cb1313bce9c80b0e7ff37c5317705ce0acf32c15.patch
create mode 100644 srcpkgs/anki/files/pyo3-patches/0011-specialization-89c028e23ab3dab4eaa2277734019f1b8e0210c1.patch
create mode 100644 srcpkgs/anki/files/pyo3-patches/0012-specialization-2f4dfec729e00355bbd067e5770a9e8e889280cf.patch
create mode 100644 srcpkgs/anki/files/pyo3-patches/0013-specialization-b0561da60c6c00fc8cd930efa34113a602a830e2.patch
create mode 100644 srcpkgs/anki/files/pyo3-patches/0014-specialization-c7e52948d9147689701a24de2fcdffafc32ebe62.patch
create mode 100644 srcpkgs/anki/files/pyo3-patches/0015-specialization-81f2c30b15f467c9f5ab139564be0099fba5b27f.patch
create mode 100644 srcpkgs/anki/files/pyo3-patches/0016-specialization-eb617c2ad89dad6be5cf454fe0012d9aba9e60b2.patch
create mode 100644 srcpkgs/anki/files/pyo3-patches/0017-specialization-c27d10fcd8932c3d83fe73b07412969cc42ff686.patch
create mode 100644 srcpkgs/anki/files/pyo3-patches/0018-specialization-d6102a4b93b16ba9b7b43a1c73614efbcb6e9814.patch
create mode 100644 srcpkgs/anki/files/pyo3-patches/0019-specialization-ac0158f18c02de6ab9dd9a6b96fd97a935d6f9b5.patch
create mode 100644 srcpkgs/anki/files/pyo3-patches/0020-remove-nightly-check.patch
create mode 100644 srcpkgs/anki/patches/0001-aqt_data-fhs.patch
create mode 100644 srcpkgs/anki/patches/0002-rust-nightly-fix.patch
create mode 100644 srcpkgs/anki/patches/0003-rustc-cross-compile.patch
create mode 100644 srcpkgs/anki/patches/0004-vendored-deps.patch
create mode 100644 srcpkgs/anki/patches/0005-patched-pyo3.patch
diff --git a/srcpkgs/anki/files/pyo3-patches/0001-stub-tests-b0561da60c6c00fc8cd930efa34113a602a830e2.patch b/srcpkgs/anki/files/pyo3-patches/0001-stub-tests-b0561da60c6c00fc8cd930efa34113a602a830e2.patch
new file mode 100644
index 00000000000..5a3f02afe94
--- /dev/null
+++ b/srcpkgs/anki/files/pyo3-patches/0001-stub-tests-b0561da60c6c00fc8cd930efa34113a602a830e2.patch
@@ -0,0 +1,118 @@
+From b0561da60c6c00fc8cd930efa34113a602a830e2 Mon Sep 17 00:00:00 2001
+From: Donlon <mdonlon@treyarch.com>
+Date: Wed, 30 Oct 2019 07:02:06 -0700
+Subject: [PATCH] Stubbed out a bunch of tests
+
+---
+ .../{test_arithmetics.rs => test_arithmetics.rp} | 0
+ ...uffer_protocol.rs => test_buffer_protocol.rp} | 0
+ tests/{test_bytes.rs => test_bytes.rp} | 0
+ tests/{test_class_new.rs => test_class_new.rp} | 0
+ ...st_compile_error.rs => test_compile_error.rp} | 0
+ tests/{test_datetime.rs => test_datetime.rp} | 0
+ tests/{test_dict_iter.rs => test_dict_iter.rp} | 0
+ tests/{test_dunder.rs => test_dunder.rp} | 0
+ tests/{test_exceptions.rs => test_exceptions.rp} | 0
+ tests/{test_gc.rs => test_gc.rp} | 0
+ ...st_getter_setter.rs => test_getter_setter.rp} | 0
+ .../{test_inheritance.rs => test_inheritance.rp} | 0
+ tests/{test_methods.rs => test_methods.rp} | 0
+ tests/{test_module.rs => test_module.rp} | 0
+ tests/{test_pyself.rs => test_pyself.rp} | 0
+ tests/{test_sequence.rs => test_sequence.rp} | 0
+ tests/{test_string.rs => test_string.rp} | 0
+ ...e_arguments.rs => test_variable_arguments.rp} | 0
+ tests/{test_various.rs => test_various.rp} | 0
+ rename tests/{test_arithmetics.rs => test_arithmetics.rp} (100%)
+ mode change 100755 => 100644
+ rename tests/{test_buffer_protocol.rs => test_buffer_protocol.rp} (100%)
+ rename tests/{test_bytes.rs => test_bytes.rp} (100%)
+ rename tests/{test_class_new.rs => test_class_new.rp} (100%)
+ rename tests/{test_compile_error.rs => test_compile_error.rp} (100%)
+ mode change 100755 => 100644
+ rename tests/{test_datetime.rs => test_datetime.rp} (100%)
+ rename tests/{test_dict_iter.rs => test_dict_iter.rp} (100%)
+ rename tests/{test_dunder.rs => test_dunder.rp} (100%)
+ mode change 100755 => 100644
+ rename tests/{test_exceptions.rs => test_exceptions.rp} (100%)
+ rename tests/{test_gc.rs => test_gc.rp} (100%)
+ rename tests/{test_getter_setter.rs => test_getter_setter.rp} (100%)
+ rename tests/{test_inheritance.rs => test_inheritance.rp} (100%)
+ rename tests/{test_methods.rs => test_methods.rp} (100%)
+ rename tests/{test_module.rs => test_module.rp} (100%)
+ rename tests/{test_pyself.rs => test_pyself.rp} (100%)
+ rename tests/{test_sequence.rs => test_sequence.rp} (100%)
+ rename tests/{test_string.rs => test_string.rp} (100%)
+ rename tests/{test_variable_arguments.rs => test_variable_arguments.rp} (100%)
+ rename tests/{test_various.rs => test_various.rp} (100%)
+
+diff --git a/tests/test_arithmetics.rs b/tests/test_arithmetics.rp
+old mode 100755
+new mode 100644
+similarity index 100%
+rename from tests/test_arithmetics.rs
+rename to tests/test_arithmetics.rp
+diff --git a/tests/test_buffer_protocol.rs b/tests/test_buffer_protocol.rp
+similarity index 100%
+rename from tests/test_buffer_protocol.rs
+rename to tests/test_buffer_protocol.rp
+diff --git a/tests/test_compile_error.rs b/tests/test_compile_error.rp
+old mode 100755
+new mode 100644
+similarity index 100%
+rename from tests/test_compile_error.rs
+rename to tests/test_compile_error.rp
+diff --git a/tests/test_datetime.rs b/tests/test_datetime.rp
+similarity index 100%
+rename from tests/test_datetime.rs
+rename to tests/test_datetime.rp
+diff --git a/tests/test_dict_iter.rs b/tests/test_dict_iter.rp
+similarity index 100%
+rename from tests/test_dict_iter.rs
+rename to tests/test_dict_iter.rp
+diff --git a/tests/test_dunder.rs b/tests/test_dunder.rp
+old mode 100755
+new mode 100644
+similarity index 100%
+rename from tests/test_dunder.rs
+rename to tests/test_dunder.rp
+diff --git a/tests/test_exceptions.rs b/tests/test_exceptions.rp
+similarity index 100%
+rename from tests/test_exceptions.rs
+rename to tests/test_exceptions.rp
+diff --git a/tests/test_gc.rs b/tests/test_gc.rp
+similarity index 100%
+rename from tests/test_gc.rs
+rename to tests/test_gc.rp
+diff --git a/tests/test_getter_setter.rs b/tests/test_getter_setter.rp
+similarity index 100%
+rename from tests/test_getter_setter.rs
+rename to tests/test_getter_setter.rp
+diff --git a/tests/test_inheritance.rs b/tests/test_inheritance.rp
+similarity index 100%
+rename from tests/test_inheritance.rs
+rename to tests/test_inheritance.rp
+diff --git a/tests/test_methods.rs b/tests/test_methods.rp
+similarity index 100%
+rename from tests/test_methods.rs
+rename to tests/test_methods.rp
+diff --git a/tests/test_module.rs b/tests/test_module.rp
+similarity index 100%
+rename from tests/test_module.rs
+rename to tests/test_module.rp
+diff --git a/tests/test_pyself.rs b/tests/test_pyself.rp
+similarity index 100%
+rename from tests/test_pyself.rs
+rename to tests/test_pyself.rp
+diff --git a/tests/test_sequence.rs b/tests/test_sequence.rp
+similarity index 100%
+rename from tests/test_sequence.rs
+rename to tests/test_sequence.rp
+diff --git a/tests/test_variable_arguments.rs b/tests/test_variable_arguments.rp
+similarity index 100%
+rename from tests/test_variable_arguments.rs
+rename to tests/test_variable_arguments.rp
+diff --git a/tests/test_various.rs b/tests/test_various.rp
+similarity index 100%
+rename from tests/test_various.rs
+rename to tests/test_various.rp
diff --git a/srcpkgs/anki/files/pyo3-patches/0002-sequence-prepatch-d57f2423c8e293f843115f617d04213f04f63a77.patch b/srcpkgs/anki/files/pyo3-patches/0002-sequence-prepatch-d57f2423c8e293f843115f617d04213f04f63a77.patch
new file mode 100644
index 00000000000..957690f295a
--- /dev/null
+++ b/srcpkgs/anki/files/pyo3-patches/0002-sequence-prepatch-d57f2423c8e293f843115f617d04213f04f63a77.patch
@@ -0,0 +1,134 @@
+diff --git a/src/class/sequence.rs b/src/class/sequence.rs
+index 0f9ca44b..5414704a 100644
+--- a/src/class/sequence.rs
++++ b/src/class/sequence.rs
+@@ -212,60 +212,6 @@ where
+ }
+ }
+
+-trait PySequenceSetItemProtocolImpl {
+- fn sq_ass_item() -> Option<ffi::ssizeobjargproc>;
+-}
+-
+-impl<'p, T> PySequenceSetItemProtocolImpl for T
+-where
+- T: PySequenceProtocol<'p>,
+-{
+- default fn sq_ass_item() -> Option<ffi::ssizeobjargproc> {
+- None
+- }
+-}
+-
+-impl<T> PySequenceSetItemProtocolImpl for T
+-where
+- T: for<'p> PySequenceSetItemProtocol<'p>,
+-{
+- fn sq_ass_item() -> Option<ffi::ssizeobjargproc> {
+- unsafe extern "C" fn wrap<T>(
+- slf: *mut ffi::PyObject,
+- key: ffi::Py_ssize_t,
+- value: *mut ffi::PyObject,
+- ) -> c_int
+- where
+- T: for<'p> PySequenceSetItemProtocol<'p>,
+- {
+- let py = Python::assume_gil_acquired();
+- let _pool = crate::GILPool::new(py);
+- let slf = py.mut_from_borrowed_ptr::<T>(slf);
+-
+- let result = if value.is_null() {
+- Err(PyErr::new::<exceptions::NotImplementedError, _>(format!(
+- "Item deletion not supported by {:?}",
+- stringify!(T)
+- )))
+- } else {
+- let value = py.from_borrowed_ptr::<PyAny>(value);
+- match value.extract() {
+- Ok(value) => slf.__setitem__(key.into(), value).into(),
+- Err(e) => Err(e),
+- }
+- };
+- match result {
+- Ok(_) => 0,
+- Err(e) => {
+- e.restore(py);
+- -1
+- }
+- }
+- }
+- Some(wrap::<T>)
+- }
+-}
+-
+ /// It can be possible to delete and set items (PySequenceSetItemProtocol and
+ /// PySequenceDelItemProtocol implemented), only to delete (PySequenceDelItemProtocol implemented)
+ /// or no deleting or setting is possible
+@@ -286,11 +232,68 @@ mod sq_ass_item_impl {
+ Some(del_set_item)
+ } else if let Some(del_item) = T::del_item() {
+ Some(del_item)
++ } else if let Some(set_item) = T::set_item() {
++ Some(set_item)
+ } else {
+ None
+ }
+ }
+
++ trait SetItem {
++ fn set_item() -> Option<ffi::ssizeobjargproc>;
++ }
++
++ impl<'p, T> SetItem for T
++ where
++ T: PySequenceProtocol<'p>,
++ {
++ default fn set_item() -> Option<ffi::ssizeobjargproc> {
++ None
++ }
++ }
++
++ impl<T> SetItem for T
++ where
++ T: for<'p> PySequenceSetItemProtocol<'p>,
++ {
++ fn set_item() -> Option<ffi::ssizeobjargproc> {
++ unsafe extern "C" fn wrap<T>(
++ slf: *mut ffi::PyObject,
++ key: ffi::Py_ssize_t,
++ value: *mut ffi::PyObject,
++ ) -> c_int
++ where
++ T: for<'p> PySequenceSetItemProtocol<'p>,
++ {
++ let py = Python::assume_gil_acquired();
++ let _pool = crate::GILPool::new(py);
++ let slf = py.mut_from_borrowed_ptr::<T>(slf);
++
++ let result = if value.is_null() {
++ Err(PyErr::new::<exceptions::NotImplementedError, _>(format!(
++ "Item deletion is not supported by {:?}",
++ stringify!(T)
++ )))
++ } else {
++ let value = py.from_borrowed_ptr::<PyAny>(value);
++ match value.extract() {
++ Ok(value) => slf.__setitem__(key.into(), value).into(),
++ Err(e) => Err(e),
++ }
++ };
++
++ match result {
++ Ok(_) => 0,
++ Err(e) => {
++ e.restore(py);
++ -1
++ }
++ }
++ }
++ Some(wrap::<T>)
++ }
++ }
++
+ trait DelItem {
+ fn del_item() -> Option<ffi::ssizeobjargproc>;
+ }
diff --git a/srcpkgs/anki/files/pyo3-patches/0010-specialization-cb1313bce9c80b0e7ff37c5317705ce0acf32c15.patch b/srcpkgs/anki/files/pyo3-patches/0010-specialization-cb1313bce9c80b0e7ff37c5317705ce0acf32c15.patch
new file mode 100644
index 00000000000..53cf0172ba2
--- /dev/null
+++ b/srcpkgs/anki/files/pyo3-patches/0010-specialization-cb1313bce9c80b0e7ff37c5317705ce0acf32c15.patch
@@ -0,0 +1,1209 @@
+From cb1313bce9c80b0e7ff37c5317705ce0acf32c15 Mon Sep 17 00:00:00 2001
+From: Martin Donlon <github-martin@donlons.com>
+Date: Fri, 25 Oct 2019 20:51:08 -0700
+Subject: [PATCH] Revert "Run `cargo fmt` on source code and update
+ `CHANGELOG.md`"
+
+This reverts commit 33bf37d3d8ca08d3af39de22547e32e7c8eb0f54.
+---
+ CHANGELOG.md | 1 -
+ pyo3-derive-backend/src/pymethod.rs | 6 +-
+ src/class/basic.rs | 55 ++-----
+ src/class/buffer.rs | 5 +-
+ src/class/context.rs | 10 +-
+ src/class/descr.rs | 10 +-
+ src/class/gc.rs | 10 +-
+ src/class/iter.rs | 10 +-
+ src/class/mapping.rs | 40 +----
+ src/class/number.rs | 245 ++++++----------------------
+ src/class/pyasync.rs | 25 +--
+ src/class/sequence.rs | 45 +----
+ src/conversion.rs | 5 +-
+ 13 files changed, 95 insertions(+), 372 deletions(-)
+
+diff --git a/CHANGELOG.md b/CHANGELOG.md
+index a3aff9b31..482e9b01d 100644
+--- a/CHANGELOG.md
++++ b/CHANGELOG.md
+@@ -27,7 +27,6 @@ and `PyString::to_string_lossy` [#642](https://github.com/PyO3/pyo3/pull/642).
+ ### Fixed
+
+ * Make sure the right Python interpreter is used in OSX builds. [#604](https://github.com/PyO3/pyo3/pull/604)
+- * Patch specialization being broken by Rust 1.40. [#614](https://github.com/PyO3/pyo3/issues/614)
+ * Fix a segfault around PyErr. [#597](https://github.com/PyO3/pyo3/pull/597)
+
+ ## [0.8.0] - 2018-09-05
+diff --git a/pyo3-derive-backend/src/pymethod.rs b/pyo3-derive-backend/src/pymethod.rs
+index 2f561cb9d..8c867a567 100644
+--- a/pyo3-derive-backend/src/pymethod.rs
++++ b/pyo3-derive-backend/src/pymethod.rs
+@@ -38,7 +38,7 @@ pub fn gen_py_method(
+ return Err(syn::Error::new_spanned(
+ spec.args[0].ty,
+ "Getter function can only have one argument of type pyo3::Python!",
+- ));
++ ))
+ }
+ };
+ impl_py_getter_def(name, doc, getter, &impl_wrap_getter(cls, name, takes_py))
+@@ -60,10 +60,10 @@ fn check_generic(name: &syn::Ident, sig: &syn::Signature) -> syn::Result<()> {
+ match param {
+ syn::GenericParam::Lifetime(_) => {}
+ syn::GenericParam::Type(_) => {
+- return Err(syn::Error::new_spanned(param, err_msg("type")));
++ return Err(syn::Error::new_spanned(param, err_msg("type")))
+ }
+ syn::GenericParam::Const(_) => {
+- return Err(syn::Error::new_spanned(param, err_msg("const")));
++ return Err(syn::Error::new_spanned(param, err_msg("const")))
+ }
+ }
+ }
+diff --git a/src/class/basic.rs b/src/class/basic.rs
+index 8c670bf82..29e19871f 100644
+--- a/src/class/basic.rs
++++ b/src/class/basic.rs
+@@ -202,10 +202,7 @@ trait GetAttrProtocolImpl {
+ fn tp_getattro() -> Option<ffi::binaryfunc>;
+ }
+
+-impl<'p, T> GetAttrProtocolImpl for T
+-where
+- T: PyObjectProtocol<'p>,
+-{
++impl<'p, T> GetAttrProtocolImpl for T where T: PyObjectProtocol<'p> {
+ default fn tp_getattro() -> Option<ffi::binaryfunc> {
+ None
+ }
+@@ -299,10 +296,7 @@ mod tp_setattro_impl {
+ fn del_attr() -> Option<ffi::setattrofunc>;
+ }
+
+- impl<'p, T> DelAttr for T
+- where
+- T: PyObjectProtocol<'p>,
+- {
++ impl<'p, T> DelAttr for T where T: PyObjectProtocol<'p> {
+ default fn del_attr() -> Option<ffi::setattrofunc> {
+ None
+ }
+@@ -321,10 +315,7 @@ mod tp_setattro_impl {
+ fn set_del_attr() -> Option<ffi::setattrofunc>;
+ }
+
+- impl<'p, T> SetDelAttr for T
+- where
+- T: PyObjectProtocol<'p>,
+- {
++ impl<'p, T> SetDelAttr for T where T: PyObjectProtocol<'p> {
+ default fn set_del_attr() -> Option<ffi::setattrofunc> {
+ None
+ }
+@@ -349,10 +340,7 @@ mod tp_setattro_impl {
+ trait StrProtocolImpl {
+ fn tp_str() -> Option<ffi::unaryfunc>;
+ }
+-impl<'p, T> StrProtocolImpl for T
+-where
+- T: PyObjectProtocol<'p>,
+-{
++impl<'p, T> StrProtocolImpl for T where T: PyObjectProtocol<'p> {
+ default fn tp_str() -> Option<ffi::unaryfunc> {
+ None
+ }
+@@ -374,10 +362,7 @@ where
+ trait ReprProtocolImpl {
+ fn tp_repr() -> Option<ffi::unaryfunc>;
+ }
+-impl<'p, T> ReprProtocolImpl for T
+-where
+- T: PyObjectProtocol<'p>,
+-{
++impl<'p, T> ReprProtocolImpl for T where T: PyObjectProtocol<'p> {
+ default fn tp_repr() -> Option<ffi::unaryfunc> {
+ None
+ }
+@@ -400,10 +385,7 @@ where
+ pub trait FormatProtocolImpl {
+ fn __format__() -> Option<PyMethodDef>;
+ }
+-impl<'p, T> FormatProtocolImpl for T
+-where
+- T: PyObjectProtocol<'p>,
+-{
++impl<'p, T> FormatProtocolImpl for T where T: PyObjectProtocol<'p> {
+ default fn __format__() -> Option<PyMethodDef> {
+ None
+ }
+@@ -413,10 +395,7 @@ where
+ pub trait BytesProtocolImpl {
+ fn __bytes__() -> Option<PyMethodDef>;
+ }
+-impl<'p, T> BytesProtocolImpl for T
+-where
+- T: PyObjectProtocol<'p>,
+-{
++impl<'p, T> BytesProtocolImpl for T where T: PyObjectProtocol<'p> {
+ default fn __bytes__() -> Option<PyMethodDef> {
+ None
+ }
+@@ -426,10 +405,7 @@ where
+ pub trait UnicodeProtocolImpl {
+ fn __unicode__() -> Option<PyMethodDef>;
+ }
+-impl<'p, T> UnicodeProtocolImpl for T
+-where
+- T: PyObjectProtocol<'p>,
+-{
++impl<'p, T> UnicodeProtocolImpl for T where T: PyObjectProtocol<'p> {
+ default fn __unicode__() -> Option<PyMethodDef> {
+ None
+ }
+@@ -438,10 +414,7 @@ where
+ trait HashProtocolImpl {
+ fn tp_hash() -> Option<ffi::hashfunc>;
+ }
+-impl<'p, T> HashProtocolImpl for T
+-where
+- T: PyObjectProtocol<'p>,
+-{
++impl<'p, T> HashProtocolImpl for T where T: PyObjectProtocol<'p> {
+ default fn tp_hash() -> Option<ffi::hashfunc> {
+ None
+ }
+@@ -464,10 +437,7 @@ where
+ trait BoolProtocolImpl {
+ fn nb_bool() -> Option<ffi::inquiry>;
+ }
+-impl<'p, T> BoolProtocolImpl for T
+-where
+- T: PyObjectProtocol<'p>,
+-{
++impl<'p, T> BoolProtocolImpl for T where T: PyObjectProtocol<'p> {
+ default fn nb_bool() -> Option<ffi::inquiry> {
+ None
+ }
+@@ -490,10 +460,7 @@ where
+ trait RichcmpProtocolImpl {
+ fn tp_richcompare() -> Option<ffi::richcmpfunc>;
+ }
+-impl<'p, T> RichcmpProtocolImpl for T
+-where
+- T: PyObjectProtocol<'p>,
+-{
++impl<'p, T> RichcmpProtocolImpl for T where T: PyObjectProtocol<'p> {
+ default fn tp_richcompare() -> Option<ffi::richcmpfunc> {
+ None
+ }
+diff --git a/src/class/buffer.rs b/src/class/buffer.rs
+index f0f462db9..c30f078cc 100644
+--- a/src/class/buffer.rs
++++ b/src/class/buffer.rs
+@@ -69,10 +69,7 @@ trait PyBufferGetBufferProtocolImpl {
+ fn cb_bf_getbuffer() -> Option<ffi::getbufferproc>;
+ }
+
+-impl<'p, T> PyBufferGetBufferProtocolImpl for T
+-where
+- T: PyBufferProtocol<'p>,
+-{
++impl<'p, T> PyBufferGetBufferProtocolImpl for T where T: PyBufferProtocol<'p> {
+ default fn cb_bf_getbuffer() -> Option<ffi::getbufferproc> {
+ None
+ }
+diff --git a/src/class/context.rs b/src/class/context.rs
+index 50aea33e9..2ad59768d 100644
+--- a/src/class/context.rs
++++ b/src/class/context.rs
+@@ -80,10 +80,7 @@ pub trait PyContextEnterProtocolImpl {
+ fn __enter__() -> Option<PyMethodDef>;
+ }
+
+-impl<'p, T> PyContextEnterProtocolImpl for T
+-where
+- T: PyContextProtocol<'p>,
+-{
++impl<'p, T> PyContextEnterProtocolImpl for T where T: PyContextProtocol<'p> {
+ default fn __enter__() -> Option<PyMethodDef> {
+ None
+ }
+@@ -94,10 +91,7 @@ pub trait PyContextExitProtocolImpl {
+ fn __exit__() -> Option<PyMethodDef>;
+ }
+
+-impl<'p, T> PyContextExitProtocolImpl for T
+-where
+- T: PyContextProtocol<'p>,
+-{
++impl<'p, T> PyContextExitProtocolImpl for T where T: PyContextProtocol<'p> {
+ default fn __exit__() -> Option<PyMethodDef> {
+ None
+ }
+diff --git a/src/class/descr.rs b/src/class/descr.rs
+index 57d9119ca..c7b5b9660 100644
+--- a/src/class/descr.rs
++++ b/src/class/descr.rs
+@@ -72,10 +72,7 @@ pub trait PyDescrSetNameProtocol<'p>: PyDescrProtocol<'p> {
+ trait PyDescrGetProtocolImpl {
+ fn tp_descr_get() -> Option<ffi::descrgetfunc>;
+ }
+-impl<'p, T> PyDescrGetProtocolImpl for T
+-where
+- T: PyDescrProtocol<'p>,
+-{
++impl<'p, T> PyDescrGetProtocolImpl for T where T: PyDescrProtocol<'p> {
+ default fn tp_descr_get() -> Option<ffi::descrgetfunc> {
+ None
+ }
+@@ -98,10 +95,7 @@ where
+ trait PyDescrSetProtocolImpl {
+ fn tp_descr_set() -> Option<ffi::descrsetfunc>;
+ }
+-impl<'p, T> PyDescrSetProtocolImpl for T
+-where
+- T: PyDescrProtocol<'p>,
+-{
++impl<'p, T> PyDescrSetProtocolImpl for T where T: PyDescrProtocol<'p> {
+ default fn tp_descr_set() -> Option<ffi::descrsetfunc> {
+ None
+ }
+diff --git a/src/class/gc.rs b/src/class/gc.rs
+index 591b686af..4b69c9643 100644
+--- a/src/class/gc.rs
++++ b/src/class/gc.rs
+@@ -68,10 +68,7 @@ trait PyGCTraverseProtocolImpl {
+ fn tp_traverse() -> Option<ffi::traverseproc>;
+ }
+
+-impl<'p, T> PyGCTraverseProtocolImpl for T
+-where
+- T: PyGCProtocol<'p>,
+-{
++impl<'p, T> PyGCTraverseProtocolImpl for T where T: PyGCProtocol<'p> {
+ default fn tp_traverse() -> Option<ffi::traverseproc> {
+ None
+ }
+@@ -115,10 +112,7 @@ trait PyGCClearProtocolImpl {
+ fn tp_clear() -> Option<ffi::inquiry>;
+ }
+
+-impl<'p, T> PyGCClearProtocolImpl for T
+-where
+- T: PyGCProtocol<'p>,
+-{
++impl<'p, T> PyGCClearProtocolImpl for T where T: PyGCProtocol<'p> {
+ default fn tp_clear() -> Option<ffi::inquiry> {
+ None
+ }
+diff --git a/src/class/iter.rs b/src/class/iter.rs
+index a528289dd..fcf76f2e5 100644
+--- a/src/class/iter.rs
++++ b/src/class/iter.rs
+@@ -66,10 +66,7 @@ trait PyIterIterProtocolImpl {
+ fn tp_iter() -> Option<ffi::getiterfunc>;
+ }
+
+-impl<'p, T> PyIterIterProtocolImpl for T
+-where
+- T: PyIterProtocol<'p>,
+-{
++impl<'p, T> PyIterIterProtocolImpl for T where T: PyIterProtocol<'p> {
+ default fn tp_iter() -> Option<ffi::getiterfunc> {
+ None
+ }
+@@ -94,10 +91,7 @@ trait PyIterNextProtocolImpl {
+ fn tp_iternext() -> Option<ffi::iternextfunc>;
+ }
+
+-impl<'p, T> PyIterNextProtocolImpl for T
+-where
+- T: PyIterProtocol<'p>,
+-{
++impl<'p, T> PyIterNextProtocolImpl for T where T: PyIterProtocol<'p> {
+ default fn tp_iternext() -> Option<ffi::iternextfunc> {
+ None
+ }
+diff --git a/src/class/mapping.rs b/src/class/mapping.rs
+index 32326ff46..64d7b57ce 100644
+--- a/src/class/mapping.rs
++++ b/src/class/mapping.rs
+@@ -160,10 +160,7 @@ trait PyMappingLenProtocolImpl {
+ fn mp_length() -> Option<ffi::lenfunc>;
+ }
+
+-impl<'p, T> PyMappingLenProtocolImpl for T
+-where
+- T: PyMappingProtocol<'p>,
+-{
++impl<'p, T> PyMappingLenProtocolImpl for T where T: PyMappingProtocol<'p> {
+ default fn mp_length() -> Option<ffi::lenfunc> {
+ None
+ }
+@@ -183,10 +180,7 @@ trait PyMappingGetItemProtocolImpl {
+ fn mp_subscript() -> Option<ffi::binaryfunc>;
+ }
+
+-impl<'p, T> PyMappingGetItemProtocolImpl for T
+-where
+- T: PyMappingProtocol<'p>,
+-{
++impl<'p, T> PyMappingGetItemProtocolImpl for T where T: PyMappingProtocol<'p> {
+ default fn mp_subscript() -> Option<ffi::binaryfunc> {
+ None
+ }
+@@ -211,10 +205,7 @@ trait PyMappingSetItemProtocolImpl {
+ fn mp_ass_subscript() -> Option<ffi::objobjargproc>;
+ }
+
+-impl<'p, T> PyMappingSetItemProtocolImpl for T
+-where
+- T: PyMappingProtocol<'p>,
+-{
++impl<'p, T> PyMappingSetItemProtocolImpl for T where T: PyMappingProtocol<'p> {
+ default fn mp_ass_subscript() -> Option<ffi::objobjargproc> {
+ None
+ }
+@@ -236,10 +227,7 @@ trait DeplItemDipatch {
+ fn mp_del_subscript() -> Option<ffi::objobjargproc>;
+ }
+
+-impl<'p, T> DeplItemDipatch for T
+-where
+- T: PyMappingProtocol<'p>,
+-{
++impl<'p, T> DeplItemDipatch for T where T: PyMappingProtocol<'p> {
+ default fn mp_del_subscript() -> Option<ffi::objobjargproc> {
+ None
+ }
+@@ -250,10 +238,7 @@ trait DelSetItemDispatch: Sized + for<'p> PyMappingDelItemProtocol<'p> {
+ fn det_set_dispatch() -> Option<ffi::objobjargproc>;
+ }
+
+-impl<T> DelSetItemDispatch for T
+-where
+- T: Sized + for<'p> PyMappingDelItemProtocol<'p>,
+-{
++impl<T> DelSetItemDispatch for T where T: Sized + for<'p> PyMappingDelItemProtocol<'p> {
+ default fn det_set_dispatch() -> Option<ffi::objobjargproc> {
+ py_func_del!(PyMappingDelItemProtocol, Self, __delitem__)
+ }
+@@ -288,10 +273,7 @@ pub trait PyMappingContainsProtocolImpl {
+ fn __contains__() -> Option<PyMethodDef>;
+ }
+
+-impl<'p, T> PyMappingContainsProtocolImpl for T
+-where
+- T: PyMappingProtocol<'p>,
+-{
++impl<'p, T> PyMappingContainsProtocolImpl for T where T: PyMappingProtocol<'p> {
+ default fn __contains__() -> Option<PyMethodDef> {
+ None
+ }
+@@ -302,10 +284,7 @@ pub trait PyMappingReversedProtocolImpl {
+ fn __reversed__() -> Option<PyMethodDef>;
+ }
+
+-impl<'p, T> PyMappingReversedProtocolImpl for T
+-where
+- T: PyMappingProtocol<'p>,
+-{
++impl<'p, T> PyMappingReversedProtocolImpl for T where T: PyMappingProtocol<'p> {
+ default fn __reversed__() -> Option<PyMethodDef> {
+ None
+ }
+@@ -316,10 +295,7 @@ pub trait PyMappingIterProtocolImpl {
+ fn __iter__() -> Option<PyMethodDef>;
+ }
+
+-impl<'p, T> PyMappingIterProtocolImpl for T
+-where
+- T: PyMappingProtocol<'p>,
+-{
++impl<'p, T> PyMappingIterProtocolImpl for T where T: PyMappingProtocol<'p> {
+ default fn __iter__() -> Option<PyMethodDef> {
+ None
+ }
+diff --git a/src/class/number.rs b/src/class/number.rs
+index 796b8bad9..0ab162e72 100644
+--- a/src/class/number.rs
++++ b/src/class/number.rs
+@@ -749,10 +749,7 @@ trait PyNumberAddProtocolImpl {
+ fn nb_add() -> Option<ffi::binaryfunc>;
+ }
+
+-impl<'p, T> PyNumberAddProtocolImpl for T
+-where
+- T: PyNumberProtocol<'p>,
+-{
++impl<'p, T> PyNumberAddProtocolImpl for T where T: PyNumberProtocol<'p> {
+ default fn nb_add() -> Option<ffi::binaryfunc> {
+ None
+ }
+@@ -776,10 +773,7 @@ trait PyNumberSubProtocolImpl {
+ fn nb_subtract() -> Option<ffi::binaryfunc>;
+ }
+
+-impl<'p, T> PyNumberSubProtocolImpl for T
+-where
+- T: PyNumberProtocol<'p>,
+-{
++impl<'p, T> PyNumberSubProtocolImpl for T where T: PyNumberProtocol<'p> {
+ default fn nb_subtract() -> Option<ffi::binaryfunc> {
+ None
+ }
+@@ -803,10 +797,7 @@ trait PyNumberMulProtocolImpl {
+ fn nb_multiply() -> Option<ffi::binaryfunc>;
+ }
+
+-impl<'p, T> PyNumberMulProtocolImpl for T
+-where
+- T: PyNumberProtocol<'p>,
+-{
++impl<'p, T> PyNumberMulProtocolImpl for T where T: PyNumberProtocol<'p> {
+ default fn nb_multiply() -> Option<ffi::binaryfunc> {
+ None
+ }
+@@ -830,10 +821,7 @@ trait PyNumberMatmulProtocolImpl {
+ fn nb_matrix_multiply() -> Option<ffi::binaryfunc>;
+ }
+
+-impl<'p, T> PyNumberMatmulProtocolImpl for T
+-where
+- T: PyNumberProtocol<'p>,
+-{
++impl<'p, T> PyNumberMatmulProtocolImpl for T where T: PyNumberProtocol<'p> {
+ default fn nb_matrix_multiply() -> Option<ffi::binaryfunc> {
+ None
+ }
+@@ -857,10 +845,7 @@ trait PyNumberTruedivProtocolImpl {
+ fn nb_true_divide() -> Option<ffi::binaryfunc>;
+ }
+
+-impl<'p, T> PyNumberTruedivProtocolImpl for T
+-where
+- T: PyNumberProtocol<'p>,
+-{
++impl<'p, T> PyNumberTruedivProtocolImpl for T where T: PyNumberProtocol<'p> {
+ default fn nb_true_divide() -> Option<ffi::binaryfunc> {
+ None
+ }
+@@ -884,10 +869,7 @@ trait PyNumberFloordivProtocolImpl {
+ fn nb_floor_divide() -> Option<ffi::binaryfunc>;
+ }
+
+-impl<'p, T> PyNumberFloordivProtocolImpl for T
+-where
+- T: PyNumberProtocol<'p>,
+-{
++impl<'p, T> PyNumberFloordivProtocolImpl for T where T: PyNumberProtocol<'p> {
+ default fn nb_floor_divide() -> Option<ffi::binaryfunc> {
+ None
+ }
+@@ -911,10 +893,7 @@ trait PyNumberModProtocolImpl {
+ fn nb_remainder() -> Option<ffi::binaryfunc>;
+ }
+
+-impl<'p, T> PyNumberModProtocolImpl for T
+-where
+- T: PyNumberProtocol<'p>,
+-{
++impl<'p, T> PyNumberModProtocolImpl for T where T: PyNumberProtocol<'p> {
+ default fn nb_remainder() -> Option<ffi::binaryfunc> {
+ None
+ }
+@@ -938,10 +917,7 @@ trait PyNumberDivmodProtocolImpl {
+ fn nb_divmod() -> Option<ffi::binaryfunc>;
+ }
+
+-impl<'p, T> PyNumberDivmodProtocolImpl for T
+-where
+- T: PyNumberProtocol<'p>,
+-{
++impl<'p, T> PyNumberDivmodProtocolImpl for T where T: PyNumberProtocol<'p> {
+ default fn nb_divmod() -> Option<ffi::binaryfunc> {
+ None
+ }
+@@ -965,10 +941,7 @@ trait PyNumberPowProtocolImpl {
+ fn nb_power() -> Option<ffi::ternaryfunc>;
+ }
+
+-impl<'p, T> PyNumberPowProtocolImpl for T
+-where
+- T: PyNumberProtocol<'p>,
+-{
++impl<'p, T> PyNumberPowProtocolImpl for T where T: PyNumberProtocol<'p> {
+ default fn nb_power() -> Option<ffi::ternaryfunc> {
+ None
+ }
+@@ -992,10 +965,7 @@ trait PyNumberLShiftProtocolImpl {
+ fn nb_lshift() -> Option<ffi::binaryfunc>;
+ }
+
+-impl<'p, T> PyNumberLShiftProtocolImpl for T
+-where
+- T: PyNumberProtocol<'p>,
+-{
++impl<'p, T> PyNumberLShiftProtocolImpl for T where T: PyNumberProtocol<'p> {
+ default fn nb_lshift() -> Option<ffi::binaryfunc> {
+ None
+ }
+@@ -1019,10 +989,7 @@ trait PyNumberRShiftProtocolImpl {
+ fn nb_rshift() -> Option<ffi::binaryfunc>;
+ }
+
+-impl<'p, T> PyNumberRShiftProtocolImpl for T
+-where
+- T: PyNumberProtocol<'p>,
+-{
++impl<'p, T> PyNumberRShiftProtocolImpl for T where T: PyNumberProtocol<'p> {
+ default fn nb_rshift() -> Option<ffi::binaryfunc> {
+ None
+ }
+@@ -1046,10 +1013,7 @@ trait PyNumberAndProtocolImpl {
+ fn nb_and() -> Option<ffi::binaryfunc>;
+ }
+
+-impl<'p, T> PyNumberAndProtocolImpl for T
+-where
+- T: PyNumberProtocol<'p>,
+-{
++impl<'p, T> PyNumberAndProtocolImpl for T where T: PyNumberProtocol<'p> {
+ default fn nb_and() -> Option<ffi::binaryfunc> {
+ None
+ }
+@@ -1073,10 +1037,7 @@ trait PyNumberXorProtocolImpl {
+ fn nb_xor() -> Option<ffi::binaryfunc>;
+ }
+
+-impl<'p, T> PyNumberXorProtocolImpl for T
+-where
+- T: PyNumberProtocol<'p>,
+-{
++impl<'p, T> PyNumberXorProtocolImpl for T where T: PyNumberProtocol<'p> {
+ default fn nb_xor() -> Option<ffi::binaryfunc> {
+ None
+ }
+@@ -1100,10 +1061,7 @@ trait PyNumberOrProtocolImpl {
+ fn nb_or() -> Option<ffi::binaryfunc>;
+ }
+
+-impl<'p, T> PyNumberOrProtocolImpl for T
+-where
+- T: PyNumberProtocol<'p>,
+-{
++impl<'p, T> PyNumberOrProtocolImpl for T where T: PyNumberProtocol<'p> {
+ default fn nb_or() -> Option<ffi::binaryfunc> {
+ None
+ }
+@@ -1127,10 +1085,7 @@ trait PyNumberIAddProtocolImpl {
+ fn nb_inplace_add() -> Option<ffi::binaryfunc>;
+ }
+
+-impl<'p, T> PyNumberIAddProtocolImpl for T
+-where
+- T: PyNumberProtocol<'p>,
+-{
++impl<'p, T> PyNumberIAddProtocolImpl for T where T: PyNumberProtocol<'p> {
+ default fn nb_inplace_add() -> Option<ffi::binaryfunc> {
+ None
+ }
+@@ -1149,10 +1104,7 @@ trait PyNumberISubProtocolImpl {
+ fn nb_inplace_subtract() -> Option<ffi::binaryfunc>;
+ }
+
+-impl<'p, T> PyNumberISubProtocolImpl for T
+-where
+- T: PyNumberProtocol<'p>,
+-{
++impl<'p, T> PyNumberISubProtocolImpl for T where T: PyNumberProtocol<'p> {
+ default fn nb_inplace_subtract() -> Option<ffi::binaryfunc> {
+ None
+ }
+@@ -1171,10 +1123,7 @@ trait PyNumberIMulProtocolImpl {
+ fn nb_inplace_multiply() -> Option<ffi::binaryfunc>;
+ }
+
+-impl<'p, T> PyNumberIMulProtocolImpl for T
+-where
+- T: PyNumberProtocol<'p>,
+-{
++impl<'p, T> PyNumberIMulProtocolImpl for T where T: PyNumberProtocol<'p> {
+ default fn nb_inplace_multiply() -> Option<ffi::binaryfunc> {
+ None
+ }
+@@ -1193,10 +1142,7 @@ trait PyNumberIMatmulProtocolImpl {
+ fn nb_inplace_matrix_multiply() -> Option<ffi::binaryfunc>;
+ }
+
+-impl<'p, T> PyNumberIMatmulProtocolImpl for T
+-where
+- T: PyNumberProtocol<'p>,
+-{
++impl<'p, T> PyNumberIMatmulProtocolImpl for T where T: PyNumberProtocol<'p> {
+ default fn nb_inplace_matrix_multiply() -> Option<ffi::binaryfunc> {
+ None
+ }
+@@ -1215,10 +1161,7 @@ trait PyNumberITruedivProtocolImpl {
+ fn nb_inplace_true_divide() -> Option<ffi::binaryfunc>;
+ }
+
+-impl<'p, T> PyNumberITruedivProtocolImpl for T
+-where
+- T: PyNumberProtocol<'p>,
+-{
++impl<'p, T> PyNumberITruedivProtocolImpl for T where T: PyNumberProtocol<'p> {
+ default fn nb_inplace_true_divide() -> Option<ffi::binaryfunc> {
+ None
+ }
+@@ -1237,10 +1180,7 @@ trait PyNumberIFloordivProtocolImpl {
+ fn nb_inplace_floor_divide() -> Option<ffi::binaryfunc>;
+ }
+
+-impl<'p, T> PyNumberIFloordivProtocolImpl for T
+-where
+- T: PyNumberProtocol<'p>,
+-{
++impl<'p, T> PyNumberIFloordivProtocolImpl for T where T: PyNumberProtocol<'p> {
+ default fn nb_inplace_floor_divide() -> Option<ffi::binaryfunc> {
+ None
+ }
+@@ -1259,10 +1199,7 @@ trait PyNumberIModProtocolImpl {
+ fn nb_inplace_remainder() -> Option<ffi::binaryfunc>;
+ }
+
+-impl<'p, T> PyNumberIModProtocolImpl for T
+-where
+- T: PyNumberProtocol<'p>,
+-{
++impl<'p, T> PyNumberIModProtocolImpl for T where T: PyNumberProtocol<'p> {
+ default fn nb_inplace_remainder() -> Option<ffi::binaryfunc> {
+ None
+ }
+@@ -1281,10 +1218,7 @@ trait PyNumberIPowProtocolImpl {
+ fn nb_inplace_power() -> Option<ffi::ternaryfunc>;
+ }
+
+-impl<'p, T> PyNumberIPowProtocolImpl for T
+-where
+- T: PyNumberProtocol<'p>,
+-{
++impl<'p, T> PyNumberIPowProtocolImpl for T where T: PyNumberProtocol<'p> {
+ default fn nb_inplace_power() -> Option<ffi::ternaryfunc> {
+ None
+ }
+@@ -1303,10 +1237,7 @@ trait PyNumberILShiftProtocolImpl {
+ fn nb_inplace_lshift() -> Option<ffi::binaryfunc>;
+ }
+
+-impl<'p, T> PyNumberILShiftProtocolImpl for T
+-where
+- T: PyNumberProtocol<'p>,
+-{
++impl<'p, T> PyNumberILShiftProtocolImpl for T where T: PyNumberProtocol<'p> {
+ default fn nb_inplace_lshift() -> Option<ffi::binaryfunc> {
+ None
+ }
+@@ -1325,10 +1256,7 @@ trait PyNumberIRShiftProtocolImpl {
+ fn nb_inplace_rshift() -> Option<ffi::binaryfunc>;
+ }
+
+-impl<'p, T> PyNumberIRShiftProtocolImpl for T
+-where
+- T: PyNumberProtocol<'p>,
+-{
++impl<'p, T> PyNumberIRShiftProtocolImpl for T where T: PyNumberProtocol<'p> {
+ default fn nb_inplace_rshift() -> Option<ffi::binaryfunc> {
+ None
+ }
+@@ -1347,10 +1275,7 @@ trait PyNumberIAndProtocolImpl {
+ fn nb_inplace_and() -> Option<ffi::binaryfunc>;
+ }
+
+-impl<'p, T> PyNumberIAndProtocolImpl for T
+-where
+- T: PyNumberProtocol<'p>,
+-{
++impl<'p, T> PyNumberIAndProtocolImpl for T where T: PyNumberProtocol<'p> {
+ default fn nb_inplace_and() -> Option<ffi::binaryfunc> {
+ None
+ }
+@@ -1369,10 +1294,7 @@ trait PyNumberIXorProtocolImpl {
+ fn nb_inplace_xor() -> Option<ffi::binaryfunc>;
+ }
+
+-impl<'p, T> PyNumberIXorProtocolImpl for T
+-where
+- T: PyNumberProtocol<'p>,
+-{
++impl<'p, T> PyNumberIXorProtocolImpl for T where T: PyNumberProtocol<'p> {
+ default fn nb_inplace_xor() -> Option<ffi::binaryfunc> {
+ None
+ }
+@@ -1391,10 +1313,7 @@ trait PyNumberIOrProtocolImpl {
+ fn nb_inplace_or() -> Option<ffi::binaryfunc>;
+ }
+
+-impl<'p, T> PyNumberIOrProtocolImpl for T
+-where
+- T: PyNumberProtocol<'p>,
+-{
++impl<'p, T> PyNumberIOrProtocolImpl for T where T: PyNumberProtocol<'p> {
+ default fn nb_inplace_or() -> Option<ffi::binaryfunc> {
+ None
+ }
+@@ -1414,10 +1333,7 @@ pub trait PyNumberRAddProtocolImpl {
+ fn __radd__() -> Option<PyMethodDef>;
+ }
+
+-impl<'p, T> PyNumberRAddProtocolImpl for T
+-where
+- T: PyNumberProtocol<'p>,
+-{
++impl<'p, T> PyNumberRAddProtocolImpl for T where T: PyNumberProtocol<'p> {
+ default fn __radd__() -> Option<PyMethodDef> {
+ None
+ }
+@@ -1437,10 +1353,7 @@ pub trait PyNumberRMulProtocolImpl {
+ fn __rmul__() -> Option<PyMethodDef>;
+ }
+
+-impl<'p, T> PyNumberRMulProtocolImpl for T
+-where
+- T: PyNumberProtocol<'p>,
+-{
++impl<'p, T> PyNumberRMulProtocolImpl for T where T: PyNumberProtocol<'p> {
+ default fn __rmul__() -> Option<PyMethodDef> {
+ None
+ }
+@@ -1451,10 +1364,7 @@ pub trait PyNumberRMatmulProtocolImpl {
+ fn __rmatmul__() -> Option<PyMethodDef>;
+ }
+
+-impl<'p, T> PyNumberRMatmulProtocolImpl for T
+-where
+- T: PyNumberProtocol<'p>,
+-{
++impl<'p, T> PyNumberRMatmulProtocolImpl for T where T: PyNumberProtocol<'p> {
+ default fn __rmatmul__() -> Option<PyMethodDef> {
+ None
+ }
+@@ -1465,10 +1375,7 @@ pub trait PyNumberRTruedivProtocolImpl {
+ fn __rtruediv__() -> Option<PyMethodDef>;
+ }
+
+-impl<'p, T> PyNumberRTruedivProtocolImpl for T
+-where
+- T: PyNumberProtocol<'p>,
+-{
++impl<'p, T> PyNumberRTruedivProtocolImpl for T where T: PyNumberProtocol<'p> {
+ default fn __rtruediv__() -> Option<PyMethodDef> {
+ None
+ }
+@@ -1479,10 +1386,7 @@ pub trait PyNumberRFloordivProtocolImpl {
+ fn __rfloordiv__() -> Option<PyMethodDef>;
+ }
+
+-impl<'p, T> PyNumberRFloordivProtocolImpl for T
+-where
+- T: PyNumberProtocol<'p>,
+-{
++impl<'p, T> PyNumberRFloordivProtocolImpl for T where T: PyNumberProtocol<'p> {
+ default fn __rfloordiv__() -> Option<PyMethodDef> {
+ None
+ }
+@@ -1493,10 +1397,7 @@ pub trait PyNumberRModProtocolImpl {
+ fn __rmod__() -> Option<PyMethodDef>;
+ }
+
+-impl<'p, T> PyNumberRModProtocolImpl for T
+-where
+- T: PyNumberProtocol<'p>,
+-{
++impl<'p, T> PyNumberRModProtocolImpl for T where T: PyNumberProtocol<'p> {
+ default fn __rmod__() -> Option<PyMethodDef> {
+ None
+ }
+@@ -1507,10 +1408,7 @@ pub trait PyNumberRDivmodProtocolImpl {
+ fn __rdivmod__() -> Option<PyMethodDef>;
+ }
+
+-impl<'p, T> PyNumberRDivmodProtocolImpl for T
+-where
+- T: PyNumberProtocol<'p>,
+-{
++impl<'p, T> PyNumberRDivmodProtocolImpl for T where T: PyNumberProtocol<'p> {
+ default fn __rdivmod__() -> Option<PyMethodDef> {
+ None
+ }
+@@ -1521,10 +1419,7 @@ pub trait PyNumberRPowProtocolImpl {
+ fn __rpow__() -> Option<PyMethodDef>;
+ }
+
+-impl<'p, T> PyNumberRPowProtocolImpl for T
+-where
+- T: PyNumberProtocol<'p>,
+-{
++impl<'p, T> PyNumberRPowProtocolImpl for T where T: PyNumberProtocol<'p> {
+ default fn __rpow__() -> Option<PyMethodDef> {
+ None
+ }
+@@ -1535,10 +1430,7 @@ pub trait PyNumberRLShiftProtocolImpl {
+ fn __rlshift__() -> Option<PyMethodDef>;
+ }
+
+-impl<'p, T> PyNumberRLShiftProtocolImpl for T
+-where
+- T: PyNumberProtocol<'p>,
+-{
++impl<'p, T> PyNumberRLShiftProtocolImpl for T where T: PyNumberProtocol<'p> {
+ default fn __rlshift__() -> Option<PyMethodDef> {
+ None
+ }
+@@ -1549,10 +1441,7 @@ pub trait PyNumberRRShiftProtocolImpl {
+ fn __rrshift__() -> Option<PyMethodDef>;
+ }
+
+-impl<'p, T> PyNumberRRShiftProtocolImpl for T
+-where
+- T: PyNumberProtocol<'p>,
+-{
++impl<'p, T> PyNumberRRShiftProtocolImpl for T where T: PyNumberProtocol<'p> {
+ default fn __rrshift__() -> Option<PyMethodDef> {
+ None
+ }
+@@ -1563,10 +1452,7 @@ pub trait PyNumberRAndProtocolImpl {
+ fn __rand__() -> Option<PyMethodDef>;
+ }
+
+-impl<'p, T> PyNumberRAndProtocolImpl for T
+-where
+- T: PyNumberProtocol<'p>,
+-{
++impl<'p, T> PyNumberRAndProtocolImpl for T where T: PyNumberProtocol<'p> {
+ default fn __rand__() -> Option<PyMethodDef> {
+ None
+ }
+@@ -1577,10 +1463,7 @@ pub trait PyNumberRXorProtocolImpl {
+ fn __rxor__() -> Option<PyMethodDef>;
+ }
+
+-impl<'p, T> PyNumberRXorProtocolImpl for T
+-where
+- T: PyNumberProtocol<'p>,
+-{
++impl<'p, T> PyNumberRXorProtocolImpl for T where T: PyNumberProtocol<'p> {
+ default fn __rxor__() -> Option<PyMethodDef> {
+ None
+ }
+@@ -1591,10 +1474,7 @@ pub trait PyNumberROrProtocolImpl {
+ fn __ror__() -> Option<PyMethodDef>;
+ }
+
+-impl<'p, T> PyNumberROrProtocolImpl for T
+-where
+- T: PyNumberProtocol<'p>,
+-{
++impl<'p, T> PyNumberROrProtocolImpl for T where T: PyNumberProtocol<'p> {
+ default fn __ror__() -> Option<PyMethodDef> {
+ None
+ }
+@@ -1604,10 +1484,7 @@ trait PyNumberNegProtocolImpl {
+ fn nb_negative() -> Option<ffi::unaryfunc>;
+ }
+
+-impl<'p, T> PyNumberNegProtocolImpl for T
+-where
+- T: PyNumberProtocol<'p>,
+-{
++impl<'p, T> PyNumberNegProtocolImpl for T where T: PyNumberProtocol<'p> {
+ default fn nb_negative() -> Option<ffi::unaryfunc> {
+ None
+ }
+@@ -1632,10 +1509,7 @@ trait PyNumberPosProtocolImpl {
+ fn nb_positive() -> Option<ffi::unaryfunc>;
+ }
+
+-impl<'p, T> PyNumberPosProtocolImpl for T
+-where
+- T: PyNumberProtocol<'p>,
+-{
++impl<'p, T> PyNumberPosProtocolImpl for T where T: PyNumberProtocol<'p> {
+ default fn nb_positive() -> Option<ffi::unaryfunc> {
+ None
+ }
+@@ -1659,10 +1533,7 @@ trait PyNumberAbsProtocolImpl {
+ fn nb_absolute() -> Option<ffi::unaryfunc>;
+ }
+
+-impl<'p, T> PyNumberAbsProtocolImpl for T
+-where
+- T: PyNumberProtocol<'p>,
+-{
++impl<'p, T> PyNumberAbsProtocolImpl for T where T: PyNumberProtocol<'p> {
+ default fn nb_absolute() -> Option<ffi::unaryfunc> {
+ None
+ }
+@@ -1686,10 +1557,7 @@ trait PyNumberInvertProtocolImpl {
+ fn nb_invert() -> Option<ffi::unaryfunc>;
+ }
+
+-impl<'p, T> PyNumberInvertProtocolImpl for T
+-where
+- T: PyNumberProtocol<'p>,
+-{
++impl<'p, T> PyNumberInvertProtocolImpl for T where T: PyNumberProtocol<'p> {
+ default fn nb_invert() -> Option<ffi::unaryfunc> {
+ None
+ }
+@@ -1713,10 +1581,7 @@ trait PyNumberIntProtocolImpl {
+ fn nb_int() -> Option<ffi::unaryfunc>;
+ }
+
+-impl<'p, T> PyNumberIntProtocolImpl for T
+-where
+- T: PyNumberProtocol<'p>,
+-{
++impl<'p, T> PyNumberIntProtocolImpl for T where T: PyNumberProtocol<'p> {
+ default fn nb_int() -> Option<ffi::unaryfunc> {
+ None
+ }
+@@ -1740,10 +1605,7 @@ trait PyNumberFloatProtocolImpl {
+ fn nb_float() -> Option<ffi::unaryfunc>;
+ }
+
+-impl<'p, T> PyNumberFloatProtocolImpl for T
+-where
+- T: PyNumberProtocol<'p>,
+-{
++impl<'p, T> PyNumberFloatProtocolImpl for T where T: PyNumberProtocol<'p> {
+ default fn nb_float() -> Option<ffi::unaryfunc> {
+ None
+ }
+@@ -1767,10 +1629,7 @@ trait PyNumberIndexProtocolImpl {
+ fn nb_index() -> Option<ffi::unaryfunc>;
+ }
+
+-impl<'p, T> PyNumberIndexProtocolImpl for T
+-where
+- T: PyNumberProtocol<'p>,
+-{
++impl<'p, T> PyNumberIndexProtocolImpl for T where T: PyNumberProtocol<'p> {
+ default fn nb_index() -> Option<ffi::unaryfunc> {
+ None
+ }
+@@ -1794,10 +1653,7 @@ trait PyNumberComplexProtocolImpl {
+ fn __complex__() -> Option<PyMethodDef>;
+ }
+
+-impl<'p, T> PyNumberComplexProtocolImpl for T
+-where
+- T: PyNumberProtocol<'p>,
+-{
++impl<'p, T> PyNumberComplexProtocolImpl for T where T: PyNumberProtocol<'p> {
+ default fn __complex__() -> Option<PyMethodDef> {
+ None
+ }
+@@ -1807,10 +1663,7 @@ trait PyNumberRoundProtocolImpl {
+ fn __round__() -> Option<PyMethodDef>;
+ }
+
+-impl<'p, T> PyNumberRoundProtocolImpl for T
+-where
+- T: PyNumberProtocol<'p>,
+-{
++impl<'p, T> PyNumberRoundProtocolImpl for T where T: PyNumberProtocol<'p> {
+ default fn __round__() -> Option<PyMethodDef> {
+ None
+ }
+diff --git a/src/class/pyasync.rs b/src/class/pyasync.rs
+index 2536d4ce2..f977fadfa 100644
+--- a/src/class/pyasync.rs
++++ b/src/class/pyasync.rs
+@@ -137,10 +137,7 @@ trait PyAsyncAwaitProtocolImpl {
+ fn am_await() -> Option<ffi::unaryfunc>;
+ }
+
+-impl<'p, T> PyAsyncAwaitProtocolImpl for T
+-where
+- T: PyAsyncProtocol<'p>,
+-{
++impl<'p, T> PyAsyncAwaitProtocolImpl for T where T: PyAsyncProtocol<'p> {
+ default fn am_await() -> Option<ffi::unaryfunc> {
+ None
+ }
+@@ -165,10 +162,7 @@ trait PyAsyncAiterProtocolImpl {
+ fn am_aiter() -> Option<ffi::unaryfunc>;
+ }
+
+-impl<'p, T> PyAsyncAiterProtocolImpl for T
+-where
+- T: PyAsyncProtocol<'p>,
+-{
++impl<'p, T> PyAsyncAiterProtocolImpl for T where T: PyAsyncProtocol<'p> {
+ default fn am_aiter() -> Option<ffi::unaryfunc> {
+ None
+ }
+@@ -193,10 +187,7 @@ trait PyAsyncAnextProtocolImpl {
+ fn am_anext() -> Option<ffi::unaryfunc>;
+ }
+
+-impl<'p, T> PyAsyncAnextProtocolImpl for T
+-where
+- T: PyAsyncProtocol<'p>,
+-{
++impl<'p, T> PyAsyncAnextProtocolImpl for T where T: PyAsyncProtocol<'p> {
+ default fn am_anext() -> Option<ffi::unaryfunc> {
+ None
+ }
+@@ -254,10 +245,7 @@ trait PyAsyncAenterProtocolImpl {
+ fn __aenter__() -> Option<PyMethodDef>;
+ }
+
+-impl<'p, T> PyAsyncAenterProtocolImpl for T
+-where
+- T: PyAsyncProtocol<'p>,
+-{
++impl<'p, T> PyAsyncAenterProtocolImpl for T where T: PyAsyncProtocol<'p> {
+ default fn __aenter__() -> Option<PyMethodDef> {
+ None
+ }
+@@ -267,10 +255,7 @@ trait PyAsyncAexitProtocolImpl {
+ fn __aexit__() -> Option<PyMethodDef>;
+ }
+
+-impl<'p, T> PyAsyncAexitProtocolImpl for T
+-where
+- T: PyAsyncProtocol<'p>,
+-{
++impl<'p, T> PyAsyncAexitProtocolImpl for T where T: PyAsyncProtocol<'p> {
+ default fn __aexit__() -> Option<PyMethodDef> {
+ None
+ }
+diff --git a/src/class/sequence.rs b/src/class/sequence.rs
+index 5414704a1..ce65508fd 100644
+--- a/src/class/sequence.rs
++++ b/src/class/sequence.rs
+@@ -167,10 +167,7 @@ trait PySequenceLenProtocolImpl {
+ fn sq_length() -> Option<ffi::lenfunc>;
+ }
+
+-impl<'p, T> PySequenceLenProtocolImpl for T
+-where
+- T: PySequenceProtocol<'p>,
+-{
++impl<'p, T> PySequenceLenProtocolImpl for T where T: PySequenceProtocol<'p> {
+ default fn sq_length() -> Option<ffi::lenfunc> {
+ None
+ }
+@@ -189,10 +186,7 @@ trait PySequenceGetItemProtocolImpl {
+ fn sq_item() -> Option<ffi::ssizeargfunc>;
+ }
+
+-impl<'p, T> PySequenceGetItemProtocolImpl for T
+-where
+- T: PySequenceProtocol<'p>,
+-{
++impl<'p, T> PySequenceGetItemProtocolImpl for T where T: PySequenceProtocol<'p> {
+ default fn sq_item() -> Option<ffi::ssizeargfunc> {
+ None
+ }
+@@ -298,10 +292,7 @@ mod sq_ass_item_impl {
+ fn del_item() -> Option<ffi::ssizeobjargproc>;
+ }
+
+- impl<'p, T> DelItem for T
+- where
+- T: PySequenceProtocol<'p>,
+- {
++ impl<'p, T> DelItem for T where T: PySequenceProtocol<'p> {
+ default fn del_item() -> Option<ffi::ssizeobjargproc> {
+ None
+ }
+@@ -349,10 +340,7 @@ mod sq_ass_item_impl {
+ fn del_set_item() -> Option<ffi::ssizeobjargproc>;
+ }
+
+- impl<'p, T> DelSetItem for T
+- where
+- T: PySequenceProtocol<'p>,
+- {
++ impl<'p, T> DelSetItem for T where T: PySequenceProtocol<'p> {
+ default fn del_set_item() -> Option<ffi::ssizeobjargproc> {
+ None
+ }
+@@ -401,10 +389,7 @@ trait PySequenceContainsProtocolImpl {
+ fn sq_contains() -> Option<ffi::objobjproc>;
+ }
+
+-impl<'p, T> PySequenceContainsProtocolImpl for T
+-where
+- T: PySequenceProtocol<'p>,
+-{
++impl<'p, T> PySequenceContainsProtocolImpl for T where T: PySequenceProtocol<'p> {
+ default fn sq_contains() -> Option<ffi::objobjproc> {
+ None
+ }
+@@ -429,10 +414,7 @@ trait PySequenceConcatProtocolImpl {
+ fn sq_concat() -> Option<ffi::binaryfunc>;
+ }
+
+-impl<'p, T> PySequenceConcatProtocolImpl for T
+-where
+- T: PySequenceProtocol<'p>,
+-{
++impl<'p, T> PySequenceConcatProtocolImpl for T where T: PySequenceProtocol<'p> {
+ default fn sq_concat() -> Option<ffi::binaryfunc> {
+ None
+ }
+@@ -456,10 +438,7 @@ trait PySequenceRepeatProtocolImpl {
+ fn sq_repeat() -> Option<ffi::ssizeargfunc>;
+ }
+
+-impl<'p, T> PySequenceRepeatProtocolImpl for T
+-where
+- T: PySequenceProtocol<'p>,
+-{
++impl<'p, T> PySequenceRepeatProtocolImpl for T where T: PySequenceProtocol<'p> {
+ default fn sq_repeat() -> Option<ffi::ssizeargfunc> {
+ None
+ }
+@@ -483,10 +462,7 @@ trait PySequenceInplaceConcatProtocolImpl {
+ fn sq_inplace_concat() -> Option<ffi::binaryfunc>;
+ }
+
+-impl<'p, T> PySequenceInplaceConcatProtocolImpl for T
+-where
+- T: PySequenceProtocol<'p>,
+-{
++impl<'p, T> PySequenceInplaceConcatProtocolImpl for T where T: PySequenceProtocol<'p> {
+ default fn sq_inplace_concat() -> Option<ffi::binaryfunc> {
+ None
+ }
+@@ -510,10 +486,7 @@ trait PySequenceInplaceRepeatProtocolImpl {
+ fn sq_inplace_repeat() -> Option<ffi::ssizeargfunc>;
+ }
+
+-impl<'p, T> PySequenceInplaceRepeatProtocolImpl for T
+-where
+- T: PySequenceProtocol<'p>,
+-{
++impl<'p, T> PySequenceInplaceRepeatProtocolImpl for T where T: PySequenceProtocol<'p> {
+ default fn sq_inplace_repeat() -> Option<ffi::ssizeargfunc> {
+ None
+ }
+diff --git a/src/conversion.rs b/src/conversion.rs
+index 38f436de4..15ccdabde 100644
+--- a/src/conversion.rs
++++ b/src/conversion.rs
+@@ -100,10 +100,7 @@ pub trait ToBorrowedObject: ToPyObject {
+ F: FnOnce(*mut ffi::PyObject) -> R;
+ }
+
+-impl<T> ToBorrowedObject for T
+-where
+- T: ToPyObject,
+-{
++impl<T> ToBorrowedObject for T where T: ToPyObject {
+ default fn with_borrowed_ptr<F, R>(&self, py: Python, f: F) -> R
+ where
+ F: FnOnce(*mut ffi::PyObject) -> R,
diff --git a/srcpkgs/anki/files/pyo3-patches/0011-specialization-89c028e23ab3dab4eaa2277734019f1b8e0210c1.patch b/srcpkgs/anki/files/pyo3-patches/0011-specialization-89c028e23ab3dab4eaa2277734019f1b8e0210c1.patch
new file mode 100644
index 00000000000..ff6e46229e8
--- /dev/null
+++ b/srcpkgs/anki/files/pyo3-patches/0011-specialization-89c028e23ab3dab4eaa2277734019f1b8e0210c1.patch
@@ -0,0 +1,1978 @@
+From 89c028e23ab3dab4eaa2277734019f1b8e0210c1 Mon Sep 17 00:00:00 2001
+From: Martin Donlon <github-martin@donlons.com>
+Date: Fri, 25 Oct 2019 20:52:10 -0700
+Subject: [PATCH] Revert "Fix broken specialized implementations with Rust
+ 1.40"
+
+This reverts commit 5397a62f486a25b2f99aac7aa758161b993af6ae.
+---
+ src/class/basic.rs | 94 ++++------
+ src/class/buffer.rs | 16 +-
+ src/class/context.rs | 24 +--
+ src/class/descr.rs | 23 +--
+ src/class/gc.rs | 22 +--
+ src/class/iter.rs | 22 +--
+ src/class/mapping.rs | 75 +++-----
+ src/class/number.rs | 403 ++++++++++++++++--------------------------
+ src/class/pyasync.rs | 51 ++----
+ src/class/sequence.rs | 80 ++++-----
+ src/conversion.rs | 8 +-
+ src/instance.rs | 39 ++--
+ 12 files changed, 319 insertions(+), 538 deletions(-)
+
+diff --git a/src/class/basic.rs b/src/class/basic.rs
+index 29e19871f..c3153dfa3 100644
+--- a/src/class/basic.rs
++++ b/src/class/basic.rs
+@@ -152,21 +152,17 @@ pub trait PyObjectRichcmpProtocol<'p>: PyObjectProtocol<'p> {
+
+ #[doc(hidden)]
+ pub trait PyObjectProtocolImpl {
+- fn methods() -> Vec<PyMethodDef>;
+- fn tp_as_object(_type_object: &mut ffi::PyTypeObject);
+- fn nb_bool_fn() -> Option<ffi::inquiry>;
+-}
+-
+-impl<T> PyObjectProtocolImpl for T {
+- default fn methods() -> Vec<PyMethodDef> {
++ fn methods() -> Vec<PyMethodDef> {
+ Vec::new()
+ }
+- default fn tp_as_object(_type_object: &mut ffi::PyTypeObject) {}
+- default fn nb_bool_fn() -> Option<ffi::inquiry> {
++ fn tp_as_object(_type_object: &mut ffi::PyTypeObject) {}
++ fn nb_bool_fn() -> Option<ffi::inquiry> {
+ None
+ }
+ }
+
++impl<T> PyObjectProtocolImpl for T {}
++
+ impl<'p, T> PyObjectProtocolImpl for T
+ where
+ T: PyObjectProtocol<'p>,
+@@ -199,15 +195,13 @@ where
+ }
+
+ trait GetAttrProtocolImpl {
+- fn tp_getattro() -> Option<ffi::binaryfunc>;
+-}
+-
+-impl<'p, T> GetAttrProtocolImpl for T where T: PyObjectProtocol<'p> {
+- default fn tp_getattro() -> Option<ffi::binaryfunc> {
++ fn tp_getattro() -> Option<ffi::binaryfunc> {
+ None
+ }
+ }
+
++impl<'p, T> GetAttrProtocolImpl for T where T: PyObjectProtocol<'p> {}
++
+ impl<T> GetAttrProtocolImpl for T
+ where
+ T: for<'p> PyObjectGetAttrProtocol<'p>,
+@@ -274,15 +268,13 @@ mod tp_setattro_impl {
+ }
+
+ trait SetAttr {
+- fn set_attr() -> Option<ffi::setattrofunc>;
+- }
+-
+- impl<'p, T: PyObjectProtocol<'p>> SetAttr for T {
+- default fn set_attr() -> Option<ffi::setattrofunc> {
++ fn set_attr() -> Option<ffi::setattrofunc> {
+ None
+ }
+ }
+
++ impl<'p, T: PyObjectProtocol<'p>> SetAttr for T {}
++
+ impl<T> SetAttr for T
+ where
+ T: for<'p> PyObjectSetAttrProtocol<'p>,
+@@ -293,15 +285,13 @@ mod tp_setattro_impl {
+ }
+
+ trait DelAttr {
+- fn del_attr() -> Option<ffi::setattrofunc>;
+- }
+-
+- impl<'p, T> DelAttr for T where T: PyObjectProtocol<'p> {
+- default fn del_attr() -> Option<ffi::setattrofunc> {
++ fn del_attr() -> Option<ffi::setattrofunc> {
+ None
+ }
+ }
+
++ impl<'p, T> DelAttr for T where T: PyObjectProtocol<'p> {}
++
+ impl<T> DelAttr for T
+ where
+ T: for<'p> PyObjectDelAttrProtocol<'p>,
+@@ -312,15 +302,13 @@ mod tp_setattro_impl {
+ }
+
+ trait SetDelAttr {
+- fn set_del_attr() -> Option<ffi::setattrofunc>;
+- }
+-
+- impl<'p, T> SetDelAttr for T where T: PyObjectProtocol<'p> {
+- default fn set_del_attr() -> Option<ffi::setattrofunc> {
++ fn set_del_attr() -> Option<ffi::setattrofunc> {
+ None
+ }
+ }
+
++ impl<'p, T> SetDelAttr for T where T: PyObjectProtocol<'p> {}
++
+ impl<T> SetDelAttr for T
+ where
+ T: for<'p> PyObjectSetAttrProtocol<'p> + for<'p> PyObjectDelAttrProtocol<'p>,
+@@ -338,13 +326,11 @@ mod tp_setattro_impl {
+ }
+
+ trait StrProtocolImpl {
+- fn tp_str() -> Option<ffi::unaryfunc>;
+-}
+-impl<'p, T> StrProtocolImpl for T where T: PyObjectProtocol<'p> {
+- default fn tp_str() -> Option<ffi::unaryfunc> {
++ fn tp_str() -> Option<ffi::unaryfunc> {
+ None
+ }
+ }
++impl<'p, T> StrProtocolImpl for T where T: PyObjectProtocol<'p> {}
+ impl<T> StrProtocolImpl for T
+ where
+ T: for<'p> PyObjectStrProtocol<'p>,
+@@ -360,13 +346,11 @@ where
+ }
+
+ trait ReprProtocolImpl {
+- fn tp_repr() -> Option<ffi::unaryfunc>;
+-}
+-impl<'p, T> ReprProtocolImpl for T where T: PyObjectProtocol<'p> {
+- default fn tp_repr() -> Option<ffi::unaryfunc> {
++ fn tp_repr() -> Option<ffi::unaryfunc> {
+ None
+ }
+ }
++impl<'p, T> ReprProtocolImpl for T where T: PyObjectProtocol<'p> {}
+ impl<T> ReprProtocolImpl for T
+ where
+ T: for<'p> PyObjectReprProtocol<'p>,
+@@ -383,42 +367,34 @@ where
+
+ #[doc(hidden)]
+ pub trait FormatProtocolImpl {
+- fn __format__() -> Option<PyMethodDef>;
+-}
+-impl<'p, T> FormatProtocolImpl for T where T: PyObjectProtocol<'p> {
+- default fn __format__() -> Option<PyMethodDef> {
++ fn __format__() -> Option<PyMethodDef> {
+ None
+ }
+ }
++impl<'p, T> FormatProtocolImpl for T where T: PyObjectProtocol<'p> {}
+
+ #[doc(hidden)]
+ pub trait BytesProtocolImpl {
+- fn __bytes__() -> Option<PyMethodDef>;
+-}
+-impl<'p, T> BytesProtocolImpl for T where T: PyObjectProtocol<'p> {
+- default fn __bytes__() -> Option<PyMethodDef> {
++ fn __bytes__() -> Option<PyMethodDef> {
+ None
+ }
+ }
++impl<'p, T> BytesProtocolImpl for T where T: PyObjectProtocol<'p> {}
+
+ #[doc(hidden)]
+ pub trait UnicodeProtocolImpl {
+- fn __unicode__() -> Option<PyMethodDef>;
+-}
+-impl<'p, T> UnicodeProtocolImpl for T where T: PyObjectProtocol<'p> {
+- default fn __unicode__() -> Option<PyMethodDef> {
++ fn __unicode__() -> Option<PyMethodDef> {
+ None
+ }
+ }
++impl<'p, T> UnicodeProtocolImpl for T where T: PyObjectProtocol<'p> {}
+
+ trait HashProtocolImpl {
+- fn tp_hash() -> Option<ffi::hashfunc>;
+-}
+-impl<'p, T> HashProtocolImpl for T where T: PyObjectProtocol<'p> {
+- default fn tp_hash() -> Option<ffi::hashfunc> {
++ fn tp_hash() -> Option<ffi::hashfunc> {
+ None
+ }
+ }
++impl<'p, T> HashProtocolImpl for T where T: PyObjectProtocol<'p> {}
+ impl<T> HashProtocolImpl for T
+ where
+ T: for<'p> PyObjectHashProtocol<'p>,
+@@ -435,13 +411,11 @@ where
+ }
+
+ trait BoolProtocolImpl {
+- fn nb_bool() -> Option<ffi::inquiry>;
+-}
+-impl<'p, T> BoolProtocolImpl for T where T: PyObjectProtocol<'p> {
+- default fn nb_bool() -> Option<ffi::inquiry> {
++ fn nb_bool() -> Option<ffi::inquiry> {
+ None
+ }
+ }
++impl<'p, T> BoolProtocolImpl for T where T: PyObjectProtocol<'p> {}
+ impl<T> BoolProtocolImpl for T
+ where
+ T: for<'p> PyObjectBoolProtocol<'p>,
+@@ -458,13 +432,11 @@ where
+ }
+
+ trait RichcmpProtocolImpl {
+- fn tp_richcompare() -> Option<ffi::richcmpfunc>;
+-}
+-impl<'p, T> RichcmpProtocolImpl for T where T: PyObjectProtocol<'p> {
+- default fn tp_richcompare() -> Option<ffi::richcmpfunc> {
++ fn tp_richcompare() -> Option<ffi::richcmpfunc> {
+ None
+ }
+ }
++impl<'p, T> RichcmpProtocolImpl for T where T: PyObjectProtocol<'p> {}
+ impl<T> RichcmpProtocolImpl for T
+ where
+ T: for<'p> PyObjectRichcmpProtocol<'p>,
+diff --git a/src/class/buffer.rs b/src/class/buffer.rs
+index c30f078cc..d36524e7c 100644
+--- a/src/class/buffer.rs
++++ b/src/class/buffer.rs
+@@ -41,15 +41,13 @@ pub trait PyBufferReleaseBufferProtocol<'p>: PyBufferProtocol<'p> {
+
+ #[doc(hidden)]
+ pub trait PyBufferProtocolImpl {
+- fn tp_as_buffer() -> Option<ffi::PyBufferProcs>;
+-}
+-
+-impl<T> PyBufferProtocolImpl for T {
+- default fn tp_as_buffer() -> Option<ffi::PyBufferProcs> {
++ fn tp_as_buffer() -> Option<ffi::PyBufferProcs> {
+ None
+ }
+ }
+
++impl<T> PyBufferProtocolImpl for T {}
++
+ impl<'p, T> PyBufferProtocolImpl for T
+ where
+ T: PyBufferProtocol<'p>,
+@@ -66,15 +64,13 @@ where
+ }
+
+ trait PyBufferGetBufferProtocolImpl {
+- fn cb_bf_getbuffer() -> Option<ffi::getbufferproc>;
+-}
+-
+-impl<'p, T> PyBufferGetBufferProtocolImpl for T where T: PyBufferProtocol<'p> {
+- default fn cb_bf_getbuffer() -> Option<ffi::getbufferproc> {
++ fn cb_bf_getbuffer() -> Option<ffi::getbufferproc> {
+ None
+ }
+ }
+
++impl<'p, T> PyBufferGetBufferProtocolImpl for T where T: PyBufferProtocol<'p> {}
++
+ impl<T> PyBufferGetBufferProtocolImpl for T
+ where
+ T: for<'p> PyBufferGetBufferProtocol<'p>,
+diff --git a/src/class/context.rs b/src/class/context.rs
+index 2ad59768d..092527ba0 100644
+--- a/src/class/context.rs
++++ b/src/class/context.rs
+@@ -47,15 +47,13 @@ pub trait PyContextExitProtocol<'p>: PyContextProtocol<'p> {
+
+ #[doc(hidden)]
+ pub trait PyContextProtocolImpl {
+- fn methods() -> Vec<PyMethodDef>;
+-}
+-
+-impl<T> PyContextProtocolImpl for T {
+- default fn methods() -> Vec<PyMethodDef> {
++ fn methods() -> Vec<PyMethodDef> {
+ Vec::new()
+ }
+ }
+
++impl<T> PyContextProtocolImpl for T {}
++
+ impl<'p, T> PyContextProtocolImpl for T
+ where
+ T: PyContextProtocol<'p>,
+@@ -77,22 +75,18 @@ where
+
+ #[doc(hidden)]
+ pub trait PyContextEnterProtocolImpl {
+- fn __enter__() -> Option<PyMethodDef>;
+-}
+-
+-impl<'p, T> PyContextEnterProtocolImpl for T where T: PyContextProtocol<'p> {
+- default fn __enter__() -> Option<PyMethodDef> {
++ fn __enter__() -> Option<PyMethodDef> {
+ None
+ }
+ }
+
++impl<'p, T> PyContextEnterProtocolImpl for T where T: PyContextProtocol<'p> {}
++
+ #[doc(hidden)]
+ pub trait PyContextExitProtocolImpl {
+- fn __exit__() -> Option<PyMethodDef>;
+-}
+-
+-impl<'p, T> PyContextExitProtocolImpl for T where T: PyContextProtocol<'p> {
+- default fn __exit__() -> Option<PyMethodDef> {
++ fn __exit__() -> Option<PyMethodDef> {
+ None
+ }
+ }
++
++impl<'p, T> PyContextExitProtocolImpl for T where T: PyContextProtocol<'p> {}
+diff --git a/src/class/descr.rs b/src/class/descr.rs
+index c7b5b9660..5f7e68306 100644
+--- a/src/class/descr.rs
++++ b/src/class/descr.rs
+@@ -70,13 +70,11 @@ pub trait PyDescrSetNameProtocol<'p>: PyDescrProtocol<'p> {
+ }
+
+ trait PyDescrGetProtocolImpl {
+- fn tp_descr_get() -> Option<ffi::descrgetfunc>;
+-}
+-impl<'p, T> PyDescrGetProtocolImpl for T where T: PyDescrProtocol<'p> {
+- default fn tp_descr_get() -> Option<ffi::descrgetfunc> {
++ fn tp_descr_get() -> Option<ffi::descrgetfunc> {
+ None
+ }
+ }
++impl<'p, T> PyDescrGetProtocolImpl for T where T: PyDescrProtocol<'p> {}
+
+ impl<T> PyDescrGetProtocolImpl for T
+ where
+@@ -93,13 +91,11 @@ where
+ }
+
+ trait PyDescrSetProtocolImpl {
+- fn tp_descr_set() -> Option<ffi::descrsetfunc>;
+-}
+-impl<'p, T> PyDescrSetProtocolImpl for T where T: PyDescrProtocol<'p> {
+- default fn tp_descr_set() -> Option<ffi::descrsetfunc> {
++ fn tp_descr_set() -> Option<ffi::descrsetfunc> {
+ None
+ }
+ }
++impl<'p, T> PyDescrSetProtocolImpl for T where T: PyDescrProtocol<'p> {}
+ impl<T> PyDescrSetProtocolImpl for T
+ where
+ T: for<'p> PyDescrSetProtocol<'p>,
+@@ -131,17 +127,14 @@ impl<'p, T> PyDescrSetNameProtocolImpl for T where T: PyDescrProtocol<'p> {}
+
+ #[doc(hidden)]
+ pub trait PyDescrProtocolImpl {
+- fn methods() -> Vec<PyMethodDef>;
+- fn tp_as_descr(_type_object: &mut ffi::PyTypeObject);
+-}
+-
+-impl<T> PyDescrProtocolImpl for T {
+- default fn methods() -> Vec<PyMethodDef> {
++ fn methods() -> Vec<PyMethodDef> {
+ Vec::new()
+ }
+- default fn tp_as_descr(_type_object: &mut ffi::PyTypeObject) {}
++ fn tp_as_descr(_type_object: &mut ffi::PyTypeObject) {}
+ }
+
++impl<T> PyDescrProtocolImpl for T {}
++
+ impl<'p, T> PyDescrProtocolImpl for T
+ where
+ T: PyDescrProtocol<'p>,
+diff --git a/src/class/gc.rs b/src/class/gc.rs
+index 4b69c9643..eaa4d9015 100644
+--- a/src/class/gc.rs
++++ b/src/class/gc.rs
+@@ -23,12 +23,10 @@ pub trait PyGCClearProtocol<'p>: PyGCProtocol<'p> {}
+
+ #[doc(hidden)]
+ pub trait PyGCProtocolImpl {
+- fn update_type_object(_type_object: &mut ffi::PyTypeObject);
++ fn update_type_object(_type_object: &mut ffi::PyTypeObject) {}
+ }
+
+-impl<'p, T> PyGCProtocolImpl for T {
+- default fn update_type_object(_type_object: &mut ffi::PyTypeObject) {}
+-}
++impl<'p, T> PyGCProtocolImpl for T {}
+
+ impl<'p, T> PyGCProtocolImpl for T
+ where
+@@ -65,15 +63,13 @@ impl<'p> PyVisit<'p> {
+ }
+
+ trait PyGCTraverseProtocolImpl {
+- fn tp_traverse() -> Option<ffi::traverseproc>;
+-}
+-
+-impl<'p, T> PyGCTraverseProtocolImpl for T where T: PyGCProtocol<'p> {
+- default fn tp_traverse() -> Option<ffi::traverseproc> {
++ fn tp_traverse() -> Option<ffi::traverseproc> {
+ None
+ }
+ }
+
++impl<'p, T> PyGCTraverseProtocolImpl for T where T: PyGCProtocol<'p> {}
++
+ #[doc(hidden)]
+ impl<T> PyGCTraverseProtocolImpl for T
+ where
+@@ -109,15 +105,13 @@ where
+ }
+
+ trait PyGCClearProtocolImpl {
+- fn tp_clear() -> Option<ffi::inquiry>;
+-}
+-
+-impl<'p, T> PyGCClearProtocolImpl for T where T: PyGCProtocol<'p> {
+- default fn tp_clear() -> Option<ffi::inquiry> {
++ fn tp_clear() -> Option<ffi::inquiry> {
+ None
+ }
+ }
+
++impl<'p, T> PyGCClearProtocolImpl for T where T: PyGCProtocol<'p> {}
++
+ impl<T> PyGCClearProtocolImpl for T
+ where
+ T: for<'p> PyGCClearProtocol<'p>,
+diff --git a/src/class/iter.rs b/src/class/iter.rs
+index fcf76f2e5..9001d53ce 100644
+--- a/src/class/iter.rs
++++ b/src/class/iter.rs
+@@ -44,12 +44,10 @@ pub trait PyIterNextProtocol<'p>: PyIterProtocol<'p> {
+
+ #[doc(hidden)]
+ pub trait PyIterProtocolImpl {
+- fn tp_as_iter(_typeob: &mut ffi::PyTypeObject);
++ fn tp_as_iter(_typeob: &mut ffi::PyTypeObject) {}
+ }
+
+-impl<T> PyIterProtocolImpl for T {
+- default fn tp_as_iter(_typeob: &mut ffi::PyTypeObject) {}
+-}
++impl<T> PyIterProtocolImpl for T {}
+
+ impl<'p, T> PyIterProtocolImpl for T
+ where
+@@ -63,15 +61,13 @@ where
+ }
+
+ trait PyIterIterProtocolImpl {
+- fn tp_iter() -> Option<ffi::getiterfunc>;
+-}
+-
+-impl<'p, T> PyIterIterProtocolImpl for T where T: PyIterProtocol<'p> {
+- default fn tp_iter() -> Option<ffi::getiterfunc> {
++ fn tp_iter() -> Option<ffi::getiterfunc> {
+ None
+ }
+ }
+
++impl<'p, T> PyIterIterProtocolImpl for T where T: PyIterProtocol<'p> {}
++
+ impl<T> PyIterIterProtocolImpl for T
+ where
+ T: for<'p> PyIterIterProtocol<'p>,
+@@ -88,15 +84,13 @@ where
+ }
+
+ trait PyIterNextProtocolImpl {
+- fn tp_iternext() -> Option<ffi::iternextfunc>;
+-}
+-
+-impl<'p, T> PyIterNextProtocolImpl for T where T: PyIterProtocol<'p> {
+- default fn tp_iternext() -> Option<ffi::iternextfunc> {
++ fn tp_iternext() -> Option<ffi::iternextfunc> {
+ None
+ }
+ }
+
++impl<'p, T> PyIterNextProtocolImpl for T where T: PyIterProtocol<'p> {}
++
+ impl<T> PyIterNextProtocolImpl for T
+ where
+ T: for<'p> PyIterNextProtocol<'p>,
+diff --git a/src/class/mapping.rs b/src/class/mapping.rs
+index 64d7b57ce..616763502 100644
+--- a/src/class/mapping.rs
++++ b/src/class/mapping.rs
+@@ -106,19 +106,16 @@ pub trait PyMappingReversedProtocol<'p>: PyMappingProtocol<'p> {
+
+ #[doc(hidden)]
+ pub trait PyMappingProtocolImpl {
+- fn tp_as_mapping() -> Option<ffi::PyMappingMethods>;
+- fn methods() -> Vec<PyMethodDef>;
+-}
+-
+-impl<T> PyMappingProtocolImpl for T {
+- default fn tp_as_mapping() -> Option<ffi::PyMappingMethods> {
++ fn tp_as_mapping() -> Option<ffi::PyMappingMethods> {
+ None
+ }
+- default fn methods() -> Vec<PyMethodDef> {
++ fn methods() -> Vec<PyMethodDef> {
+ Vec::new()
+ }
+ }
+
++impl<T> PyMappingProtocolImpl for T {}
++
+ impl<'p, T> PyMappingProtocolImpl for T
+ where
+ T: PyMappingProtocol<'p>,
+@@ -157,15 +154,13 @@ where
+ }
+
+ trait PyMappingLenProtocolImpl {
+- fn mp_length() -> Option<ffi::lenfunc>;
+-}
+-
+-impl<'p, T> PyMappingLenProtocolImpl for T where T: PyMappingProtocol<'p> {
+- default fn mp_length() -> Option<ffi::lenfunc> {
++ fn mp_length() -> Option<ffi::lenfunc> {
+ None
+ }
+ }
+
++impl<'p, T> PyMappingLenProtocolImpl for T where T: PyMappingProtocol<'p> {}
++
+ impl<T> PyMappingLenProtocolImpl for T
+ where
+ T: for<'p> PyMappingLenProtocol<'p>,
+@@ -177,15 +172,13 @@ where
+ }
+
+ trait PyMappingGetItemProtocolImpl {
+- fn mp_subscript() -> Option<ffi::binaryfunc>;
+-}
+-
+-impl<'p, T> PyMappingGetItemProtocolImpl for T where T: PyMappingProtocol<'p> {
+- default fn mp_subscript() -> Option<ffi::binaryfunc> {
++ fn mp_subscript() -> Option<ffi::binaryfunc> {
+ None
+ }
+ }
+
++impl<'p, T> PyMappingGetItemProtocolImpl for T where T: PyMappingProtocol<'p> {}
++
+ impl<T> PyMappingGetItemProtocolImpl for T
+ where
+ T: for<'p> PyMappingGetItemProtocol<'p>,
+@@ -202,15 +195,13 @@ where
+ }
+
+ trait PyMappingSetItemProtocolImpl {
+- fn mp_ass_subscript() -> Option<ffi::objobjargproc>;
+-}
+-
+-impl<'p, T> PyMappingSetItemProtocolImpl for T where T: PyMappingProtocol<'p> {
+- default fn mp_ass_subscript() -> Option<ffi::objobjargproc> {
++ fn mp_ass_subscript() -> Option<ffi::objobjargproc> {
+ None
+ }
+ }
+
++impl<'p, T> PyMappingSetItemProtocolImpl for T where T: PyMappingProtocol<'p> {}
++
+ impl<T> PyMappingSetItemProtocolImpl for T
+ where
+ T: for<'p> PyMappingSetItemProtocol<'p>,
+@@ -224,26 +215,22 @@ where
+ /// Returns `None` if PyMappingDelItemProtocol isn't implemented, otherwise dispatches to
+ /// `DelSetItemDispatch`
+ trait DeplItemDipatch {
+- fn mp_del_subscript() -> Option<ffi::objobjargproc>;
+-}
+-
+-impl<'p, T> DeplItemDipatch for T where T: PyMappingProtocol<'p> {
+- default fn mp_del_subscript() -> Option<ffi::objobjargproc> {
++ fn mp_del_subscript() -> Option<ffi::objobjargproc> {
+ None
+ }
+ }
+
++impl<'p, T> DeplItemDipatch for T where T: PyMappingProtocol<'p> {}
++
+ /// Returns `py_func_set_del` if PyMappingSetItemProtocol is implemented, otherwise `py_func_del`
+ trait DelSetItemDispatch: Sized + for<'p> PyMappingDelItemProtocol<'p> {
+- fn det_set_dispatch() -> Option<ffi::objobjargproc>;
+-}
+-
+-impl<T> DelSetItemDispatch for T where T: Sized + for<'p> PyMappingDelItemProtocol<'p> {
+- default fn det_set_dispatch() -> Option<ffi::objobjargproc> {
++ fn det_set_dispatch() -> Option<ffi::objobjargproc> {
+ py_func_del!(PyMappingDelItemProtocol, Self, __delitem__)
+ }
+ }
+
++impl<T> DelSetItemDispatch for T where T: Sized + for<'p> PyMappingDelItemProtocol<'p> {}
++
+ impl<T> DelSetItemDispatch for T
+ where
+ T: for<'p> PyMappingSetItemProtocol<'p> + for<'p> PyMappingDelItemProtocol<'p>,
+@@ -270,33 +257,27 @@ where
+
+ #[doc(hidden)]
+ pub trait PyMappingContainsProtocolImpl {
+- fn __contains__() -> Option<PyMethodDef>;
+-}
+-
+-impl<'p, T> PyMappingContainsProtocolImpl for T where T: PyMappingProtocol<'p> {
+- default fn __contains__() -> Option<PyMethodDef> {
++ fn __contains__() -> Option<PyMethodDef> {
+ None
+ }
+ }
+
++impl<'p, T> PyMappingContainsProtocolImpl for T where T: PyMappingProtocol<'p> {}
++
+ #[doc(hidden)]
+ pub trait PyMappingReversedProtocolImpl {
+- fn __reversed__() -> Option<PyMethodDef>;
+-}
+-
+-impl<'p, T> PyMappingReversedProtocolImpl for T where T: PyMappingProtocol<'p> {
+- default fn __reversed__() -> Option<PyMethodDef> {
++ fn __reversed__() -> Option<PyMethodDef> {
+ None
+ }
+ }
+
++impl<'p, T> PyMappingReversedProtocolImpl for T where T: PyMappingProtocol<'p> {}
++
+ #[doc(hidden)]
+ pub trait PyMappingIterProtocolImpl {
+- fn __iter__() -> Option<PyMethodDef>;
+-}
+-
+-impl<'p, T> PyMappingIterProtocolImpl for T where T: PyMappingProtocol<'p> {
+- default fn __iter__() -> Option<PyMethodDef> {
++ fn __iter__() -> Option<PyMethodDef> {
+ None
+ }
+ }
++
++impl<'p, T> PyMappingIterProtocolImpl for T where T: PyMappingProtocol<'p> {}
+diff --git a/src/class/number.rs b/src/class/number.rs
+index 0ab162e72..2ee3a57d5 100644
+--- a/src/class/number.rs
++++ b/src/class/number.rs
+@@ -622,15 +622,10 @@ pub trait PyNumberIndexProtocol<'p>: PyNumberProtocol<'p> {
+
+ #[doc(hidden)]
+ pub trait PyNumberProtocolImpl: PyObjectProtocolImpl {
+- fn methods() -> Vec<PyMethodDef>;
+- fn tp_as_number() -> Option<ffi::PyNumberMethods>;
+-}
+-
+-impl<'p, T> PyNumberProtocolImpl for T {
+- default fn methods() -> Vec<PyMethodDef> {
++ fn methods() -> Vec<PyMethodDef> {
+ Vec::new()
+ }
+- default fn tp_as_number() -> Option<ffi::PyNumberMethods> {
++ fn tp_as_number() -> Option<ffi::PyNumberMethods> {
+ if let Some(nb_bool) = <Self as PyObjectProtocolImpl>::nb_bool_fn() {
+ let meth = ffi::PyNumberMethods {
+ nb_bool: Some(nb_bool),
+@@ -643,6 +638,8 @@ impl<'p, T> PyNumberProtocolImpl for T {
+ }
+ }
+
++impl<'p, T> PyNumberProtocolImpl for T {}
++
+ impl<'p, T> PyNumberProtocolImpl for T
+ where
+ T: PyNumberProtocol<'p>,
+@@ -746,15 +743,13 @@ where
+ }
+
+ trait PyNumberAddProtocolImpl {
+- fn nb_add() -> Option<ffi::binaryfunc>;
+-}
+-
+-impl<'p, T> PyNumberAddProtocolImpl for T where T: PyNumberProtocol<'p> {
+- default fn nb_add() -> Option<ffi::binaryfunc> {
++ fn nb_add() -> Option<ffi::binaryfunc> {
+ None
+ }
+ }
+
++impl<'p, T> PyNumberAddProtocolImpl for T where T: PyNumberProtocol<'p> {}
++
+ impl<T> PyNumberAddProtocolImpl for T
+ where
+ T: for<'p> PyNumberAddProtocol<'p>,
+@@ -770,15 +765,13 @@ where
+ }
+
+ trait PyNumberSubProtocolImpl {
+- fn nb_subtract() -> Option<ffi::binaryfunc>;
+-}
+-
+-impl<'p, T> PyNumberSubProtocolImpl for T where T: PyNumberProtocol<'p> {
+- default fn nb_subtract() -> Option<ffi::binaryfunc> {
++ fn nb_subtract() -> Option<ffi::binaryfunc> {
+ None
+ }
+ }
+
++impl<'p, T> PyNumberSubProtocolImpl for T where T: PyNumberProtocol<'p> {}
++
+ impl<T> PyNumberSubProtocolImpl for T
+ where
+ T: for<'p> PyNumberSubProtocol<'p>,
+@@ -794,15 +787,13 @@ where
+ }
+
+ trait PyNumberMulProtocolImpl {
+- fn nb_multiply() -> Option<ffi::binaryfunc>;
+-}
+-
+-impl<'p, T> PyNumberMulProtocolImpl for T where T: PyNumberProtocol<'p> {
+- default fn nb_multiply() -> Option<ffi::binaryfunc> {
++ fn nb_multiply() -> Option<ffi::binaryfunc> {
+ None
+ }
+ }
+
++impl<'p, T> PyNumberMulProtocolImpl for T where T: PyNumberProtocol<'p> {}
++
+ impl<T> PyNumberMulProtocolImpl for T
+ where
+ T: for<'p> PyNumberMulProtocol<'p>,
+@@ -818,15 +809,13 @@ where
+ }
+
+ trait PyNumberMatmulProtocolImpl {
+- fn nb_matrix_multiply() -> Option<ffi::binaryfunc>;
+-}
+-
+-impl<'p, T> PyNumberMatmulProtocolImpl for T where T: PyNumberProtocol<'p> {
+- default fn nb_matrix_multiply() -> Option<ffi::binaryfunc> {
++ fn nb_matrix_multiply() -> Option<ffi::binaryfunc> {
+ None
+ }
+ }
+
++impl<'p, T> PyNumberMatmulProtocolImpl for T where T: PyNumberProtocol<'p> {}
++
+ impl<T> PyNumberMatmulProtocolImpl for T
+ where
+ T: for<'p> PyNumberMatmulProtocol<'p>,
+@@ -842,15 +831,13 @@ where
+ }
+
+ trait PyNumberTruedivProtocolImpl {
+- fn nb_true_divide() -> Option<ffi::binaryfunc>;
+-}
+-
+-impl<'p, T> PyNumberTruedivProtocolImpl for T where T: PyNumberProtocol<'p> {
+- default fn nb_true_divide() -> Option<ffi::binaryfunc> {
++ fn nb_true_divide() -> Option<ffi::binaryfunc> {
+ None
+ }
+ }
+
++impl<'p, T> PyNumberTruedivProtocolImpl for T where T: PyNumberProtocol<'p> {}
++
+ impl<T> PyNumberTruedivProtocolImpl for T
+ where
+ T: for<'p> PyNumberTruedivProtocol<'p>,
+@@ -866,15 +853,13 @@ where
+ }
+
+ trait PyNumberFloordivProtocolImpl {
+- fn nb_floor_divide() -> Option<ffi::binaryfunc>;
+-}
+-
+-impl<'p, T> PyNumberFloordivProtocolImpl for T where T: PyNumberProtocol<'p> {
+- default fn nb_floor_divide() -> Option<ffi::binaryfunc> {
++ fn nb_floor_divide() -> Option<ffi::binaryfunc> {
+ None
+ }
+ }
+
++impl<'p, T> PyNumberFloordivProtocolImpl for T where T: PyNumberProtocol<'p> {}
++
+ impl<T> PyNumberFloordivProtocolImpl for T
+ where
+ T: for<'p> PyNumberFloordivProtocol<'p>,
+@@ -890,15 +875,13 @@ where
+ }
+
+ trait PyNumberModProtocolImpl {
+- fn nb_remainder() -> Option<ffi::binaryfunc>;
+-}
+-
+-impl<'p, T> PyNumberModProtocolImpl for T where T: PyNumberProtocol<'p> {
+- default fn nb_remainder() -> Option<ffi::binaryfunc> {
++ fn nb_remainder() -> Option<ffi::binaryfunc> {
+ None
+ }
+ }
+
++impl<'p, T> PyNumberModProtocolImpl for T where T: PyNumberProtocol<'p> {}
++
+ impl<T> PyNumberModProtocolImpl for T
+ where
+ T: for<'p> PyNumberModProtocol<'p>,
+@@ -914,15 +897,13 @@ where
+ }
+
+ trait PyNumberDivmodProtocolImpl {
+- fn nb_divmod() -> Option<ffi::binaryfunc>;
+-}
+-
+-impl<'p, T> PyNumberDivmodProtocolImpl for T where T: PyNumberProtocol<'p> {
+- default fn nb_divmod() -> Option<ffi::binaryfunc> {
++ fn nb_divmod() -> Option<ffi::binaryfunc> {
+ None
+ }
+ }
+
++impl<'p, T> PyNumberDivmodProtocolImpl for T where T: PyNumberProtocol<'p> {}
++
+ impl<T> PyNumberDivmodProtocolImpl for T
+ where
+ T: for<'p> PyNumberDivmodProtocol<'p>,
+@@ -938,15 +919,13 @@ where
+ }
+
+ trait PyNumberPowProtocolImpl {
+- fn nb_power() -> Option<ffi::ternaryfunc>;
+-}
+-
+-impl<'p, T> PyNumberPowProtocolImpl for T where T: PyNumberProtocol<'p> {
+- default fn nb_power() -> Option<ffi::ternaryfunc> {
++ fn nb_power() -> Option<ffi::ternaryfunc> {
+ None
+ }
+ }
+
++impl<'p, T> PyNumberPowProtocolImpl for T where T: PyNumberProtocol<'p> {}
++
+ impl<T> PyNumberPowProtocolImpl for T
+ where
+ T: for<'p> PyNumberPowProtocol<'p>,
+@@ -962,15 +941,13 @@ where
+ }
+
+ trait PyNumberLShiftProtocolImpl {
+- fn nb_lshift() -> Option<ffi::binaryfunc>;
+-}
+-
+-impl<'p, T> PyNumberLShiftProtocolImpl for T where T: PyNumberProtocol<'p> {
+- default fn nb_lshift() -> Option<ffi::binaryfunc> {
++ fn nb_lshift() -> Option<ffi::binaryfunc> {
+ None
+ }
+ }
+
++impl<'p, T> PyNumberLShiftProtocolImpl for T where T: PyNumberProtocol<'p> {}
++
+ impl<T> PyNumberLShiftProtocolImpl for T
+ where
+ T: for<'p> PyNumberLShiftProtocol<'p>,
+@@ -986,15 +963,13 @@ where
+ }
+
+ trait PyNumberRShiftProtocolImpl {
+- fn nb_rshift() -> Option<ffi::binaryfunc>;
+-}
+-
+-impl<'p, T> PyNumberRShiftProtocolImpl for T where T: PyNumberProtocol<'p> {
+- default fn nb_rshift() -> Option<ffi::binaryfunc> {
++ fn nb_rshift() -> Option<ffi::binaryfunc> {
+ None
+ }
+ }
+
++impl<'p, T> PyNumberRShiftProtocolImpl for T where T: PyNumberProtocol<'p> {}
++
+ impl<T> PyNumberRShiftProtocolImpl for T
+ where
+ T: for<'p> PyNumberRShiftProtocol<'p>,
+@@ -1010,15 +985,13 @@ where
+ }
+
+ trait PyNumberAndProtocolImpl {
+- fn nb_and() -> Option<ffi::binaryfunc>;
+-}
+-
+-impl<'p, T> PyNumberAndProtocolImpl for T where T: PyNumberProtocol<'p> {
+- default fn nb_and() -> Option<ffi::binaryfunc> {
++ fn nb_and() -> Option<ffi::binaryfunc> {
+ None
+ }
+ }
+
++impl<'p, T> PyNumberAndProtocolImpl for T where T: PyNumberProtocol<'p> {}
++
+ impl<T> PyNumberAndProtocolImpl for T
+ where
+ T: for<'p> PyNumberAndProtocol<'p>,
+@@ -1034,15 +1007,13 @@ where
+ }
+
+ trait PyNumberXorProtocolImpl {
+- fn nb_xor() -> Option<ffi::binaryfunc>;
+-}
+-
+-impl<'p, T> PyNumberXorProtocolImpl for T where T: PyNumberProtocol<'p> {
+- default fn nb_xor() -> Option<ffi::binaryfunc> {
++ fn nb_xor() -> Option<ffi::binaryfunc> {
+ None
+ }
+ }
+
++impl<'p, T> PyNumberXorProtocolImpl for T where T: PyNumberProtocol<'p> {}
++
+ impl<T> PyNumberXorProtocolImpl for T
+ where
+ T: for<'p> PyNumberXorProtocol<'p>,
+@@ -1058,15 +1029,13 @@ where
+ }
+
+ trait PyNumberOrProtocolImpl {
+- fn nb_or() -> Option<ffi::binaryfunc>;
+-}
+-
+-impl<'p, T> PyNumberOrProtocolImpl for T where T: PyNumberProtocol<'p> {
+- default fn nb_or() -> Option<ffi::binaryfunc> {
++ fn nb_or() -> Option<ffi::binaryfunc> {
+ None
+ }
+ }
+
++impl<'p, T> PyNumberOrProtocolImpl for T where T: PyNumberProtocol<'p> {}
++
+ impl<T> PyNumberOrProtocolImpl for T
+ where
+ T: for<'p> PyNumberOrProtocol<'p>,
+@@ -1082,15 +1051,13 @@ where
+ }
+
+ trait PyNumberIAddProtocolImpl {
+- fn nb_inplace_add() -> Option<ffi::binaryfunc>;
+-}
+-
+-impl<'p, T> PyNumberIAddProtocolImpl for T where T: PyNumberProtocol<'p> {
+- default fn nb_inplace_add() -> Option<ffi::binaryfunc> {
++ fn nb_inplace_add() -> Option<ffi::binaryfunc> {
+ None
+ }
+ }
+
++impl<'p, T> PyNumberIAddProtocolImpl for T where T: PyNumberProtocol<'p> {}
++
+ impl<T> PyNumberIAddProtocolImpl for T
+ where
+ T: for<'p> PyNumberIAddProtocol<'p>,
+@@ -1101,15 +1068,13 @@ where
+ }
+
+ trait PyNumberISubProtocolImpl {
+- fn nb_inplace_subtract() -> Option<ffi::binaryfunc>;
+-}
+-
+-impl<'p, T> PyNumberISubProtocolImpl for T where T: PyNumberProtocol<'p> {
+- default fn nb_inplace_subtract() -> Option<ffi::binaryfunc> {
++ fn nb_inplace_subtract() -> Option<ffi::binaryfunc> {
+ None
+ }
+ }
+
++impl<'p, T> PyNumberISubProtocolImpl for T where T: PyNumberProtocol<'p> {}
++
+ impl<T> PyNumberISubProtocolImpl for T
+ where
+ T: for<'p> PyNumberISubProtocol<'p>,
+@@ -1120,15 +1085,13 @@ where
+ }
+
+ trait PyNumberIMulProtocolImpl {
+- fn nb_inplace_multiply() -> Option<ffi::binaryfunc>;
+-}
+-
+-impl<'p, T> PyNumberIMulProtocolImpl for T where T: PyNumberProtocol<'p> {
+- default fn nb_inplace_multiply() -> Option<ffi::binaryfunc> {
++ fn nb_inplace_multiply() -> Option<ffi::binaryfunc> {
+ None
+ }
+ }
+
++impl<'p, T> PyNumberIMulProtocolImpl for T where T: PyNumberProtocol<'p> {}
++
+ impl<T> PyNumberIMulProtocolImpl for T
+ where
+ T: for<'p> PyNumberIMulProtocol<'p>,
+@@ -1139,15 +1102,13 @@ where
+ }
+
+ trait PyNumberIMatmulProtocolImpl {
+- fn nb_inplace_matrix_multiply() -> Option<ffi::binaryfunc>;
+-}
+-
+-impl<'p, T> PyNumberIMatmulProtocolImpl for T where T: PyNumberProtocol<'p> {
+- default fn nb_inplace_matrix_multiply() -> Option<ffi::binaryfunc> {
++ fn nb_inplace_matrix_multiply() -> Option<ffi::binaryfunc> {
+ None
+ }
+ }
+
++impl<'p, T> PyNumberIMatmulProtocolImpl for T where T: PyNumberProtocol<'p> {}
++
+ impl<T> PyNumberIMatmulProtocolImpl for T
+ where
+ T: for<'p> PyNumberIMatmulProtocol<'p>,
+@@ -1158,15 +1119,13 @@ where
+ }
+
+ trait PyNumberITruedivProtocolImpl {
+- fn nb_inplace_true_divide() -> Option<ffi::binaryfunc>;
+-}
+-
+-impl<'p, T> PyNumberITruedivProtocolImpl for T where T: PyNumberProtocol<'p> {
+- default fn nb_inplace_true_divide() -> Option<ffi::binaryfunc> {
++ fn nb_inplace_true_divide() -> Option<ffi::binaryfunc> {
+ None
+ }
+ }
+
++impl<'p, T> PyNumberITruedivProtocolImpl for T where T: PyNumberProtocol<'p> {}
++
+ impl<T> PyNumberITruedivProtocolImpl for T
+ where
+ T: for<'p> PyNumberITruedivProtocol<'p>,
+@@ -1177,15 +1136,13 @@ where
+ }
+
+ trait PyNumberIFloordivProtocolImpl {
+- fn nb_inplace_floor_divide() -> Option<ffi::binaryfunc>;
+-}
+-
+-impl<'p, T> PyNumberIFloordivProtocolImpl for T where T: PyNumberProtocol<'p> {
+- default fn nb_inplace_floor_divide() -> Option<ffi::binaryfunc> {
++ fn nb_inplace_floor_divide() -> Option<ffi::binaryfunc> {
+ None
+ }
+ }
+
++impl<'p, T> PyNumberIFloordivProtocolImpl for T where T: PyNumberProtocol<'p> {}
++
+ impl<T> PyNumberIFloordivProtocolImpl for T
+ where
+ T: for<'p> PyNumberIFloordivProtocol<'p>,
+@@ -1196,15 +1153,13 @@ where
+ }
+
+ trait PyNumberIModProtocolImpl {
+- fn nb_inplace_remainder() -> Option<ffi::binaryfunc>;
+-}
+-
+-impl<'p, T> PyNumberIModProtocolImpl for T where T: PyNumberProtocol<'p> {
+- default fn nb_inplace_remainder() -> Option<ffi::binaryfunc> {
++ fn nb_inplace_remainder() -> Option<ffi::binaryfunc> {
+ None
+ }
+ }
+
++impl<'p, T> PyNumberIModProtocolImpl for T where T: PyNumberProtocol<'p> {}
++
+ impl<T> PyNumberIModProtocolImpl for T
+ where
+ T: for<'p> PyNumberIModProtocol<'p>,
+@@ -1215,15 +1170,13 @@ where
+ }
+
+ trait PyNumberIPowProtocolImpl {
+- fn nb_inplace_power() -> Option<ffi::ternaryfunc>;
+-}
+-
+-impl<'p, T> PyNumberIPowProtocolImpl for T where T: PyNumberProtocol<'p> {
+- default fn nb_inplace_power() -> Option<ffi::ternaryfunc> {
++ fn nb_inplace_power() -> Option<ffi::ternaryfunc> {
+ None
+ }
+ }
+
++impl<'p, T> PyNumberIPowProtocolImpl for T where T: PyNumberProtocol<'p> {}
++
+ impl<T> PyNumberIPowProtocolImpl for T
+ where
+ T: for<'p> PyNumberIPowProtocol<'p>,
+@@ -1234,15 +1187,13 @@ where
+ }
+
+ trait PyNumberILShiftProtocolImpl {
+- fn nb_inplace_lshift() -> Option<ffi::binaryfunc>;
+-}
+-
+-impl<'p, T> PyNumberILShiftProtocolImpl for T where T: PyNumberProtocol<'p> {
+- default fn nb_inplace_lshift() -> Option<ffi::binaryfunc> {
++ fn nb_inplace_lshift() -> Option<ffi::binaryfunc> {
+ None
+ }
+ }
+
++impl<'p, T> PyNumberILShiftProtocolImpl for T where T: PyNumberProtocol<'p> {}
++
+ impl<T> PyNumberILShiftProtocolImpl for T
+ where
+ T: for<'p> PyNumberILShiftProtocol<'p>,
+@@ -1253,15 +1204,13 @@ where
+ }
+
+ trait PyNumberIRShiftProtocolImpl {
+- fn nb_inplace_rshift() -> Option<ffi::binaryfunc>;
+-}
+-
+-impl<'p, T> PyNumberIRShiftProtocolImpl for T where T: PyNumberProtocol<'p> {
+- default fn nb_inplace_rshift() -> Option<ffi::binaryfunc> {
++ fn nb_inplace_rshift() -> Option<ffi::binaryfunc> {
+ None
+ }
+ }
+
++impl<'p, T> PyNumberIRShiftProtocolImpl for T where T: PyNumberProtocol<'p> {}
++
+ impl<T> PyNumberIRShiftProtocolImpl for T
+ where
+ T: for<'p> PyNumberIRShiftProtocol<'p>,
+@@ -1272,15 +1221,13 @@ where
+ }
+
+ trait PyNumberIAndProtocolImpl {
+- fn nb_inplace_and() -> Option<ffi::binaryfunc>;
+-}
+-
+-impl<'p, T> PyNumberIAndProtocolImpl for T where T: PyNumberProtocol<'p> {
+- default fn nb_inplace_and() -> Option<ffi::binaryfunc> {
++ fn nb_inplace_and() -> Option<ffi::binaryfunc> {
+ None
+ }
+ }
+
++impl<'p, T> PyNumberIAndProtocolImpl for T where T: PyNumberProtocol<'p> {}
++
+ impl<T> PyNumberIAndProtocolImpl for T
+ where
+ T: for<'p> PyNumberIAndProtocol<'p>,
+@@ -1291,15 +1238,13 @@ where
+ }
+
+ trait PyNumberIXorProtocolImpl {
+- fn nb_inplace_xor() -> Option<ffi::binaryfunc>;
+-}
+-
+-impl<'p, T> PyNumberIXorProtocolImpl for T where T: PyNumberProtocol<'p> {
+- default fn nb_inplace_xor() -> Option<ffi::binaryfunc> {
++ fn nb_inplace_xor() -> Option<ffi::binaryfunc> {
+ None
+ }
+ }
+
++impl<'p, T> PyNumberIXorProtocolImpl for T where T: PyNumberProtocol<'p> {}
++
+ impl<T> PyNumberIXorProtocolImpl for T
+ where
+ T: for<'p> PyNumberIXorProtocol<'p>,
+@@ -1310,15 +1255,13 @@ where
+ }
+
+ trait PyNumberIOrProtocolImpl {
+- fn nb_inplace_or() -> Option<ffi::binaryfunc>;
+-}
+-
+-impl<'p, T> PyNumberIOrProtocolImpl for T where T: PyNumberProtocol<'p> {
+- default fn nb_inplace_or() -> Option<ffi::binaryfunc> {
++ fn nb_inplace_or() -> Option<ffi::binaryfunc> {
+ None
+ }
+ }
+
++impl<'p, T> PyNumberIOrProtocolImpl for T where T: PyNumberProtocol<'p> {}
++
+ impl<T> PyNumberIOrProtocolImpl for T
+ where
+ T: for<'p> PyNumberIOrProtocol<'p>,
+@@ -1330,15 +1273,13 @@ where
+
+ #[doc(hidden)]
+ pub trait PyNumberRAddProtocolImpl {
+- fn __radd__() -> Option<PyMethodDef>;
+-}
+-
+-impl<'p, T> PyNumberRAddProtocolImpl for T where T: PyNumberProtocol<'p> {
+- default fn __radd__() -> Option<PyMethodDef> {
++ fn __radd__() -> Option<PyMethodDef> {
+ None
+ }
+ }
+
++impl<'p, T> PyNumberRAddProtocolImpl for T where T: PyNumberProtocol<'p> {}
++
+ #[doc(hidden)]
+ pub trait PyNumberRSubProtocolImpl {
+ fn __rsub__() -> Option<PyMethodDef> {
+@@ -1350,146 +1291,120 @@ impl<'p, T> PyNumberRSubProtocolImpl for T where T: PyNumberProtocol<'p> {}
+
+ #[doc(hidden)]
+ pub trait PyNumberRMulProtocolImpl {
+- fn __rmul__() -> Option<PyMethodDef>;
+-}
+-
+-impl<'p, T> PyNumberRMulProtocolImpl for T where T: PyNumberProtocol<'p> {
+- default fn __rmul__() -> Option<PyMethodDef> {
++ fn __rmul__() -> Option<PyMethodDef> {
+ None
+ }
+ }
+
++impl<'p, T> PyNumberRMulProtocolImpl for T where T: PyNumberProtocol<'p> {}
++
+ #[doc(hidden)]
+ pub trait PyNumberRMatmulProtocolImpl {
+- fn __rmatmul__() -> Option<PyMethodDef>;
+-}
+-
+-impl<'p, T> PyNumberRMatmulProtocolImpl for T where T: PyNumberProtocol<'p> {
+- default fn __rmatmul__() -> Option<PyMethodDef> {
++ fn __rmatmul__() -> Option<PyMethodDef> {
+ None
+ }
+ }
+
++impl<'p, T> PyNumberRMatmulProtocolImpl for T where T: PyNumberProtocol<'p> {}
++
+ #[doc(hidden)]
+ pub trait PyNumberRTruedivProtocolImpl {
+- fn __rtruediv__() -> Option<PyMethodDef>;
+-}
+-
+-impl<'p, T> PyNumberRTruedivProtocolImpl for T where T: PyNumberProtocol<'p> {
+- default fn __rtruediv__() -> Option<PyMethodDef> {
++ fn __rtruediv__() -> Option<PyMethodDef> {
+ None
+ }
+ }
+
++impl<'p, T> PyNumberRTruedivProtocolImpl for T where T: PyNumberProtocol<'p> {}
++
+ #[doc(hidden)]
+ pub trait PyNumberRFloordivProtocolImpl {
+- fn __rfloordiv__() -> Option<PyMethodDef>;
+-}
+-
+-impl<'p, T> PyNumberRFloordivProtocolImpl for T where T: PyNumberProtocol<'p> {
+- default fn __rfloordiv__() -> Option<PyMethodDef> {
++ fn __rfloordiv__() -> Option<PyMethodDef> {
+ None
+ }
+ }
+
++impl<'p, T> PyNumberRFloordivProtocolImpl for T where T: PyNumberProtocol<'p> {}
++
+ #[doc(hidden)]
+ pub trait PyNumberRModProtocolImpl {
+- fn __rmod__() -> Option<PyMethodDef>;
+-}
+-
+-impl<'p, T> PyNumberRModProtocolImpl for T where T: PyNumberProtocol<'p> {
+- default fn __rmod__() -> Option<PyMethodDef> {
++ fn __rmod__() -> Option<PyMethodDef> {
+ None
+ }
+ }
+
++impl<'p, T> PyNumberRModProtocolImpl for T where T: PyNumberProtocol<'p> {}
++
+ #[doc(hidden)]
+ pub trait PyNumberRDivmodProtocolImpl {
+- fn __rdivmod__() -> Option<PyMethodDef>;
+-}
+-
+-impl<'p, T> PyNumberRDivmodProtocolImpl for T where T: PyNumberProtocol<'p> {
+- default fn __rdivmod__() -> Option<PyMethodDef> {
++ fn __rdivmod__() -> Option<PyMethodDef> {
+ None
+ }
+ }
+
++impl<'p, T> PyNumberRDivmodProtocolImpl for T where T: PyNumberProtocol<'p> {}
++
+ #[doc(hidden)]
+ pub trait PyNumberRPowProtocolImpl {
+- fn __rpow__() -> Option<PyMethodDef>;
+-}
+-
+-impl<'p, T> PyNumberRPowProtocolImpl for T where T: PyNumberProtocol<'p> {
+- default fn __rpow__() -> Option<PyMethodDef> {
++ fn __rpow__() -> Option<PyMethodDef> {
+ None
+ }
+ }
+
++impl<'p, T> PyNumberRPowProtocolImpl for T where T: PyNumberProtocol<'p> {}
++
+ #[doc(hidden)]
+ pub trait PyNumberRLShiftProtocolImpl {
+- fn __rlshift__() -> Option<PyMethodDef>;
+-}
+-
+-impl<'p, T> PyNumberRLShiftProtocolImpl for T where T: PyNumberProtocol<'p> {
+- default fn __rlshift__() -> Option<PyMethodDef> {
++ fn __rlshift__() -> Option<PyMethodDef> {
+ None
+ }
+ }
+
++impl<'p, T> PyNumberRLShiftProtocolImpl for T where T: PyNumberProtocol<'p> {}
++
+ #[doc(hidden)]
+ pub trait PyNumberRRShiftProtocolImpl {
+- fn __rrshift__() -> Option<PyMethodDef>;
+-}
+-
+-impl<'p, T> PyNumberRRShiftProtocolImpl for T where T: PyNumberProtocol<'p> {
+- default fn __rrshift__() -> Option<PyMethodDef> {
++ fn __rrshift__() -> Option<PyMethodDef> {
+ None
+ }
+ }
+
++impl<'p, T> PyNumberRRShiftProtocolImpl for T where T: PyNumberProtocol<'p> {}
++
+ #[doc(hidden)]
+ pub trait PyNumberRAndProtocolImpl {
+- fn __rand__() -> Option<PyMethodDef>;
+-}
+-
+-impl<'p, T> PyNumberRAndProtocolImpl for T where T: PyNumberProtocol<'p> {
+- default fn __rand__() -> Option<PyMethodDef> {
++ fn __rand__() -> Option<PyMethodDef> {
+ None
+ }
+ }
+
++impl<'p, T> PyNumberRAndProtocolImpl for T where T: PyNumberProtocol<'p> {}
++
+ #[doc(hidden)]
+ pub trait PyNumberRXorProtocolImpl {
+- fn __rxor__() -> Option<PyMethodDef>;
+-}
+-
+-impl<'p, T> PyNumberRXorProtocolImpl for T where T: PyNumberProtocol<'p> {
+- default fn __rxor__() -> Option<PyMethodDef> {
++ fn __rxor__() -> Option<PyMethodDef> {
+ None
+ }
+ }
+
++impl<'p, T> PyNumberRXorProtocolImpl for T where T: PyNumberProtocol<'p> {}
++
+ #[doc(hidden)]
+ pub trait PyNumberROrProtocolImpl {
+- fn __ror__() -> Option<PyMethodDef>;
+-}
+-
+-impl<'p, T> PyNumberROrProtocolImpl for T where T: PyNumberProtocol<'p> {
+- default fn __ror__() -> Option<PyMethodDef> {
++ fn __ror__() -> Option<PyMethodDef> {
+ None
+ }
+ }
+
+-trait PyNumberNegProtocolImpl {
+- fn nb_negative() -> Option<ffi::unaryfunc>;
+-}
++impl<'p, T> PyNumberROrProtocolImpl for T where T: PyNumberProtocol<'p> {}
+
+-impl<'p, T> PyNumberNegProtocolImpl for T where T: PyNumberProtocol<'p> {
+- default fn nb_negative() -> Option<ffi::unaryfunc> {
++trait PyNumberNegProtocolImpl {
++ fn nb_negative() -> Option<ffi::unaryfunc> {
+ None
+ }
+ }
+
++impl<'p, T> PyNumberNegProtocolImpl for T where T: PyNumberProtocol<'p> {}
++
+ impl<T> PyNumberNegProtocolImpl for T
+ where
+ T: for<'p> PyNumberNegProtocol<'p>,
+@@ -1506,15 +1421,13 @@ where
+ }
+
+ trait PyNumberPosProtocolImpl {
+- fn nb_positive() -> Option<ffi::unaryfunc>;
+-}
+-
+-impl<'p, T> PyNumberPosProtocolImpl for T where T: PyNumberProtocol<'p> {
+- default fn nb_positive() -> Option<ffi::unaryfunc> {
++ fn nb_positive() -> Option<ffi::unaryfunc> {
+ None
+ }
+ }
+
++impl<'p, T> PyNumberPosProtocolImpl for T where T: PyNumberProtocol<'p> {}
++
+ impl<T> PyNumberPosProtocolImpl for T
+ where
+ T: for<'p> PyNumberPosProtocol<'p>,
+@@ -1530,15 +1443,13 @@ where
+ }
+
+ trait PyNumberAbsProtocolImpl {
+- fn nb_absolute() -> Option<ffi::unaryfunc>;
+-}
+-
+-impl<'p, T> PyNumberAbsProtocolImpl for T where T: PyNumberProtocol<'p> {
+- default fn nb_absolute() -> Option<ffi::unaryfunc> {
++ fn nb_absolute() -> Option<ffi::unaryfunc> {
+ None
+ }
+ }
+
++impl<'p, T> PyNumberAbsProtocolImpl for T where T: PyNumberProtocol<'p> {}
++
+ impl<T> PyNumberAbsProtocolImpl for T
+ where
+ T: for<'p> PyNumberAbsProtocol<'p>,
+@@ -1554,15 +1465,13 @@ where
+ }
+
+ trait PyNumberInvertProtocolImpl {
+- fn nb_invert() -> Option<ffi::unaryfunc>;
+-}
+-
+-impl<'p, T> PyNumberInvertProtocolImpl for T where T: PyNumberProtocol<'p> {
+- default fn nb_invert() -> Option<ffi::unaryfunc> {
++ fn nb_invert() -> Option<ffi::unaryfunc> {
+ None
+ }
+ }
+
++impl<'p, T> PyNumberInvertProtocolImpl for T where T: PyNumberProtocol<'p> {}
++
+ impl<T> PyNumberInvertProtocolImpl for T
+ where
+ T: for<'p> PyNumberInvertProtocol<'p>,
+@@ -1578,15 +1487,13 @@ where
+ }
+
+ trait PyNumberIntProtocolImpl {
+- fn nb_int() -> Option<ffi::unaryfunc>;
+-}
+-
+-impl<'p, T> PyNumberIntProtocolImpl for T where T: PyNumberProtocol<'p> {
+- default fn nb_int() -> Option<ffi::unaryfunc> {
++ fn nb_int() -> Option<ffi::unaryfunc> {
+ None
+ }
+ }
+
++impl<'p, T> PyNumberIntProtocolImpl for T where T: PyNumberProtocol<'p> {}
++
+ impl<T> PyNumberIntProtocolImpl for T
+ where
+ T: for<'p> PyNumberIntProtocol<'p>,
+@@ -1602,15 +1509,13 @@ where
+ }
+
+ trait PyNumberFloatProtocolImpl {
+- fn nb_float() -> Option<ffi::unaryfunc>;
+-}
+-
+-impl<'p, T> PyNumberFloatProtocolImpl for T where T: PyNumberProtocol<'p> {
+- default fn nb_float() -> Option<ffi::unaryfunc> {
++ fn nb_float() -> Option<ffi::unaryfunc> {
+ None
+ }
+ }
+
++impl<'p, T> PyNumberFloatProtocolImpl for T where T: PyNumberProtocol<'p> {}
++
+ impl<T> PyNumberFloatProtocolImpl for T
+ where
+ T: for<'p> PyNumberFloatProtocol<'p>,
+@@ -1626,15 +1531,13 @@ where
+ }
+
+ trait PyNumberIndexProtocolImpl {
+- fn nb_index() -> Option<ffi::unaryfunc>;
+-}
+-
+-impl<'p, T> PyNumberIndexProtocolImpl for T where T: PyNumberProtocol<'p> {
+- default fn nb_index() -> Option<ffi::unaryfunc> {
++ fn nb_index() -> Option<ffi::unaryfunc> {
+ None
+ }
+ }
+
++impl<'p, T> PyNumberIndexProtocolImpl for T where T: PyNumberProtocol<'p> {}
++
+ impl<T> PyNumberIndexProtocolImpl for T
+ where
+ T: for<'p> PyNumberIndexProtocol<'p>,
+@@ -1650,21 +1553,17 @@ where
+ }
+
+ trait PyNumberComplexProtocolImpl {
+- fn __complex__() -> Option<PyMethodDef>;
+-}
+-
+-impl<'p, T> PyNumberComplexProtocolImpl for T where T: PyNumberProtocol<'p> {
+- default fn __complex__() -> Option<PyMethodDef> {
++ fn __complex__() -> Option<PyMethodDef> {
+ None
+ }
+ }
+
+-trait PyNumberRoundProtocolImpl {
+- fn __round__() -> Option<PyMethodDef>;
+-}
++impl<'p, T> PyNumberComplexProtocolImpl for T where T: PyNumberProtocol<'p> {}
+
+-impl<'p, T> PyNumberRoundProtocolImpl for T where T: PyNumberProtocol<'p> {
+- default fn __round__() -> Option<PyMethodDef> {
++trait PyNumberRoundProtocolImpl {
++ fn __round__() -> Option<PyMethodDef> {
+ None
+ }
+ }
++
++impl<'p, T> PyNumberRoundProtocolImpl for T where T: PyNumberProtocol<'p> {}
+diff --git a/src/class/pyasync.rs b/src/class/pyasync.rs
+index f977fadfa..9afb72c17 100644
+--- a/src/class/pyasync.rs
++++ b/src/class/pyasync.rs
+@@ -91,20 +91,17 @@ pub trait PyAsyncAexitProtocol<'p>: PyAsyncProtocol<'p> {
+
+ #[doc(hidden)]
+ pub trait PyAsyncProtocolImpl {
+- fn tp_as_async() -> Option<ffi::PyAsyncMethods>;
+- fn methods() -> Vec<PyMethodDef>;
+-}
+-
+-impl<T> PyAsyncProtocolImpl for T {
+- default fn tp_as_async() -> Option<ffi::PyAsyncMethods> {
++ fn tp_as_async() -> Option<ffi::PyAsyncMethods> {
+ None
+ }
+
+- default fn methods() -> Vec<PyMethodDef> {
++ fn methods() -> Vec<PyMethodDef> {
+ Vec::new()
+ }
+ }
+
++impl<T> PyAsyncProtocolImpl for T {}
++
+ impl<'p, T> PyAsyncProtocolImpl for T
+ where
+ T: PyAsyncProtocol<'p>,
+@@ -134,15 +131,13 @@ where
+ }
+
+ trait PyAsyncAwaitProtocolImpl {
+- fn am_await() -> Option<ffi::unaryfunc>;
+-}
+-
+-impl<'p, T> PyAsyncAwaitProtocolImpl for T where T: PyAsyncProtocol<'p> {
+- default fn am_await() -> Option<ffi::unaryfunc> {
++ fn am_await() -> Option<ffi::unaryfunc> {
+ None
+ }
+ }
+
++impl<'p, T> PyAsyncAwaitProtocolImpl for T where T: PyAsyncProtocol<'p> {}
++
+ impl<T> PyAsyncAwaitProtocolImpl for T
+ where
+ T: for<'p> PyAsyncAwaitProtocol<'p>,
+@@ -159,15 +154,13 @@ where
+ }
+
+ trait PyAsyncAiterProtocolImpl {
+- fn am_aiter() -> Option<ffi::unaryfunc>;
+-}
+-
+-impl<'p, T> PyAsyncAiterProtocolImpl for T where T: PyAsyncProtocol<'p> {
+- default fn am_aiter() -> Option<ffi::unaryfunc> {
++ fn am_aiter() -> Option<ffi::unaryfunc> {
+ None
+ }
+ }
+
++impl<'p, T> PyAsyncAiterProtocolImpl for T where T: PyAsyncProtocol<'p> {}
++
+ impl<T> PyAsyncAiterProtocolImpl for T
+ where
+ T: for<'p> PyAsyncAiterProtocol<'p>,
+@@ -184,15 +177,13 @@ where
+ }
+
+ trait PyAsyncAnextProtocolImpl {
+- fn am_anext() -> Option<ffi::unaryfunc>;
+-}
+-
+-impl<'p, T> PyAsyncAnextProtocolImpl for T where T: PyAsyncProtocol<'p> {
+- default fn am_anext() -> Option<ffi::unaryfunc> {
++ fn am_anext() -> Option<ffi::unaryfunc> {
+ None
+ }
+ }
+
++impl<'p, T> PyAsyncAnextProtocolImpl for T where T: PyAsyncProtocol<'p> {}
++
+ mod anext {
+ use super::{PyAsyncAnextProtocol, PyAsyncAnextProtocolImpl};
+ use crate::callback::CallbackConverter;
+@@ -242,21 +233,17 @@ mod anext {
+ }
+
+ trait PyAsyncAenterProtocolImpl {
+- fn __aenter__() -> Option<PyMethodDef>;
+-}
+-
+-impl<'p, T> PyAsyncAenterProtocolImpl for T where T: PyAsyncProtocol<'p> {
+- default fn __aenter__() -> Option<PyMethodDef> {
++ fn __aenter__() -> Option<PyMethodDef> {
+ None
+ }
+ }
+
+-trait PyAsyncAexitProtocolImpl {
+- fn __aexit__() -> Option<PyMethodDef>;
+-}
++impl<'p, T> PyAsyncAenterProtocolImpl for T where T: PyAsyncProtocol<'p> {}
+
+-impl<'p, T> PyAsyncAexitProtocolImpl for T where T: PyAsyncProtocol<'p> {
+- default fn __aexit__() -> Option<PyMethodDef> {
++trait PyAsyncAexitProtocolImpl {
++ fn __aexit__() -> Option<PyMethodDef> {
+ None
+ }
+ }
++
++impl<'p, T> PyAsyncAexitProtocolImpl for T where T: PyAsyncProtocol<'p> {}
+diff --git a/src/class/sequence.rs b/src/class/sequence.rs
+index ce65508fd..23771ba0b 100644
+--- a/src/class/sequence.rs
++++ b/src/class/sequence.rs
+@@ -134,15 +134,13 @@ pub trait PySequenceInplaceRepeatProtocol<'p>: PySequenceProtocol<'p> + IntoPy<P
+
+ #[doc(hidden)]
+ pub trait PySequenceProtocolImpl {
+- fn tp_as_sequence() -> Option<ffi::PySequenceMethods>;
+-}
+-
+-impl<T> PySequenceProtocolImpl for T {
+- default fn tp_as_sequence() -> Option<ffi::PySequenceMethods> {
++ fn tp_as_sequence() -> Option<ffi::PySequenceMethods> {
+ None
+ }
+ }
+
++impl<T> PySequenceProtocolImpl for T {}
++
+ impl<'p, T> PySequenceProtocolImpl for T
+ where
+ T: PySequenceProtocol<'p>,
+@@ -164,15 +162,13 @@ where
+ }
+
+ trait PySequenceLenProtocolImpl {
+- fn sq_length() -> Option<ffi::lenfunc>;
+-}
+-
+-impl<'p, T> PySequenceLenProtocolImpl for T where T: PySequenceProtocol<'p> {
+- default fn sq_length() -> Option<ffi::lenfunc> {
++ fn sq_length() -> Option<ffi::lenfunc> {
+ None
+ }
+ }
+
++impl<'p, T> PySequenceLenProtocolImpl for T where T: PySequenceProtocol<'p> {}
++
+ impl<T> PySequenceLenProtocolImpl for T
+ where
+ T: for<'p> PySequenceLenProtocol<'p>,
+@@ -183,15 +179,13 @@ where
+ }
+
+ trait PySequenceGetItemProtocolImpl {
+- fn sq_item() -> Option<ffi::ssizeargfunc>;
+-}
+-
+-impl<'p, T> PySequenceGetItemProtocolImpl for T where T: PySequenceProtocol<'p> {
+- default fn sq_item() -> Option<ffi::ssizeargfunc> {
++ fn sq_item() -> Option<ffi::ssizeargfunc> {
+ None
+ }
+ }
+
++impl<'p, T> PySequenceGetItemProtocolImpl for T where T: PySequenceProtocol<'p> {}
++
+ impl<T> PySequenceGetItemProtocolImpl for T
+ where
+ T: for<'p> PySequenceGetItemProtocol<'p>,
+@@ -289,15 +283,13 @@ mod sq_ass_item_impl {
+ }
+
+ trait DelItem {
+- fn del_item() -> Option<ffi::ssizeobjargproc>;
+- }
+-
+- impl<'p, T> DelItem for T where T: PySequenceProtocol<'p> {
+- default fn del_item() -> Option<ffi::ssizeobjargproc> {
++ fn del_item() -> Option<ffi::ssizeobjargproc> {
+ None
+ }
+ }
+
++ impl<'p, T> DelItem for T where T: PySequenceProtocol<'p> {}
++
+ impl<T> DelItem for T
+ where
+ T: for<'p> PySequenceDelItemProtocol<'p>,
+@@ -337,15 +329,13 @@ mod sq_ass_item_impl {
+ }
+
+ trait DelSetItem {
+- fn del_set_item() -> Option<ffi::ssizeobjargproc>;
+- }
+-
+- impl<'p, T> DelSetItem for T where T: PySequenceProtocol<'p> {
+- default fn del_set_item() -> Option<ffi::ssizeobjargproc> {
++ fn del_set_item() -> Option<ffi::ssizeobjargproc> {
+ None
+ }
+ }
+
++ impl<'p, T> DelSetItem for T where T: PySequenceProtocol<'p> {}
++
+ impl<T> DelSetItem for T
+ where
+ T: for<'p> PySequenceSetItemProtocol<'p> + for<'p> PySequenceDelItemProtocol<'p>,
+@@ -386,15 +376,13 @@ mod sq_ass_item_impl {
+ }
+
+ trait PySequenceContainsProtocolImpl {
+- fn sq_contains() -> Option<ffi::objobjproc>;
+-}
+-
+-impl<'p, T> PySequenceContainsProtocolImpl for T where T: PySequenceProtocol<'p> {
+- default fn sq_contains() -> Option<ffi::objobjproc> {
++ fn sq_contains() -> Option<ffi::objobjproc> {
+ None
+ }
+ }
+
++impl<'p, T> PySequenceContainsProtocolImpl for T where T: PySequenceProtocol<'p> {}
++
+ impl<T> PySequenceContainsProtocolImpl for T
+ where
+ T: for<'p> PySequenceContainsProtocol<'p>,
+@@ -411,15 +399,13 @@ where
+ }
+
+ trait PySequenceConcatProtocolImpl {
+- fn sq_concat() -> Option<ffi::binaryfunc>;
+-}
+-
+-impl<'p, T> PySequenceConcatProtocolImpl for T where T: PySequenceProtocol<'p> {
+- default fn sq_concat() -> Option<ffi::binaryfunc> {
++ fn sq_concat() -> Option<ffi::binaryfunc> {
+ None
+ }
+ }
+
++impl<'p, T> PySequenceConcatProtocolImpl for T where T: PySequenceProtocol<'p> {}
++
+ impl<T> PySequenceConcatProtocolImpl for T
+ where
+ T: for<'p> PySequenceConcatProtocol<'p>,
+@@ -435,15 +421,13 @@ where
+ }
+
+ trait PySequenceRepeatProtocolImpl {
+- fn sq_repeat() -> Option<ffi::ssizeargfunc>;
+-}
+-
+-impl<'p, T> PySequenceRepeatProtocolImpl for T where T: PySequenceProtocol<'p> {
+- default fn sq_repeat() -> Option<ffi::ssizeargfunc> {
++ fn sq_repeat() -> Option<ffi::ssizeargfunc> {
+ None
+ }
+ }
+
++impl<'p, T> PySequenceRepeatProtocolImpl for T where T: PySequenceProtocol<'p> {}
++
+ impl<T> PySequenceRepeatProtocolImpl for T
+ where
+ T: for<'p> PySequenceRepeatProtocol<'p>,
+@@ -459,15 +443,13 @@ where
+ }
+
+ trait PySequenceInplaceConcatProtocolImpl {
+- fn sq_inplace_concat() -> Option<ffi::binaryfunc>;
+-}
+-
+-impl<'p, T> PySequenceInplaceConcatProtocolImpl for T where T: PySequenceProtocol<'p> {
+- default fn sq_inplace_concat() -> Option<ffi::binaryfunc> {
++ fn sq_inplace_concat() -> Option<ffi::binaryfunc> {
+ None
+ }
+ }
+
++impl<'p, T> PySequenceInplaceConcatProtocolImpl for T where T: PySequenceProtocol<'p> {}
++
+ impl<T> PySequenceInplaceConcatProtocolImpl for T
+ where
+ T: for<'p> PySequenceInplaceConcatProtocol<'p>,
+@@ -483,15 +465,13 @@ where
+ }
+
+ trait PySequenceInplaceRepeatProtocolImpl {
+- fn sq_inplace_repeat() -> Option<ffi::ssizeargfunc>;
+-}
+-
+-impl<'p, T> PySequenceInplaceRepeatProtocolImpl for T where T: PySequenceProtocol<'p> {
+- default fn sq_inplace_repeat() -> Option<ffi::ssizeargfunc> {
++ fn sq_inplace_repeat() -> Option<ffi::ssizeargfunc> {
+ None
+ }
+ }
+
++impl<'p, T> PySequenceInplaceRepeatProtocolImpl for T where T: PySequenceProtocol<'p> {}
++
+ impl<T> PySequenceInplaceRepeatProtocolImpl for T
+ where
+ T: for<'p> PySequenceInplaceRepeatProtocol<'p>,
+diff --git a/src/conversion.rs b/src/conversion.rs
+index 15ccdabde..a3bca1175 100644
+--- a/src/conversion.rs
++++ b/src/conversion.rs
+@@ -96,12 +96,6 @@ pub trait ToBorrowedObject: ToPyObject {
+ /// May be more efficient than `to_object` because it does not need
+ /// to touch any reference counts when the input object already is a Python object.
+ fn with_borrowed_ptr<F, R>(&self, py: Python, f: F) -> R
+- where
+- F: FnOnce(*mut ffi::PyObject) -> R;
+-}
+-
+-impl<T> ToBorrowedObject for T where T: ToPyObject {
+- default fn with_borrowed_ptr<F, R>(&self, py: Python, f: F) -> R
+ where
+ F: FnOnce(*mut ffi::PyObject) -> R,
+ {
+@@ -114,6 +108,8 @@ impl<T> ToBorrowedObject for T where T: ToPyObject {
+ }
+ }
+
++impl<T> ToBorrowedObject for T where T: ToPyObject {}
++
+ impl<T> ToBorrowedObject for T
+ where
+ T: ToPyObject + AsPyPointer,
+diff --git a/src/instance.rs b/src/instance.rs
+index 779d18617..68bd45ec3 100644
+--- a/src/instance.rs
++++ b/src/instance.rs
+@@ -359,18 +359,13 @@ impl<T> Py<T> {
+
+ /// Specialization workaround
+ trait AsPyRefDispatch<T: PyTypeInfo>: AsPyPointer {
+- fn as_ref_dispatch(&self, _py: Python) -> &T;
+- fn as_mut_dispatch(&mut self, _py: Python) -> &mut T;
+-}
+-
+-impl<T: PyTypeInfo> AsPyRefDispatch<T> for Py<T> {
+- default fn as_ref_dispatch(&self, _py: Python) -> &T {
++ fn as_ref_dispatch(&self, _py: Python) -> &T {
+ unsafe {
+ let ptr = (self.as_ptr() as *mut u8).offset(T::OFFSET) as *mut T;
+ ptr.as_ref().expect("Py has a null pointer")
+ }
+ }
+- default fn as_mut_dispatch(&mut self, _py: Python) -> &mut T {
++ fn as_mut_dispatch(&mut self, _py: Python) -> &mut T {
+ unsafe {
+ let ptr = (self.as_ptr() as *mut u8).offset(T::OFFSET) as *mut T;
+ ptr.as_mut().expect("Py has a null pointer")
+@@ -378,6 +373,8 @@ impl<T: PyTypeInfo> AsPyRefDispatch<T> for Py<T> {
+ }
+ }
+
++impl<T: PyTypeInfo> AsPyRefDispatch<T> for Py<T> {}
++
+ impl<T: PyTypeInfo + PyNativeType> AsPyRefDispatch<T> for Py<T> {
+ fn as_ref_dispatch(&self, _py: Python) -> &T {
+ unsafe { &*(self as *const instance::Py<T> as *const T) }
+@@ -556,21 +553,9 @@ impl<'p, T: ToPyObject> AsPyPointer for ManagedPyRef<'p, T> {
+ /// Helper trait to choose the right implementation for [ManagedPyRef]
+ pub trait ManagedPyRefDispatch: ToPyObject {
+ /// Optionally converts into a python object and stores the pointer to the python heap.
+- fn to_managed_py_ref<'p>(&self, py: Python<'p>) -> ManagedPyRef<'p, Self>;
+-
+- /// Dispatch over a xdecref and a noop drop impl
+- fn drop_impl(borrowed: &mut ManagedPyRef<Self>);
+-}
+-
+-/// Case 1: It's a rust object which still needs to be converted to a python object.
+-/// This means we're storing the owned pointer that into_ptr() has given us
+-/// and therefore need to xdecref when we're done.
+-///
+-/// Note that the actual implementations are part of the trait declaration to avoid
+-/// a specialization error
+-impl<T: ToPyObject + ?Sized> ManagedPyRefDispatch for T {
++ ///
+ /// Contains the case 1 impl (with to_object) to avoid a specialization error
+- default fn to_managed_py_ref<'p>(&self, py: Python<'p>) -> ManagedPyRef<'p, Self> {
++ fn to_managed_py_ref<'p>(&self, py: Python<'p>) -> ManagedPyRef<'p, Self> {
+ ManagedPyRef {
+ data: self.to_object(py).into_ptr(),
+ data_type: PhantomData,
+@@ -578,12 +563,22 @@ impl<T: ToPyObject + ?Sized> ManagedPyRefDispatch for T {
+ }
+ }
+
++ /// Dispatch over a xdecref and a noop drop impl
++ ///
+ /// Contains the case 1 impl (decref) to avoid a specialization error
+- default fn drop_impl(borrowed: &mut ManagedPyRef<Self>) {
++ fn drop_impl(borrowed: &mut ManagedPyRef<Self>) {
+ unsafe { ffi::Py_DECREF(borrowed.data) };
+ }
+ }
+
++/// Case 1: It's a rust object which still needs to be converted to a python object.
++/// This means we're storing the owned pointer that into_ptr() has given us
++/// and therefore need to xdecref when we're done.
++///
++/// Note that the actual implementations are part of the trait declaration to avoid
++/// a specialization error
++impl<T: ToPyObject + ?Sized> ManagedPyRefDispatch for T {}
++
+ /// Case 2: It's an object on the python heap, we're just storing a borrowed pointer.
+ /// The object we're getting is an owned pointer, it might have it's own drop impl.
+ impl<T: ToPyObject + AsPyPointer + ?Sized> ManagedPyRefDispatch for T {
diff --git a/srcpkgs/anki/files/pyo3-patches/0012-specialization-2f4dfec729e00355bbd067e5770a9e8e889280cf.patch b/srcpkgs/anki/files/pyo3-patches/0012-specialization-2f4dfec729e00355bbd067e5770a9e8e889280cf.patch
new file mode 100644
index 00000000000..c4315a09425
--- /dev/null
+++ b/srcpkgs/anki/files/pyo3-patches/0012-specialization-2f4dfec729e00355bbd067e5770a9e8e889280cf.patch
@@ -0,0 +1,1659 @@
+From 2f4dfec729e00355bbd067e5770a9e8e889280cf Mon Sep 17 00:00:00 2001
+From: Martin Donlon <github-martin@donlons.com>
+Date: Mon, 28 Oct 2019 14:44:26 -0700
+Subject: [PATCH] Removed specialization for all traits
+
+Crate compiles but tests all fail due to missing trait implementations
+---
+ build.rs | 5 --
+ src/class/basic.rs | 55 ++++++------
+ src/class/buffer.rs | 8 +-
+ src/class/context.rs | 2 -
+ src/class/descr.rs | 11 +--
+ src/class/gc.rs | 12 +--
+ src/class/iter.rs | 12 +--
+ src/class/mapping.rs | 24 ++---
+ src/class/number.rs | 199 +++++++++++++++++++-----------------------
+ src/class/pyasync.rs | 19 ++--
+ src/class/sequence.rs | 63 +++++--------
+ src/conversion.rs | 9 +-
+ src/instance.rs | 13 ++-
+ src/lib.rs | 2 -
+ src/object.rs | 2 +-
+ src/type_object.rs | 50 +++++++++--
+ src/types/sequence.rs | 5 +-
+ 17 files changed, 229 insertions(+), 262 deletions(-)
+
+diff --git a/build.rs b/build.rs
+index 7f1060acc..d6b38c489 100644
+--- a/build.rs
++++ b/build.rs
+@@ -537,11 +537,6 @@ fn configure(interpreter_config: &InterpreterConfig) -> Result<(String), String>
+ }
+
+ fn check_rustc_version() {
+- let channel = Channel::read().expect("Failed to determine rustc channel");
+- if !channel.supports_features() {
+- panic!("Error: pyo3 requires a nightly or dev version of Rust.");
+- }
+-
+ let actual_version = Version::read().expect("Failed to determine the rustc version");
+ if !actual_version.at_least(MIN_VERSION) {
+ panic!(
+diff --git a/src/class/basic.rs b/src/class/basic.rs
+index c3153dfa3..f87a0d029 100644
+--- a/src/class/basic.rs
++++ b/src/class/basic.rs
+@@ -161,11 +161,21 @@ pub trait PyObjectProtocolImpl {
+ }
+ }
+
+-impl<T> PyObjectProtocolImpl for T {}
++//impl<T> PyObjectProtocolImpl for T {}
+
+ impl<'p, T> PyObjectProtocolImpl for T
+ where
+- T: PyObjectProtocol<'p>,
++ T: PyObjectProtocol<'p>
++ + PyObjectSetAttrProtocol<'p>
++ + GetAttrProtocolImpl
++ + StrProtocolImpl
++ + ReprProtocolImpl
++ + HashProtocolImpl
++ + RichcmpProtocolImpl
++ + BoolProtocolImpl
++ + tp_setattro_impl::DelAttr
++ + tp_setattro_impl::SetAttr
++ + tp_setattro_impl::SetDelAttr,
+ {
+ fn methods() -> Vec<PyMethodDef> {
+ let mut methods = Vec::new();
+@@ -194,14 +204,12 @@ where
+ }
+ }
+
+-trait GetAttrProtocolImpl {
++pub trait GetAttrProtocolImpl {
+ fn tp_getattro() -> Option<ffi::binaryfunc> {
+ None
+ }
+ }
+
+-impl<'p, T> GetAttrProtocolImpl for T where T: PyObjectProtocol<'p> {}
+-
+ impl<T> GetAttrProtocolImpl for T
+ where
+ T: for<'p> PyObjectGetAttrProtocol<'p>,
+@@ -255,7 +263,10 @@ mod tp_setattro_impl {
+ /// The signature is the same as for PyObject_SetAttr(), but setting v to NULL to delete an
+ /// attribute must be supported. It is usually convenient to set this field to
+ /// PyObject_GenericSetAttr(), which implements the normal way of setting object attributes.
+- pub(super) fn tp_setattro<'p, T: PyObjectProtocol<'p>>() -> Option<ffi::setattrofunc> {
++ pub(super) fn tp_setattro<'p, T>() -> Option<ffi::setattrofunc>
++ where
++ T: PyObjectProtocol<'p> + SetDelAttr + SetAttr + DelAttr,
++ {
+ if let Some(set_del) = T::set_del_attr() {
+ Some(set_del)
+ } else if let Some(set) = T::set_attr() {
+@@ -267,14 +278,12 @@ mod tp_setattro_impl {
+ }
+ }
+
+- trait SetAttr {
++ pub trait SetAttr {
+ fn set_attr() -> Option<ffi::setattrofunc> {
+ None
+ }
+ }
+
+- impl<'p, T: PyObjectProtocol<'p>> SetAttr for T {}
+-
+ impl<T> SetAttr for T
+ where
+ T: for<'p> PyObjectSetAttrProtocol<'p>,
+@@ -284,14 +293,12 @@ mod tp_setattro_impl {
+ }
+ }
+
+- trait DelAttr {
++ pub trait DelAttr {
+ fn del_attr() -> Option<ffi::setattrofunc> {
+ None
+ }
+ }
+
+- impl<'p, T> DelAttr for T where T: PyObjectProtocol<'p> {}
+-
+ impl<T> DelAttr for T
+ where
+ T: for<'p> PyObjectDelAttrProtocol<'p>,
+@@ -301,14 +308,12 @@ mod tp_setattro_impl {
+ }
+ }
+
+- trait SetDelAttr {
++ pub trait SetDelAttr {
+ fn set_del_attr() -> Option<ffi::setattrofunc> {
+ None
+ }
+ }
+
+- impl<'p, T> SetDelAttr for T where T: PyObjectProtocol<'p> {}
+-
+ impl<T> SetDelAttr for T
+ where
+ T: for<'p> PyObjectSetAttrProtocol<'p> + for<'p> PyObjectDelAttrProtocol<'p>,
+@@ -325,12 +330,12 @@ mod tp_setattro_impl {
+ }
+ }
+
+-trait StrProtocolImpl {
++pub trait StrProtocolImpl {
+ fn tp_str() -> Option<ffi::unaryfunc> {
+ None
+ }
+ }
+-impl<'p, T> StrProtocolImpl for T where T: PyObjectProtocol<'p> {}
++
+ impl<T> StrProtocolImpl for T
+ where
+ T: for<'p> PyObjectStrProtocol<'p>,
+@@ -345,12 +350,12 @@ where
+ }
+ }
+
+-trait ReprProtocolImpl {
++pub trait ReprProtocolImpl {
+ fn tp_repr() -> Option<ffi::unaryfunc> {
+ None
+ }
+ }
+-impl<'p, T> ReprProtocolImpl for T where T: PyObjectProtocol<'p> {}
++
+ impl<T> ReprProtocolImpl for T
+ where
+ T: for<'p> PyObjectReprProtocol<'p>,
+@@ -389,12 +394,12 @@ pub trait UnicodeProtocolImpl {
+ }
+ impl<'p, T> UnicodeProtocolImpl for T where T: PyObjectProtocol<'p> {}
+
+-trait HashProtocolImpl {
++pub trait HashProtocolImpl {
+ fn tp_hash() -> Option<ffi::hashfunc> {
+ None
+ }
+ }
+-impl<'p, T> HashProtocolImpl for T where T: PyObjectProtocol<'p> {}
++
+ impl<T> HashProtocolImpl for T
+ where
+ T: for<'p> PyObjectHashProtocol<'p>,
+@@ -410,12 +415,12 @@ where
+ }
+ }
+
+-trait BoolProtocolImpl {
++pub trait BoolProtocolImpl {
+ fn nb_bool() -> Option<ffi::inquiry> {
+ None
+ }
+ }
+-impl<'p, T> BoolProtocolImpl for T where T: PyObjectProtocol<'p> {}
++
+ impl<T> BoolProtocolImpl for T
+ where
+ T: for<'p> PyObjectBoolProtocol<'p>,
+@@ -431,12 +436,12 @@ where
+ }
+ }
+
+-trait RichcmpProtocolImpl {
++pub trait RichcmpProtocolImpl {
+ fn tp_richcompare() -> Option<ffi::richcmpfunc> {
+ None
+ }
+ }
+-impl<'p, T> RichcmpProtocolImpl for T where T: PyObjectProtocol<'p> {}
++
+ impl<T> RichcmpProtocolImpl for T
+ where
+ T: for<'p> PyObjectRichcmpProtocol<'p>,
+diff --git a/src/class/buffer.rs b/src/class/buffer.rs
+index d36524e7c..32d1a25af 100644
+--- a/src/class/buffer.rs
++++ b/src/class/buffer.rs
+@@ -46,11 +46,9 @@ pub trait PyBufferProtocolImpl {
+ }
+ }
+
+-impl<T> PyBufferProtocolImpl for T {}
+-
+ impl<'p, T> PyBufferProtocolImpl for T
+ where
+- T: PyBufferProtocol<'p>,
++ T: PyBufferProtocol<'p> + PyBufferGetBufferProtocolImpl,
+ {
+ #[inline]
+ #[allow(clippy::needless_update)] // For python 2 it's not useless
+@@ -63,14 +61,12 @@ where
+ }
+ }
+
+-trait PyBufferGetBufferProtocolImpl {
++pub trait PyBufferGetBufferProtocolImpl {
+ fn cb_bf_getbuffer() -> Option<ffi::getbufferproc> {
+ None
+ }
+ }
+
+-impl<'p, T> PyBufferGetBufferProtocolImpl for T where T: PyBufferProtocol<'p> {}
+-
+ impl<T> PyBufferGetBufferProtocolImpl for T
+ where
+ T: for<'p> PyBufferGetBufferProtocol<'p>,
+diff --git a/src/class/context.rs b/src/class/context.rs
+index 092527ba0..e5dd56b90 100644
+--- a/src/class/context.rs
++++ b/src/class/context.rs
+@@ -52,8 +52,6 @@ pub trait PyContextProtocolImpl {
+ }
+ }
+
+-impl<T> PyContextProtocolImpl for T {}
+-
+ impl<'p, T> PyContextProtocolImpl for T
+ where
+ T: PyContextProtocol<'p>,
+diff --git a/src/class/descr.rs b/src/class/descr.rs
+index 5f7e68306..ea1dbf012 100644
+--- a/src/class/descr.rs
++++ b/src/class/descr.rs
+@@ -69,12 +69,11 @@ pub trait PyDescrSetNameProtocol<'p>: PyDescrProtocol<'p> {
+ type Result: Into<PyResult<()>>;
+ }
+
+-trait PyDescrGetProtocolImpl {
++pub trait PyDescrGetProtocolImpl {
+ fn tp_descr_get() -> Option<ffi::descrgetfunc> {
+ None
+ }
+ }
+-impl<'p, T> PyDescrGetProtocolImpl for T where T: PyDescrProtocol<'p> {}
+
+ impl<T> PyDescrGetProtocolImpl for T
+ where
+@@ -90,12 +89,12 @@ where
+ }
+ }
+
+-trait PyDescrSetProtocolImpl {
++pub trait PyDescrSetProtocolImpl {
+ fn tp_descr_set() -> Option<ffi::descrsetfunc> {
+ None
+ }
+ }
+-impl<'p, T> PyDescrSetProtocolImpl for T where T: PyDescrProtocol<'p> {}
++
+ impl<T> PyDescrSetProtocolImpl for T
+ where
+ T: for<'p> PyDescrSetProtocol<'p>,
+@@ -133,11 +132,9 @@ pub trait PyDescrProtocolImpl {
+ fn tp_as_descr(_type_object: &mut ffi::PyTypeObject) {}
+ }
+
+-impl<T> PyDescrProtocolImpl for T {}
+-
+ impl<'p, T> PyDescrProtocolImpl for T
+ where
+- T: PyDescrProtocol<'p>,
++ T: PyDescrProtocol<'p> + PyDescrGetProtocolImpl + PyDescrSetProtocolImpl,
+ {
+ fn methods() -> Vec<PyMethodDef> {
+ Vec::new()
+diff --git a/src/class/gc.rs b/src/class/gc.rs
+index eaa4d9015..7e6bc8b45 100644
+--- a/src/class/gc.rs
++++ b/src/class/gc.rs
+@@ -26,11 +26,9 @@ pub trait PyGCProtocolImpl {
+ fn update_type_object(_type_object: &mut ffi::PyTypeObject) {}
+ }
+
+-impl<'p, T> PyGCProtocolImpl for T {}
+-
+ impl<'p, T> PyGCProtocolImpl for T
+ where
+- T: PyGCProtocol<'p>,
++ T: PyGCProtocol<'p> + PyGCTraverseProtocolImpl + PyGCClearProtocolImpl,
+ {
+ fn update_type_object(type_object: &mut ffi::PyTypeObject) {
+ type_object.tp_traverse = Self::tp_traverse();
+@@ -62,14 +60,12 @@ impl<'p> PyVisit<'p> {
+ }
+ }
+
+-trait PyGCTraverseProtocolImpl {
++pub trait PyGCTraverseProtocolImpl {
+ fn tp_traverse() -> Option<ffi::traverseproc> {
+ None
+ }
+ }
+
+-impl<'p, T> PyGCTraverseProtocolImpl for T where T: PyGCProtocol<'p> {}
+-
+ #[doc(hidden)]
+ impl<T> PyGCTraverseProtocolImpl for T
+ where
+@@ -104,14 +100,12 @@ where
+ }
+ }
+
+-trait PyGCClearProtocolImpl {
++pub trait PyGCClearProtocolImpl {
+ fn tp_clear() -> Option<ffi::inquiry> {
+ None
+ }
+ }
+
+-impl<'p, T> PyGCClearProtocolImpl for T where T: PyGCProtocol<'p> {}
+-
+ impl<T> PyGCClearProtocolImpl for T
+ where
+ T: for<'p> PyGCClearProtocol<'p>,
+diff --git a/src/class/iter.rs b/src/class/iter.rs
+index 9001d53ce..b1e896420 100644
+--- a/src/class/iter.rs
++++ b/src/class/iter.rs
+@@ -47,11 +47,9 @@ pub trait PyIterProtocolImpl {
+ fn tp_as_iter(_typeob: &mut ffi::PyTypeObject) {}
+ }
+
+-impl<T> PyIterProtocolImpl for T {}
+-
+ impl<'p, T> PyIterProtocolImpl for T
+ where
+- T: PyIterProtocol<'p>,
++ T: PyIterProtocol<'p> + PyIterIterProtocolImpl + PyIterNextProtocolImpl,
+ {
+ #[inline]
+ fn tp_as_iter(typeob: &mut ffi::PyTypeObject) {
+@@ -60,14 +58,12 @@ where
+ }
+ }
+
+-trait PyIterIterProtocolImpl {
++pub trait PyIterIterProtocolImpl {
+ fn tp_iter() -> Option<ffi::getiterfunc> {
+ None
+ }
+ }
+
+-impl<'p, T> PyIterIterProtocolImpl for T where T: PyIterProtocol<'p> {}
+-
+ impl<T> PyIterIterProtocolImpl for T
+ where
+ T: for<'p> PyIterIterProtocol<'p>,
+@@ -83,14 +79,12 @@ where
+ }
+ }
+
+-trait PyIterNextProtocolImpl {
++pub trait PyIterNextProtocolImpl {
+ fn tp_iternext() -> Option<ffi::iternextfunc> {
+ None
+ }
+ }
+
+-impl<'p, T> PyIterNextProtocolImpl for T where T: PyIterProtocol<'p> {}
+-
+ impl<T> PyIterNextProtocolImpl for T
+ where
+ T: for<'p> PyIterNextProtocol<'p>,
+diff --git a/src/class/mapping.rs b/src/class/mapping.rs
+index 616763502..df2ede958 100644
+--- a/src/class/mapping.rs
++++ b/src/class/mapping.rs
+@@ -114,11 +114,12 @@ pub trait PyMappingProtocolImpl {
+ }
+ }
+
+-impl<T> PyMappingProtocolImpl for T {}
+-
+ impl<'p, T> PyMappingProtocolImpl for T
+ where
+- T: PyMappingProtocol<'p>,
++ T: PyMappingProtocol<'p>
++ + PyMappingSetItemProtocolImpl
++ + PyMappingGetItemProtocolImpl
++ + PyMappingLenProtocolImpl,
+ {
+ #[inline]
+ fn tp_as_mapping() -> Option<ffi::PyMappingMethods> {
+@@ -153,14 +154,12 @@ where
+ }
+ }
+
+-trait PyMappingLenProtocolImpl {
++pub trait PyMappingLenProtocolImpl {
+ fn mp_length() -> Option<ffi::lenfunc> {
+ None
+ }
+ }
+
+-impl<'p, T> PyMappingLenProtocolImpl for T where T: PyMappingProtocol<'p> {}
+-
+ impl<T> PyMappingLenProtocolImpl for T
+ where
+ T: for<'p> PyMappingLenProtocol<'p>,
+@@ -171,14 +170,12 @@ where
+ }
+ }
+
+-trait PyMappingGetItemProtocolImpl {
++pub trait PyMappingGetItemProtocolImpl {
+ fn mp_subscript() -> Option<ffi::binaryfunc> {
+ None
+ }
+ }
+
+-impl<'p, T> PyMappingGetItemProtocolImpl for T where T: PyMappingProtocol<'p> {}
+-
+ impl<T> PyMappingGetItemProtocolImpl for T
+ where
+ T: for<'p> PyMappingGetItemProtocol<'p>,
+@@ -194,14 +191,12 @@ where
+ }
+ }
+
+-trait PyMappingSetItemProtocolImpl {
++pub trait PyMappingSetItemProtocolImpl {
+ fn mp_ass_subscript() -> Option<ffi::objobjargproc> {
+ None
+ }
+ }
+
+-impl<'p, T> PyMappingSetItemProtocolImpl for T where T: PyMappingProtocol<'p> {}
+-
+ impl<T> PyMappingSetItemProtocolImpl for T
+ where
+ T: for<'p> PyMappingSetItemProtocol<'p>,
+@@ -229,8 +224,6 @@ trait DelSetItemDispatch: Sized + for<'p> PyMappingDelItemProtocol<'p> {
+ }
+ }
+
+-impl<T> DelSetItemDispatch for T where T: Sized + for<'p> PyMappingDelItemProtocol<'p> {}
+-
+ impl<T> DelSetItemDispatch for T
+ where
+ T: for<'p> PyMappingSetItemProtocol<'p> + for<'p> PyMappingDelItemProtocol<'p>,
+@@ -246,6 +239,7 @@ where
+ }
+ }
+
++/* MJDFIXME
+ impl<T> DeplItemDipatch for T
+ where
+ T: Sized + for<'p> PyMappingDelItemProtocol<'p>,
+@@ -253,7 +247,7 @@ where
+ fn mp_del_subscript() -> Option<ffi::objobjargproc> {
+ <T as DelSetItemDispatch>::det_set_dispatch()
+ }
+-}
++}*/
+
+ #[doc(hidden)]
+ pub trait PyMappingContainsProtocolImpl {
+diff --git a/src/class/number.rs b/src/class/number.rs
+index 2ee3a57d5..796a1c7ea 100644
+--- a/src/class/number.rs
++++ b/src/class/number.rs
+@@ -638,11 +638,60 @@ pub trait PyNumberProtocolImpl: PyObjectProtocolImpl {
+ }
+ }
+
+-impl<'p, T> PyNumberProtocolImpl for T {}
+-
+ impl<'p, T> PyNumberProtocolImpl for T
+ where
+- T: PyNumberProtocol<'p>,
++ T: PyNumberProtocol<'p>
++ + PyNumberAbsProtocolImpl
++ + PyNumberAddProtocolImpl
++ + PyNumberAndProtocolImpl
++ + PyNumberComplexProtocolImpl
++ + PyNumberDivmodProtocolImpl
++ + PyNumberFloatProtocolImpl
++ + PyNumberFloordivProtocolImpl
++ + PyNumberIAddProtocolImpl
++ + PyNumberIAndProtocolImpl
++ + PyNumberIFloordivProtocolImpl
++ + PyNumberILShiftProtocolImpl
++ + PyNumberIMatmulProtocolImpl
++ + PyNumberIModProtocolImpl
++ + PyNumberIMulProtocolImpl
++ + PyNumberIOrProtocolImpl
++ + PyNumberIPowProtocolImpl
++ + PyNumberIRShiftProtocolImpl
++ + PyNumberISubProtocolImpl
++ + PyNumberITruedivProtocolImpl
++ + PyNumberIXorProtocolImpl
++ + PyNumberIndexProtocolImpl
++ + PyNumberIntProtocolImpl
++ + PyNumberInvertProtocolImpl
++ + PyNumberLShiftProtocolImpl
++ + PyNumberMatmulProtocolImpl
++ + PyNumberModProtocolImpl
++ + PyNumberMulProtocolImpl
++ + PyNumberNegProtocolImpl
++ + PyNumberOrProtocolImpl
++ + PyNumberPosProtocolImpl
++ + PyNumberPowProtocolImpl
++ + PyNumberRAddProtocolImpl
++ + PyNumberRAndProtocolImpl
++ + PyNumberRDivmodProtocolImpl
++ + PyNumberRFloordivProtocolImpl
++ + PyNumberRLShiftProtocolImpl
++ + PyNumberRMatmulProtocolImpl
++ + PyNumberRModProtocolImpl
++ + PyNumberRMulProtocolImpl
++ + PyNumberROrProtocolImpl
++ + PyNumberRPowProtocolImpl
++ + PyNumberRRShiftProtocolImpl
++ + PyNumberRShiftProtocolImpl
++ + PyNumberRSubProtocolImpl
++ + PyNumberRTruedivProtocolImpl
++ + PyNumberRXorProtocolImpl
++ + PyNumberRoundProtocolImpl
++ + PyNumberSubProtocolImpl
++ + PyNumberTruedivProtocolImpl
++ + PyNumberXorProtocolImpl
++ + PyObjectProtocolImpl,
+ {
+ fn tp_as_number() -> Option<ffi::PyNumberMethods> {
+ Some(ffi::PyNumberMethods {
+@@ -742,14 +791,12 @@ where
+ }
+ }
+
+-trait PyNumberAddProtocolImpl {
++pub trait PyNumberAddProtocolImpl {
+ fn nb_add() -> Option<ffi::binaryfunc> {
+ None
+ }
+ }
+
+-impl<'p, T> PyNumberAddProtocolImpl for T where T: PyNumberProtocol<'p> {}
+-
+ impl<T> PyNumberAddProtocolImpl for T
+ where
+ T: for<'p> PyNumberAddProtocol<'p>,
+@@ -764,14 +811,12 @@ where
+ }
+ }
+
+-trait PyNumberSubProtocolImpl {
++pub trait PyNumberSubProtocolImpl {
+ fn nb_subtract() -> Option<ffi::binaryfunc> {
+ None
+ }
+ }
+
+-impl<'p, T> PyNumberSubProtocolImpl for T where T: PyNumberProtocol<'p> {}
+-
+ impl<T> PyNumberSubProtocolImpl for T
+ where
+ T: for<'p> PyNumberSubProtocol<'p>,
+@@ -786,14 +831,12 @@ where
+ }
+ }
+
+-trait PyNumberMulProtocolImpl {
++pub trait PyNumberMulProtocolImpl {
+ fn nb_multiply() -> Option<ffi::binaryfunc> {
+ None
+ }
+ }
+
+-impl<'p, T> PyNumberMulProtocolImpl for T where T: PyNumberProtocol<'p> {}
+-
+ impl<T> PyNumberMulProtocolImpl for T
+ where
+ T: for<'p> PyNumberMulProtocol<'p>,
+@@ -808,14 +851,12 @@ where
+ }
+ }
+
+-trait PyNumberMatmulProtocolImpl {
++pub trait PyNumberMatmulProtocolImpl {
+ fn nb_matrix_multiply() -> Option<ffi::binaryfunc> {
+ None
+ }
+ }
+
+-impl<'p, T> PyNumberMatmulProtocolImpl for T where T: PyNumberProtocol<'p> {}
+-
+ impl<T> PyNumberMatmulProtocolImpl for T
+ where
+ T: for<'p> PyNumberMatmulProtocol<'p>,
+@@ -830,14 +871,12 @@ where
+ }
+ }
+
+-trait PyNumberTruedivProtocolImpl {
++pub trait PyNumberTruedivProtocolImpl {
+ fn nb_true_divide() -> Option<ffi::binaryfunc> {
+ None
+ }
+ }
+
+-impl<'p, T> PyNumberTruedivProtocolImpl for T where T: PyNumberProtocol<'p> {}
+-
+ impl<T> PyNumberTruedivProtocolImpl for T
+ where
+ T: for<'p> PyNumberTruedivProtocol<'p>,
+@@ -852,14 +891,12 @@ where
+ }
+ }
+
+-trait PyNumberFloordivProtocolImpl {
++pub trait PyNumberFloordivProtocolImpl {
+ fn nb_floor_divide() -> Option<ffi::binaryfunc> {
+ None
+ }
+ }
+
+-impl<'p, T> PyNumberFloordivProtocolImpl for T where T: PyNumberProtocol<'p> {}
+-
+ impl<T> PyNumberFloordivProtocolImpl for T
+ where
+ T: for<'p> PyNumberFloordivProtocol<'p>,
+@@ -874,14 +911,12 @@ where
+ }
+ }
+
+-trait PyNumberModProtocolImpl {
++pub trait PyNumberModProtocolImpl {
+ fn nb_remainder() -> Option<ffi::binaryfunc> {
+ None
+ }
+ }
+
+-impl<'p, T> PyNumberModProtocolImpl for T where T: PyNumberProtocol<'p> {}
+-
+ impl<T> PyNumberModProtocolImpl for T
+ where
+ T: for<'p> PyNumberModProtocol<'p>,
+@@ -896,14 +931,12 @@ where
+ }
+ }
+
+-trait PyNumberDivmodProtocolImpl {
++pub trait PyNumberDivmodProtocolImpl {
+ fn nb_divmod() -> Option<ffi::binaryfunc> {
+ None
+ }
+ }
+
+-impl<'p, T> PyNumberDivmodProtocolImpl for T where T: PyNumberProtocol<'p> {}
+-
+ impl<T> PyNumberDivmodProtocolImpl for T
+ where
+ T: for<'p> PyNumberDivmodProtocol<'p>,
+@@ -918,14 +951,12 @@ where
+ }
+ }
+
+-trait PyNumberPowProtocolImpl {
++pub trait PyNumberPowProtocolImpl {
+ fn nb_power() -> Option<ffi::ternaryfunc> {
+ None
+ }
+ }
+
+-impl<'p, T> PyNumberPowProtocolImpl for T where T: PyNumberProtocol<'p> {}
+-
+ impl<T> PyNumberPowProtocolImpl for T
+ where
+ T: for<'p> PyNumberPowProtocol<'p>,
+@@ -940,14 +971,12 @@ where
+ }
+ }
+
+-trait PyNumberLShiftProtocolImpl {
++pub trait PyNumberLShiftProtocolImpl {
+ fn nb_lshift() -> Option<ffi::binaryfunc> {
+ None
+ }
+ }
+
+-impl<'p, T> PyNumberLShiftProtocolImpl for T where T: PyNumberProtocol<'p> {}
+-
+ impl<T> PyNumberLShiftProtocolImpl for T
+ where
+ T: for<'p> PyNumberLShiftProtocol<'p>,
+@@ -962,14 +991,12 @@ where
+ }
+ }
+
+-trait PyNumberRShiftProtocolImpl {
++pub trait PyNumberRShiftProtocolImpl {
+ fn nb_rshift() -> Option<ffi::binaryfunc> {
+ None
+ }
+ }
+
+-impl<'p, T> PyNumberRShiftProtocolImpl for T where T: PyNumberProtocol<'p> {}
+-
+ impl<T> PyNumberRShiftProtocolImpl for T
+ where
+ T: for<'p> PyNumberRShiftProtocol<'p>,
+@@ -984,14 +1011,12 @@ where
+ }
+ }
+
+-trait PyNumberAndProtocolImpl {
++pub trait PyNumberAndProtocolImpl {
+ fn nb_and() -> Option<ffi::binaryfunc> {
+ None
+ }
+ }
+
+-impl<'p, T> PyNumberAndProtocolImpl for T where T: PyNumberProtocol<'p> {}
+-
+ impl<T> PyNumberAndProtocolImpl for T
+ where
+ T: for<'p> PyNumberAndProtocol<'p>,
+@@ -1006,14 +1031,12 @@ where
+ }
+ }
+
+-trait PyNumberXorProtocolImpl {
++pub trait PyNumberXorProtocolImpl {
+ fn nb_xor() -> Option<ffi::binaryfunc> {
+ None
+ }
+ }
+
+-impl<'p, T> PyNumberXorProtocolImpl for T where T: PyNumberProtocol<'p> {}
+-
+ impl<T> PyNumberXorProtocolImpl for T
+ where
+ T: for<'p> PyNumberXorProtocol<'p>,
+@@ -1028,14 +1051,12 @@ where
+ }
+ }
+
+-trait PyNumberOrProtocolImpl {
++pub trait PyNumberOrProtocolImpl {
+ fn nb_or() -> Option<ffi::binaryfunc> {
+ None
+ }
+ }
+
+-impl<'p, T> PyNumberOrProtocolImpl for T where T: PyNumberProtocol<'p> {}
+-
+ impl<T> PyNumberOrProtocolImpl for T
+ where
+ T: for<'p> PyNumberOrProtocol<'p>,
+@@ -1050,14 +1071,12 @@ where
+ }
+ }
+
+-trait PyNumberIAddProtocolImpl {
++pub trait PyNumberIAddProtocolImpl {
+ fn nb_inplace_add() -> Option<ffi::binaryfunc> {
+ None
+ }
+ }
+
+-impl<'p, T> PyNumberIAddProtocolImpl for T where T: PyNumberProtocol<'p> {}
+-
+ impl<T> PyNumberIAddProtocolImpl for T
+ where
+ T: for<'p> PyNumberIAddProtocol<'p>,
+@@ -1067,14 +1086,12 @@ where
+ }
+ }
+
+-trait PyNumberISubProtocolImpl {
++pub trait PyNumberISubProtocolImpl {
+ fn nb_inplace_subtract() -> Option<ffi::binaryfunc> {
+ None
+ }
+ }
+
+-impl<'p, T> PyNumberISubProtocolImpl for T where T: PyNumberProtocol<'p> {}
+-
+ impl<T> PyNumberISubProtocolImpl for T
+ where
+ T: for<'p> PyNumberISubProtocol<'p>,
+@@ -1084,14 +1101,12 @@ where
+ }
+ }
+
+-trait PyNumberIMulProtocolImpl {
++pub trait PyNumberIMulProtocolImpl {
+ fn nb_inplace_multiply() -> Option<ffi::binaryfunc> {
+ None
+ }
+ }
+
+-impl<'p, T> PyNumberIMulProtocolImpl for T where T: PyNumberProtocol<'p> {}
+-
+ impl<T> PyNumberIMulProtocolImpl for T
+ where
+ T: for<'p> PyNumberIMulProtocol<'p>,
+@@ -1101,14 +1116,12 @@ where
+ }
+ }
+
+-trait PyNumberIMatmulProtocolImpl {
++pub trait PyNumberIMatmulProtocolImpl {
+ fn nb_inplace_matrix_multiply() -> Option<ffi::binaryfunc> {
+ None
+ }
+ }
+
+-impl<'p, T> PyNumberIMatmulProtocolImpl for T where T: PyNumberProtocol<'p> {}
+-
+ impl<T> PyNumberIMatmulProtocolImpl for T
+ where
+ T: for<'p> PyNumberIMatmulProtocol<'p>,
+@@ -1118,14 +1131,12 @@ where
+ }
+ }
+
+-trait PyNumberITruedivProtocolImpl {
++pub trait PyNumberITruedivProtocolImpl {
+ fn nb_inplace_true_divide() -> Option<ffi::binaryfunc> {
+ None
+ }
+ }
+
+-impl<'p, T> PyNumberITruedivProtocolImpl for T where T: PyNumberProtocol<'p> {}
+-
+ impl<T> PyNumberITruedivProtocolImpl for T
+ where
+ T: for<'p> PyNumberITruedivProtocol<'p>,
+@@ -1135,14 +1146,12 @@ where
+ }
+ }
+
+-trait PyNumberIFloordivProtocolImpl {
++pub trait PyNumberIFloordivProtocolImpl {
+ fn nb_inplace_floor_divide() -> Option<ffi::binaryfunc> {
+ None
+ }
+ }
+
+-impl<'p, T> PyNumberIFloordivProtocolImpl for T where T: PyNumberProtocol<'p> {}
+-
+ impl<T> PyNumberIFloordivProtocolImpl for T
+ where
+ T: for<'p> PyNumberIFloordivProtocol<'p>,
+@@ -1152,14 +1161,12 @@ where
+ }
+ }
+
+-trait PyNumberIModProtocolImpl {
++pub trait PyNumberIModProtocolImpl {
+ fn nb_inplace_remainder() -> Option<ffi::binaryfunc> {
+ None
+ }
+ }
+
+-impl<'p, T> PyNumberIModProtocolImpl for T where T: PyNumberProtocol<'p> {}
+-
+ impl<T> PyNumberIModProtocolImpl for T
+ where
+ T: for<'p> PyNumberIModProtocol<'p>,
+@@ -1169,14 +1176,12 @@ where
+ }
+ }
+
+-trait PyNumberIPowProtocolImpl {
++pub trait PyNumberIPowProtocolImpl {
+ fn nb_inplace_power() -> Option<ffi::ternaryfunc> {
+ None
+ }
+ }
+
+-impl<'p, T> PyNumberIPowProtocolImpl for T where T: PyNumberProtocol<'p> {}
+-
+ impl<T> PyNumberIPowProtocolImpl for T
+ where
+ T: for<'p> PyNumberIPowProtocol<'p>,
+@@ -1186,14 +1191,12 @@ where
+ }
+ }
+
+-trait PyNumberILShiftProtocolImpl {
++pub trait PyNumberILShiftProtocolImpl {
+ fn nb_inplace_lshift() -> Option<ffi::binaryfunc> {
+ None
+ }
+ }
+
+-impl<'p, T> PyNumberILShiftProtocolImpl for T where T: PyNumberProtocol<'p> {}
+-
+ impl<T> PyNumberILShiftProtocolImpl for T
+ where
+ T: for<'p> PyNumberILShiftProtocol<'p>,
+@@ -1203,14 +1206,12 @@ where
+ }
+ }
+
+-trait PyNumberIRShiftProtocolImpl {
++pub trait PyNumberIRShiftProtocolImpl {
+ fn nb_inplace_rshift() -> Option<ffi::binaryfunc> {
+ None
+ }
+ }
+
+-impl<'p, T> PyNumberIRShiftProtocolImpl for T where T: PyNumberProtocol<'p> {}
+-
+ impl<T> PyNumberIRShiftProtocolImpl for T
+ where
+ T: for<'p> PyNumberIRShiftProtocol<'p>,
+@@ -1220,14 +1221,12 @@ where
+ }
+ }
+
+-trait PyNumberIAndProtocolImpl {
++pub trait PyNumberIAndProtocolImpl {
+ fn nb_inplace_and() -> Option<ffi::binaryfunc> {
+ None
+ }
+ }
+
+-impl<'p, T> PyNumberIAndProtocolImpl for T where T: PyNumberProtocol<'p> {}
+-
+ impl<T> PyNumberIAndProtocolImpl for T
+ where
+ T: for<'p> PyNumberIAndProtocol<'p>,
+@@ -1237,14 +1236,12 @@ where
+ }
+ }
+
+-trait PyNumberIXorProtocolImpl {
++pub trait PyNumberIXorProtocolImpl {
+ fn nb_inplace_xor() -> Option<ffi::binaryfunc> {
+ None
+ }
+ }
+
+-impl<'p, T> PyNumberIXorProtocolImpl for T where T: PyNumberProtocol<'p> {}
+-
+ impl<T> PyNumberIXorProtocolImpl for T
+ where
+ T: for<'p> PyNumberIXorProtocol<'p>,
+@@ -1254,14 +1251,12 @@ where
+ }
+ }
+
+-trait PyNumberIOrProtocolImpl {
++pub trait PyNumberIOrProtocolImpl {
+ fn nb_inplace_or() -> Option<ffi::binaryfunc> {
+ None
+ }
+ }
+
+-impl<'p, T> PyNumberIOrProtocolImpl for T where T: PyNumberProtocol<'p> {}
+-
+ impl<T> PyNumberIOrProtocolImpl for T
+ where
+ T: for<'p> PyNumberIOrProtocol<'p>,
+@@ -1397,14 +1392,12 @@ pub trait PyNumberROrProtocolImpl {
+
+ impl<'p, T> PyNumberROrProtocolImpl for T where T: PyNumberProtocol<'p> {}
+
+-trait PyNumberNegProtocolImpl {
++pub trait PyNumberNegProtocolImpl {
+ fn nb_negative() -> Option<ffi::unaryfunc> {
+ None
+ }
+ }
+
+-impl<'p, T> PyNumberNegProtocolImpl for T where T: PyNumberProtocol<'p> {}
+-
+ impl<T> PyNumberNegProtocolImpl for T
+ where
+ T: for<'p> PyNumberNegProtocol<'p>,
+@@ -1420,14 +1413,12 @@ where
+ }
+ }
+
+-trait PyNumberPosProtocolImpl {
++pub trait PyNumberPosProtocolImpl {
+ fn nb_positive() -> Option<ffi::unaryfunc> {
+ None
+ }
+ }
+
+-impl<'p, T> PyNumberPosProtocolImpl for T where T: PyNumberProtocol<'p> {}
+-
+ impl<T> PyNumberPosProtocolImpl for T
+ where
+ T: for<'p> PyNumberPosProtocol<'p>,
+@@ -1442,14 +1433,12 @@ where
+ }
+ }
+
+-trait PyNumberAbsProtocolImpl {
++pub trait PyNumberAbsProtocolImpl {
+ fn nb_absolute() -> Option<ffi::unaryfunc> {
+ None
+ }
+ }
+
+-impl<'p, T> PyNumberAbsProtocolImpl for T where T: PyNumberProtocol<'p> {}
+-
+ impl<T> PyNumberAbsProtocolImpl for T
+ where
+ T: for<'p> PyNumberAbsProtocol<'p>,
+@@ -1464,14 +1453,12 @@ where
+ }
+ }
+
+-trait PyNumberInvertProtocolImpl {
++pub trait PyNumberInvertProtocolImpl {
+ fn nb_invert() -> Option<ffi::unaryfunc> {
+ None
+ }
+ }
+
+-impl<'p, T> PyNumberInvertProtocolImpl for T where T: PyNumberProtocol<'p> {}
+-
+ impl<T> PyNumberInvertProtocolImpl for T
+ where
+ T: for<'p> PyNumberInvertProtocol<'p>,
+@@ -1486,14 +1473,12 @@ where
+ }
+ }
+
+-trait PyNumberIntProtocolImpl {
++pub trait PyNumberIntProtocolImpl {
+ fn nb_int() -> Option<ffi::unaryfunc> {
+ None
+ }
+ }
+
+-impl<'p, T> PyNumberIntProtocolImpl for T where T: PyNumberProtocol<'p> {}
+-
+ impl<T> PyNumberIntProtocolImpl for T
+ where
+ T: for<'p> PyNumberIntProtocol<'p>,
+@@ -1508,14 +1493,12 @@ where
+ }
+ }
+
+-trait PyNumberFloatProtocolImpl {
++pub trait PyNumberFloatProtocolImpl {
+ fn nb_float() -> Option<ffi::unaryfunc> {
+ None
+ }
+ }
+
+-impl<'p, T> PyNumberFloatProtocolImpl for T where T: PyNumberProtocol<'p> {}
+-
+ impl<T> PyNumberFloatProtocolImpl for T
+ where
+ T: for<'p> PyNumberFloatProtocol<'p>,
+@@ -1530,14 +1513,12 @@ where
+ }
+ }
+
+-trait PyNumberIndexProtocolImpl {
++pub trait PyNumberIndexProtocolImpl {
+ fn nb_index() -> Option<ffi::unaryfunc> {
+ None
+ }
+ }
+
+-impl<'p, T> PyNumberIndexProtocolImpl for T where T: PyNumberProtocol<'p> {}
+-
+ impl<T> PyNumberIndexProtocolImpl for T
+ where
+ T: for<'p> PyNumberIndexProtocol<'p>,
+@@ -1552,18 +1533,14 @@ where
+ }
+ }
+
+-trait PyNumberComplexProtocolImpl {
++pub trait PyNumberComplexProtocolImpl {
+ fn __complex__() -> Option<PyMethodDef> {
+ None
+ }
+ }
+
+-impl<'p, T> PyNumberComplexProtocolImpl for T where T: PyNumberProtocol<'p> {}
+-
+-trait PyNumberRoundProtocolImpl {
++pub trait PyNumberRoundProtocolImpl {
+ fn __round__() -> Option<PyMethodDef> {
+ None
+ }
+ }
+-
+-impl<'p, T> PyNumberRoundProtocolImpl for T where T: PyNumberProtocol<'p> {}
+diff --git a/src/class/pyasync.rs b/src/class/pyasync.rs
+index 9afb72c17..e04aea33b 100644
+--- a/src/class/pyasync.rs
++++ b/src/class/pyasync.rs
+@@ -100,11 +100,12 @@ pub trait PyAsyncProtocolImpl {
+ }
+ }
+
+-impl<T> PyAsyncProtocolImpl for T {}
+-
+ impl<'p, T> PyAsyncProtocolImpl for T
+ where
+- T: PyAsyncProtocol<'p>,
++ T: PyAsyncProtocol<'p>
++ + PyAsyncAwaitProtocolImpl
++ + PyAsyncAiterProtocolImpl
++ + PyAsyncAnextProtocolImpl,
+ {
+ #[inline]
+ fn tp_as_async() -> Option<ffi::PyAsyncMethods> {
+@@ -130,14 +131,12 @@ where
+ }
+ }
+
+-trait PyAsyncAwaitProtocolImpl {
++pub trait PyAsyncAwaitProtocolImpl {
+ fn am_await() -> Option<ffi::unaryfunc> {
+ None
+ }
+ }
+
+-impl<'p, T> PyAsyncAwaitProtocolImpl for T where T: PyAsyncProtocol<'p> {}
+-
+ impl<T> PyAsyncAwaitProtocolImpl for T
+ where
+ T: for<'p> PyAsyncAwaitProtocol<'p>,
+@@ -153,14 +152,12 @@ where
+ }
+ }
+
+-trait PyAsyncAiterProtocolImpl {
++pub trait PyAsyncAiterProtocolImpl {
+ fn am_aiter() -> Option<ffi::unaryfunc> {
+ None
+ }
+ }
+
+-impl<'p, T> PyAsyncAiterProtocolImpl for T where T: PyAsyncProtocol<'p> {}
+-
+ impl<T> PyAsyncAiterProtocolImpl for T
+ where
+ T: for<'p> PyAsyncAiterProtocol<'p>,
+@@ -176,14 +173,12 @@ where
+ }
+ }
+
+-trait PyAsyncAnextProtocolImpl {
++pub trait PyAsyncAnextProtocolImpl {
+ fn am_anext() -> Option<ffi::unaryfunc> {
+ None
+ }
+ }
+
+-impl<'p, T> PyAsyncAnextProtocolImpl for T where T: PyAsyncProtocol<'p> {}
+-
+ mod anext {
+ use super::{PyAsyncAnextProtocol, PyAsyncAnextProtocolImpl};
+ use crate::callback::CallbackConverter;
+diff --git a/src/class/sequence.rs b/src/class/sequence.rs
+index 23771ba0b..840c11b97 100644
+--- a/src/class/sequence.rs
++++ b/src/class/sequence.rs
+@@ -139,11 +139,19 @@ pub trait PySequenceProtocolImpl {
+ }
+ }
+
+-impl<T> PySequenceProtocolImpl for T {}
+-
+ impl<'p, T> PySequenceProtocolImpl for T
+ where
+- T: PySequenceProtocol<'p>,
++ T: PySequenceProtocol<'p>
++ + PySequenceConcatProtocolImpl
++ + PySequenceContainsProtocolImpl
++ + PySequenceGetItemProtocolImpl
++ + PySequenceInplaceConcatProtocolImpl
++ + PySequenceInplaceRepeatProtocolImpl
++ + PySequenceLenProtocolImpl
++ + PySequenceRepeatProtocolImpl
++ + sq_ass_item_impl::SetItem
++ + sq_ass_item_impl::DelItem
++ + sq_ass_item_impl::DelSetItem,
+ {
+ fn tp_as_sequence() -> Option<ffi::PySequenceMethods> {
+ Some(ffi::PySequenceMethods {
+@@ -161,14 +169,12 @@ where
+ }
+ }
+
+-trait PySequenceLenProtocolImpl {
++pub trait PySequenceLenProtocolImpl {
+ fn sq_length() -> Option<ffi::lenfunc> {
+ None
+ }
+ }
+
+-impl<'p, T> PySequenceLenProtocolImpl for T where T: PySequenceProtocol<'p> {}
+-
+ impl<T> PySequenceLenProtocolImpl for T
+ where
+ T: for<'p> PySequenceLenProtocol<'p>,
+@@ -178,14 +184,12 @@ where
+ }
+ }
+
+-trait PySequenceGetItemProtocolImpl {
++pub trait PySequenceGetItemProtocolImpl {
+ fn sq_item() -> Option<ffi::ssizeargfunc> {
+ None
+ }
+ }
+
+-impl<'p, T> PySequenceGetItemProtocolImpl for T where T: PySequenceProtocol<'p> {}
+-
+ impl<T> PySequenceGetItemProtocolImpl for T
+ where
+ T: for<'p> PySequenceGetItemProtocol<'p>,
+@@ -214,7 +218,7 @@ mod sq_ass_item_impl {
+ /// item assignment and deletion.
+ pub(super) fn sq_ass_item<'p, T>() -> Option<ffi::ssizeobjargproc>
+ where
+- T: PySequenceProtocol<'p>,
++ T: PySequenceProtocol<'p> + SetItem + DelItem + DelSetItem,
+ {
+ if let Some(del_set_item) = T::del_set_item() {
+ Some(del_set_item)
+@@ -227,15 +231,8 @@ mod sq_ass_item_impl {
+ }
+ }
+
+- trait SetItem {
+- fn set_item() -> Option<ffi::ssizeobjargproc>;
+- }
+-
+- impl<'p, T> SetItem for T
+- where
+- T: PySequenceProtocol<'p>,
+- {
+- default fn set_item() -> Option<ffi::ssizeobjargproc> {
++ pub trait SetItem {
++ fn set_item() -> Option<ffi::ssizeobjargproc> {
+ None
+ }
+ }
+@@ -282,14 +279,12 @@ mod sq_ass_item_impl {
+ }
+ }
+
+- trait DelItem {
++ pub trait DelItem {
+ fn del_item() -> Option<ffi::ssizeobjargproc> {
+ None
+ }
+ }
+
+- impl<'p, T> DelItem for T where T: PySequenceProtocol<'p> {}
+-
+ impl<T> DelItem for T
+ where
+ T: for<'p> PySequenceDelItemProtocol<'p>,
+@@ -328,14 +323,12 @@ mod sq_ass_item_impl {
+ }
+ }
+
+- trait DelSetItem {
++ pub trait DelSetItem {
+ fn del_set_item() -> Option<ffi::ssizeobjargproc> {
+ None
+ }
+ }
+
+- impl<'p, T> DelSetItem for T where T: PySequenceProtocol<'p> {}
+-
+ impl<T> DelSetItem for T
+ where
+ T: for<'p> PySequenceSetItemProtocol<'p> + for<'p> PySequenceDelItemProtocol<'p>,
+@@ -375,14 +368,12 @@ mod sq_ass_item_impl {
+ }
+ }
+
+-trait PySequenceContainsProtocolImpl {
++pub trait PySequenceContainsProtocolImpl {
+ fn sq_contains() -> Option<ffi::objobjproc> {
+ None
+ }
+ }
+
+-impl<'p, T> PySequenceContainsProtocolImpl for T where T: PySequenceProtocol<'p> {}
+-
+ impl<T> PySequenceContainsProtocolImpl for T
+ where
+ T: for<'p> PySequenceContainsProtocol<'p>,
+@@ -398,14 +389,12 @@ where
+ }
+ }
+
+-trait PySequenceConcatProtocolImpl {
++pub trait PySequenceConcatProtocolImpl {
+ fn sq_concat() -> Option<ffi::binaryfunc> {
+ None
+ }
+ }
+
+-impl<'p, T> PySequenceConcatProtocolImpl for T where T: PySequenceProtocol<'p> {}
+-
+ impl<T> PySequenceConcatProtocolImpl for T
+ where
+ T: for<'p> PySequenceConcatProtocol<'p>,
+@@ -420,14 +409,12 @@ where
+ }
+ }
+
+-trait PySequenceRepeatProtocolImpl {
++pub trait PySequenceRepeatProtocolImpl {
+ fn sq_repeat() -> Option<ffi::ssizeargfunc> {
+ None
+ }
+ }
+
+-impl<'p, T> PySequenceRepeatProtocolImpl for T where T: PySequenceProtocol<'p> {}
+-
+ impl<T> PySequenceRepeatProtocolImpl for T
+ where
+ T: for<'p> PySequenceRepeatProtocol<'p>,
+@@ -442,14 +429,12 @@ where
+ }
+ }
+
+-trait PySequenceInplaceConcatProtocolImpl {
++pub trait PySequenceInplaceConcatProtocolImpl {
+ fn sq_inplace_concat() -> Option<ffi::binaryfunc> {
+ None
+ }
+ }
+
+-impl<'p, T> PySequenceInplaceConcatProtocolImpl for T where T: PySequenceProtocol<'p> {}
+-
+ impl<T> PySequenceInplaceConcatProtocolImpl for T
+ where
+ T: for<'p> PySequenceInplaceConcatProtocol<'p>,
+@@ -464,14 +449,12 @@ where
+ }
+ }
+
+-trait PySequenceInplaceRepeatProtocolImpl {
++pub trait PySequenceInplaceRepeatProtocolImpl {
+ fn sq_inplace_repeat() -> Option<ffi::ssizeargfunc> {
+ None
+ }
+ }
+
+-impl<'p, T> PySequenceInplaceRepeatProtocolImpl for T where T: PySequenceProtocol<'p> {}
+-
+ impl<T> PySequenceInplaceRepeatProtocolImpl for T
+ where
+ T: for<'p> PySequenceInplaceRepeatProtocol<'p>,
+diff --git a/src/conversion.rs b/src/conversion.rs
+index a3bca1175..76094694d 100644
+--- a/src/conversion.rs
++++ b/src/conversion.rs
+@@ -110,6 +110,7 @@ pub trait ToBorrowedObject: ToPyObject {
+
+ impl<T> ToBorrowedObject for T where T: ToPyObject {}
+
++/*MJDFIXME
+ impl<T> ToBorrowedObject for T
+ where
+ T: ToPyObject + AsPyPointer,
+@@ -120,7 +121,7 @@ where
+ {
+ f(self.as_ptr())
+ }
+-}
++}*/
+
+ /// Similar to [std::convert::From], just that it requires a gil token.
+ pub trait FromPy<T>: Sized {
+@@ -139,7 +140,7 @@ impl<T, U> IntoPy<U> for T
+ where
+ U: FromPy<T>,
+ {
+- default fn into_py(self, py: Python) -> U {
++ fn into_py(self, py: Python) -> U {
+ U::from_py(self, py)
+ }
+ }
+@@ -243,7 +244,7 @@ where
+ T: PyTryFrom<'a>,
+ {
+ #[inline]
+- default fn extract(ob: &'a PyAny) -> PyResult<&'a T> {
++ fn extract(ob: &'a PyAny) -> PyResult<&'a T> {
+ Ok(T::try_from(ob)?)
+ }
+ }
+@@ -254,7 +255,7 @@ where
+ T: PyTryFrom<'a>,
+ {
+ #[inline]
+- default fn extract(ob: &'a PyAny) -> PyResult<&'a mut T> {
++ fn extract(ob: &'a PyAny) -> PyResult<&'a mut T> {
+ Ok(T::try_from_mut(ob)?)
+ }
+ }
+diff --git a/src/instance.rs b/src/instance.rs
+index 68bd45ec3..ccbd07c57 100644
+--- a/src/instance.rs
++++ b/src/instance.rs
+@@ -358,7 +358,7 @@ impl<T> Py<T> {
+ }
+
+ /// Specialization workaround
+-trait AsPyRefDispatch<T: PyTypeInfo>: AsPyPointer {
++pub trait AsPyRefDispatch<T: PyTypeInfo>: AsPyPointer {
+ fn as_ref_dispatch(&self, _py: Python) -> &T {
+ unsafe {
+ let ptr = (self.as_ptr() as *mut u8).offset(T::OFFSET) as *mut T;
+@@ -373,8 +373,6 @@ trait AsPyRefDispatch<T: PyTypeInfo>: AsPyPointer {
+ }
+ }
+
+-impl<T: PyTypeInfo> AsPyRefDispatch<T> for Py<T> {}
+-
+ impl<T: PyTypeInfo + PyNativeType> AsPyRefDispatch<T> for Py<T> {
+ fn as_ref_dispatch(&self, _py: Python) -> &T {
+ unsafe { &*(self as *const instance::Py<T> as *const T) }
+@@ -387,6 +385,7 @@ impl<T: PyTypeInfo + PyNativeType> AsPyRefDispatch<T> for Py<T> {
+ impl<T> AsPyRef<T> for Py<T>
+ where
+ T: PyTypeInfo,
++ Py<T>: AsPyRefDispatch<T>,
+ {
+ #[inline]
+ fn as_ref(&self, py: Python) -> PyRef<T> {
+@@ -538,7 +537,7 @@ pub struct ManagedPyRef<'p, T: ToPyObject + ?Sized> {
+
+ /// This should eventually be replaced with a generic `IntoPy` trait impl by figuring
+ /// out the correct lifetime annotation to make the compiler happy
+-impl<'p, T: ToPyObject> ManagedPyRef<'p, T> {
++impl<'p, T: ToPyObject + ManagedPyRefDispatch> ManagedPyRef<'p, T> {
+ pub fn from_to_pyobject(py: Python<'p>, to_pyobject: &T) -> Self {
+ to_pyobject.to_managed_py_ref(py)
+ }
+@@ -577,7 +576,6 @@ pub trait ManagedPyRefDispatch: ToPyObject {
+ ///
+ /// Note that the actual implementations are part of the trait declaration to avoid
+ /// a specialization error
+-impl<T: ToPyObject + ?Sized> ManagedPyRefDispatch for T {}
+
+ /// Case 2: It's an object on the python heap, we're just storing a borrowed pointer.
+ /// The object we're getting is an owned pointer, it might have it's own drop impl.
+@@ -595,13 +593,14 @@ impl<T: ToPyObject + AsPyPointer + ?Sized> ManagedPyRefDispatch for T {
+ fn drop_impl(_: &mut ManagedPyRef<T>) {}
+ }
+
+-impl<'p, T: ToPyObject + ?Sized> Drop for ManagedPyRef<'p, T> {
++/* MJDFIXME
++impl<'p, T: ToPyObject + ?Sized + AsPyPointer> Drop for ManagedPyRef<'p, T> {
+ /// Uses the internal [ManagedPyRefDispatch] trait to get the right drop impl without causing
+ /// a specialization error
+ fn drop(&mut self) {
+ ManagedPyRefDispatch::drop_impl(self);
+ }
+-}
++}*/
+
+ #[cfg(test)]
+ mod test {
+diff --git a/src/lib.rs b/src/lib.rs
+index b5cb5402a..65fb611db 100755
+--- a/src/lib.rs
++++ b/src/lib.rs
+@@ -1,5 +1,3 @@
+-#![feature(specialization)]
+-
+ //! Rust bindings to the Python interpreter.
+ //!
+ //! Look at [the guide](https://pyo3.rs/) for a detailed introduction.
+diff --git a/src/object.rs b/src/object.rs
+index 128ef8377..5d46bfc71 100644
+--- a/src/object.rs
++++ b/src/object.rs
+@@ -171,7 +171,7 @@ impl PyObject {
+ /// This is equivalent to the Python expression 'self.attr_name'.
+ pub fn getattr<N>(&self, py: Python, attr_name: N) -> PyResult<PyObject>
+ where
+- N: ToPyObject,
++ N: ToPyObject + ToBorrowedObject,
+ {
+ attr_name.with_borrowed_ptr(py, |attr_name| unsafe {
+ PyObject::from_owned_ptr_or_err(py, ffi::PyObject_GetAttr(self.as_ptr(), attr_name))
+diff --git a/src/type_object.rs b/src/type_object.rs
+index 4cdd2d8db..3038afb40 100644
+--- a/src/type_object.rs
++++ b/src/type_object.rs
+@@ -2,6 +2,7 @@
+
+ //! Python type object information
+
++use crate::class::gc::PyGCProtocolImpl;
+ use crate::class::methods::PyMethodDefType;
+ use crate::err::{PyErr, PyResult};
+ use crate::instance::{Py, PyNativeType};
+@@ -249,7 +250,19 @@ pub unsafe trait PyTypeObject {
+
+ unsafe impl<T> PyTypeObject for T
+ where
+- T: PyTypeInfo + PyMethodsProtocol + PyObjectAlloc,
++ T: PyTypeInfo
++ + PyMethodsProtocol
++ + PyObjectAlloc
++ + class::gc::PyGCProtocolImpl
++ + class::context::PyContextProtocolImpl
++ + class::descr::PyDescrProtocolImpl
++ + class::iter::PyIterProtocolImpl
++ + class::basic::PyObjectProtocolImpl
++ + class::number::PyNumberProtocolImpl
++ + class::mapping::PyMappingProtocolImpl
++ + class::sequence::PySequenceProtocolImpl
++ + class::pyasync::PyAsyncProtocolImpl
++ + class::buffer::PyBufferProtocolImpl,
+ {
+ fn init_type() -> NonNull<ffi::PyTypeObject> {
+ let type_object = unsafe { <Self as PyTypeInfo>::type_object() };
+@@ -297,7 +310,19 @@ impl<T> PyTypeCreate for T where T: PyObjectAlloc + PyTypeObject + Sized {}
+ #[cfg(not(Py_LIMITED_API))]
+ pub fn initialize_type<T>(py: Python, module_name: Option<&str>) -> PyResult<*mut ffi::PyTypeObject>
+ where
+- T: PyObjectAlloc + PyTypeInfo + PyMethodsProtocol,
++ T: PyObjectAlloc
++ + PyTypeInfo
++ + PyMethodsProtocol
++ + class::gc::PyGCProtocolImpl
++ + class::context::PyContextProtocolImpl
++ + class::descr::PyDescrProtocolImpl
++ + class::iter::PyIterProtocolImpl
++ + class::basic::PyObjectProtocolImpl
++ + class::number::PyNumberProtocolImpl
++ + class::mapping::PyMappingProtocolImpl
++ + class::sequence::PySequenceProtocolImpl
++ + class::pyasync::PyAsyncProtocolImpl
++ + class::buffer::PyBufferProtocolImpl,
+ {
+ let type_object: &mut ffi::PyTypeObject = unsafe { T::type_object() };
+ let base_type_object: &mut ffi::PyTypeObject =
+@@ -438,12 +463,25 @@ fn py_class_flags<T: PyTypeInfo>(type_object: &mut ffi::PyTypeObject) {
+ }
+ }
+
+-fn py_class_method_defs<T: PyMethodsProtocol>() -> (
++fn py_class_method_defs<T>() -> (
+ Option<ffi::newfunc>,
+ Option<ffi::initproc>,
+ Option<ffi::PyCFunctionWithKeywords>,
+ Vec<ffi::PyMethodDef>,
+-) {
++)
++where
++ T: PyMethodsProtocol
++ + class::gc::PyGCProtocolImpl
++ + class::context::PyContextProtocolImpl
++ + class::descr::PyDescrProtocolImpl
++ + class::iter::PyIterProtocolImpl
++ + class::basic::PyObjectProtocolImpl
++ + class::number::PyNumberProtocolImpl
++ + class::mapping::PyMappingProtocolImpl
++ + class::sequence::PySequenceProtocolImpl
++ + class::pyasync::PyAsyncProtocolImpl
++ + class::buffer::PyBufferProtocolImpl,
++{
+ let mut defs = Vec::new();
+ let mut call = None;
+ let mut new = None;
+@@ -500,7 +538,9 @@ fn py_class_method_defs<T: PyMethodsProtocol>() -> (
+ (new, init, call, defs)
+ }
+
+-fn py_class_async_methods<T>(defs: &mut Vec<ffi::PyMethodDef>) {
++fn py_class_async_methods<T: class::pyasync::PyAsyncProtocolImpl>(
++ defs: &mut Vec<ffi::PyMethodDef>,
++) {
+ for def in <T as class::pyasync::PyAsyncProtocolImpl>::methods() {
+ defs.push(def.as_method_def());
+ }
+diff --git a/src/types/sequence.rs b/src/types/sequence.rs
+index d81ffbdd9..08d38b072 100644
+--- a/src/types/sequence.rs
++++ b/src/types/sequence.rs
+@@ -244,11 +244,12 @@ impl<'a, T> FromPyObject<'a> for Vec<T>
+ where
+ T: FromPyObject<'a>,
+ {
+- default fn extract(obj: &'a PyAny) -> PyResult<Self> {
++ fn extract(obj: &'a PyAny) -> PyResult<Self> {
+ extract_sequence(obj)
+ }
+ }
+
++/* MJDFIXME
+ impl<'source, T> FromPyObject<'source> for Vec<T>
+ where
+ for<'a> T: FromPyObject<'a> + buffer::Element + Copy,
+@@ -267,7 +268,7 @@ where
+ // fall back to sequence protocol
+ extract_sequence(obj)
+ }
+-}
++}*/
+
+ fn extract_sequence<'s, T>(obj: &'s PyAny) -> PyResult<Vec<T>>
+ where
diff --git a/srcpkgs/anki/files/pyo3-patches/0013-specialization-b0561da60c6c00fc8cd930efa34113a602a830e2.patch b/srcpkgs/anki/files/pyo3-patches/0013-specialization-b0561da60c6c00fc8cd930efa34113a602a830e2.patch
new file mode 100644
index 00000000000..8e8e4e9cff7
--- /dev/null
+++ b/srcpkgs/anki/files/pyo3-patches/0013-specialization-b0561da60c6c00fc8cd930efa34113a602a830e2.patch
@@ -0,0 +1,69 @@
+From b0561da60c6c00fc8cd930efa34113a602a830e2 Mon Sep 17 00:00:00 2001
+From: Donlon <mdonlon@treyarch.com>
+Date: Wed, 30 Oct 2019 07:02:06 -0700
+Subject: [PATCH] Stubbed out a bunch of tests
+
+---
+ src/instance.rs | 3 ++-
+ tests/test_class_basics.rs | 16 ++++++++++++++--
+
+diff --git a/src/instance.rs b/src/instance.rs
+index ccbd07c57..af0cd4382 100644
+--- a/src/instance.rs
++++ b/src/instance.rs
+@@ -602,6 +602,7 @@ impl<'p, T: ToPyObject + ?Sized + AsPyPointer> Drop for ManagedPyRef<'p, T> {
+ }
+ }*/
+
++/* MJDFIXME
+ #[cfg(test)]
+ mod test {
+ use crate::ffi;
+@@ -640,4 +641,4 @@ mod test {
+ ffi::Py_DECREF(ptr);
+ }
+ }
+-}
++}*/
+diff --git a/tests/test_class_basics.rs b/tests/test_class_basics.rs
+index 00e2674e6..53e4df51e 100644
+--- a/tests/test_class_basics.rs
++++ b/tests/test_class_basics.rs
+@@ -1,3 +1,4 @@
++use pyo3::class;
+ use pyo3::prelude::*;
+ use pyo3::py_run;
+ use pyo3::type_object::initialize_type;
+@@ -7,6 +8,17 @@ mod common;
+ #[pyclass]
+ struct EmptyClass {}
+
++impl class::gc::PyGCProtocolImpl for EmptyClass {}
++impl class::buffer::PyBufferProtocolImpl for EmptyClass {}
++impl class::context::PyContextProtocolImpl for EmptyClass {}
++impl class::iter::PyIterProtocolImpl for EmptyClass {}
++impl class::descr::PyDescrProtocolImpl for EmptyClass {}
++impl class::basic::PyObjectProtocolImpl for EmptyClass {}
++impl class::number::PyNumberProtocolImpl for EmptyClass {}
++impl class::mapping::PyMappingProtocolImpl for EmptyClass {}
++impl class::sequence::PySequenceProtocolImpl for EmptyClass {}
++impl class::pyasync::PyAsyncProtocolImpl for EmptyClass {}
++
+ #[test]
+ fn empty_class() {
+ let gil = Python::acquire_gil();
+@@ -17,7 +29,7 @@ fn empty_class() {
+
+ py_assert!(py, typeobj, "typeobj.__name__ == 'EmptyClass'");
+ }
+-
++/*
+ /// Line1
+ ///Line2
+ /// Line3
+@@ -77,4 +89,4 @@ fn empty_class_in_module() {
+ initialize_type::<EmptyClassInModule>(py, Some("test_module.nested")).unwrap();
+ let module: String = ty.getattr("__module__").unwrap().extract().unwrap();
+ assert_eq!(module, "test_module.nested");
+-}
++}*/
diff --git a/srcpkgs/anki/files/pyo3-patches/0014-specialization-c7e52948d9147689701a24de2fcdffafc32ebe62.patch b/srcpkgs/anki/files/pyo3-patches/0014-specialization-c7e52948d9147689701a24de2fcdffafc32ebe62.patch
new file mode 100644
index 00000000000..1d00862ff05
--- /dev/null
+++ b/srcpkgs/anki/files/pyo3-patches/0014-specialization-c7e52948d9147689701a24de2fcdffafc32ebe62.patch
@@ -0,0 +1,93 @@
+From c7e52948d9147689701a24de2fcdffafc32ebe62 Mon Sep 17 00:00:00 2001
+From: Martin Donlon <github-martin@donlons.com>
+Date: Wed, 30 Oct 2019 22:12:49 -0700
+Subject: [PATCH] pyclass protocols attribute parsing
+
+---
+ .vscode/settings.json | 4 ++++
+ pyo3-derive-backend/src/pyclass.rs | 32 ++++++++++++++++++++++++++++++
+ tests/test_class_basics.rs | 2 +-
+ 3 files changed, 37 insertions(+), 1 deletion(-)
+ create mode 100644 .vscode/settings.json
+
+diff --git a/.vscode/settings.json b/.vscode/settings.json
+new file mode 100644
+index 000000000..2b5f84ecc
+--- /dev/null
++++ b/.vscode/settings.json
+@@ -0,0 +1,4 @@
++{
++ "rust.all_targets": false,
++ "editor.formatOnSave": true
++}
+\ No newline at end of file
+diff --git a/pyo3-derive-backend/src/pyclass.rs b/pyo3-derive-backend/src/pyclass.rs
+index 1f902a959..3ac5d4cde 100644
+--- a/pyo3-derive-backend/src/pyclass.rs
++++ b/pyo3-derive-backend/src/pyclass.rs
+@@ -16,6 +16,7 @@ pub struct PyClassArgs {
+ pub flags: Vec<syn::Expr>,
+ pub base: syn::TypePath,
+ pub module: Option<syn::LitStr>,
++ pub protocols: Vec<syn::Ident>,
+ }
+
+ impl Parse for PyClassArgs {
+@@ -40,6 +41,7 @@ impl Default for PyClassArgs {
+ // are no other flags
+ flags: vec![parse_quote! {0}],
+ base: parse_quote! {pyo3::types::PyAny},
++ protocols: Vec::new(),
+ }
+ }
+ }
+@@ -110,6 +112,36 @@ impl PyClassArgs {
+ ));
+ }
+ },
++ "protocols" => match *assign.right {
++ syn::Expr::Array(syn::ExprArray { ref elems, .. }) => {
++ for elem in elems.iter() {
++ match elem {
++ syn::Expr::Path(syn::ExprPath { ref path, .. }) => {
++ if path.segments.len() == 1 {
++ self.protocols.push(path.segments[0].ident.clone());
++ } else {
++ return Err(syn::Error::new_spanned(
++ path.clone(),
++ "Expected an unqualified name for protocol",
++ ));
++ }
++ }
++ _ => {
++ return Err(syn::Error::new_spanned(
++ elem.clone(),
++ "Wrong format for protocol entry",
++ ));
++ }
++ }
++ }
++ }
++ _ => {
++ return Err(syn::Error::new_spanned(
++ *assign.right.clone(),
++ "Wrong format for protocol",
++ ));
++ }
++ },
+ _ => {
+ return Err(syn::Error::new_spanned(
+ *assign.left.clone(),
+diff --git a/tests/test_class_basics.rs b/tests/test_class_basics.rs
+index 53e4df51e..c8e1a42df 100644
+--- a/tests/test_class_basics.rs
++++ b/tests/test_class_basics.rs
+@@ -5,7 +5,7 @@ use pyo3::type_object::initialize_type;
+
+ mod common;
+
+-#[pyclass]
++#[pyclass(protocols=[PySequenceProtocol])]
+ struct EmptyClass {}
+
+ impl class::gc::PyGCProtocolImpl for EmptyClass {}
diff --git a/srcpkgs/anki/files/pyo3-patches/0015-specialization-81f2c30b15f467c9f5ab139564be0099fba5b27f.patch b/srcpkgs/anki/files/pyo3-patches/0015-specialization-81f2c30b15f467c9f5ab139564be0099fba5b27f.patch
new file mode 100644
index 00000000000..b7436efdee9
--- /dev/null
+++ b/srcpkgs/anki/files/pyo3-patches/0015-specialization-81f2c30b15f467c9f5ab139564be0099fba5b27f.patch
@@ -0,0 +1,159 @@
+From 81f2c30b15f467c9f5ab139564be0099fba5b27f Mon Sep 17 00:00:00 2001
+From: Martin Donlon <github-martin@donlons.com>
+Date: Thu, 31 Oct 2019 22:40:33 -0700
+Subject: [PATCH] Add lookup function for protocol defs
+
+---
+ pyo3-derive-backend/src/defs.rs | 40 ++++++++++++++++++++++--------
+ pyo3-derive-backend/src/pyproto.rs | 15 +++--------
+ 2 files changed, 33 insertions(+), 22 deletions(-)
+
+diff --git a/pyo3-derive-backend/src/defs.rs b/pyo3-derive-backend/src/defs.rs
+index 04c1fa3b0..52024c12b 100644
+--- a/pyo3-derive-backend/src/defs.rs
++++ b/pyo3-derive-backend/src/defs.rs
+@@ -7,12 +7,22 @@ pub struct Proto {
+ pub py_methods: &'static [PyMethod],
+ }
+
++impl Proto {
++ pub fn protocol_trait(&self) -> String {
++ format!("Py{}Protocol", self.name)
++ }
++
++ pub fn _impl_trait(&self) -> String {
++ format!("Py{}ProtocolImpl", self.name)
++ }
++}
++
+ pub struct PyMethod {
+ pub name: &'static str,
+ pub proto: &'static str,
+ }
+
+-pub const OBJECT: Proto = Proto {
++const OBJECT: Proto = Proto {
+ name: "Object",
+ methods: &[
+ MethodProto::Binary {
+@@ -88,7 +98,7 @@ pub const OBJECT: Proto = Proto {
+ ],
+ };
+
+-pub const ASYNC: Proto = Proto {
++const ASYNC: Proto = Proto {
+ name: "Async",
+ methods: &[
+ MethodProto::Unary {
+@@ -131,7 +141,7 @@ pub const ASYNC: Proto = Proto {
+ ],
+ };
+
+-pub const BUFFER: Proto = Proto {
++const BUFFER: Proto = Proto {
+ name: "Buffer",
+ methods: &[
+ MethodProto::Unary {
+@@ -148,7 +158,7 @@ pub const BUFFER: Proto = Proto {
+ py_methods: &[],
+ };
+
+-pub const CONTEXT: Proto = Proto {
++const CONTEXT: Proto = Proto {
+ name: "Context",
+ methods: &[
+ MethodProto::Unary {
+@@ -176,7 +186,7 @@ pub const CONTEXT: Proto = Proto {
+ ],
+ };
+
+-pub const GC: Proto = Proto {
++const GC: Proto = Proto {
+ name: "GC",
+ methods: &[
+ MethodProto::Free {
+@@ -191,7 +201,7 @@ pub const GC: Proto = Proto {
+ py_methods: &[],
+ };
+
+-pub const DESCR: Proto = Proto {
++const DESCR: Proto = Proto {
+ name: "Descriptor",
+ methods: &[
+ MethodProto::Ternary {
+@@ -233,7 +243,7 @@ pub const DESCR: Proto = Proto {
+ ],
+ };
+
+-pub const ITER: Proto = Proto {
++const ITER: Proto = Proto {
+ name: "Iter",
+ py_methods: &[],
+ methods: &[
+@@ -250,7 +260,7 @@ pub const ITER: Proto = Proto {
+ ],
+ };
+
+-pub const MAPPING: Proto = Proto {
++const MAPPING: Proto = Proto {
+ name: "Mapping",
+ methods: &[
+ MethodProto::Unary {
+@@ -310,7 +320,7 @@ pub const MAPPING: Proto = Proto {
+ ],
+ };
+
+-pub const SEQ: Proto = Proto {
++const SEQ: Proto = Proto {
+ name: "Sequence",
+ methods: &[
+ MethodProto::Unary {
+@@ -371,7 +381,7 @@ pub const SEQ: Proto = Proto {
+ py_methods: &[],
+ };
+
+-pub const NUM: Proto = Proto {
++const NUM: Proto = Proto {
+ name: "Number",
+ methods: &[
+ MethodProto::BinaryS {
+@@ -750,3 +760,13 @@ pub const NUM: Proto = Proto {
+ },
+ ],
+ };
++
++const PROTOCOLS: &[Proto] = &[
++ OBJECT, ASYNC, MAPPING, ITER, CONTEXT, SEQ, NUM, DESCR, BUFFER, GC,
++];
++
++pub fn find_protocol(protocol_trait: &str) -> Option<&'static Proto> {
++ PROTOCOLS
++ .iter()
++ .find(|p| p.protocol_trait() == protocol_trait)
++}
+diff --git a/pyo3-derive-backend/src/pyproto.rs b/pyo3-derive-backend/src/pyproto.rs
+index c0921bcbb..41f1deaf9 100644
+--- a/pyo3-derive-backend/src/pyproto.rs
++++ b/pyo3-derive-backend/src/pyproto.rs
+@@ -12,18 +12,9 @@ use quote::ToTokens;
+ pub fn build_py_proto(ast: &mut syn::ItemImpl) -> syn::Result<TokenStream> {
+ if let Some((_, ref mut path, _)) = ast.trait_ {
+ let proto = if let Some(ref mut segment) = path.segments.last() {
+- match segment.ident.to_string().as_str() {
+- "PyObjectProtocol" => &defs::OBJECT,
+- "PyAsyncProtocol" => &defs::ASYNC,
+- "PyMappingProtocol" => &defs::MAPPING,
+- "PyIterProtocol" => &defs::ITER,
+- "PyContextProtocol" => &defs::CONTEXT,
+- "PySequenceProtocol" => &defs::SEQ,
+- "PyNumberProtocol" => &defs::NUM,
+- "PyDescrProtocol" => &defs::DESCR,
+- "PyBufferProtocol" => &defs::BUFFER,
+- "PyGCProtocol" => &defs::GC,
+- _ => {
++ match defs::find_protocol(segment.ident.to_string().as_str()) {
++ Some(p) => p,
++ None => {
+ return Err(syn::Error::new_spanned(
+ path,
+ "#[pyproto] can not be used with this block",
diff --git a/srcpkgs/anki/files/pyo3-patches/0016-specialization-eb617c2ad89dad6be5cf454fe0012d9aba9e60b2.patch b/srcpkgs/anki/files/pyo3-patches/0016-specialization-eb617c2ad89dad6be5cf454fe0012d9aba9e60b2.patch
new file mode 100644
index 00000000000..615bd92790b
--- /dev/null
+++ b/srcpkgs/anki/files/pyo3-patches/0016-specialization-eb617c2ad89dad6be5cf454fe0012d9aba9e60b2.patch
@@ -0,0 +1,1387 @@
+From eb617c2ad89dad6be5cf454fe0012d9aba9e60b2 Mon Sep 17 00:00:00 2001
+From: Martin Donlon <github-martin@donlons.com>
+Date: Sun, 3 Nov 2019 18:06:54 -0800
+Subject: [PATCH] Proc macros now add the necessary default implementations
+
+---
+ .vscode/settings.json | 3 +-
+ pyo3-derive-backend/src/defs.rs | 137 ++++++++++++++++--
+ pyo3-derive-backend/src/func.rs | 37 +++++
+ pyo3-derive-backend/src/pyclass.rs | 34 ++++-
+ pyo3-derive-backend/src/pyproto.rs | 91 +++++++-----
+ src/buffer.rs | 5 +-
+ src/class/buffer.rs | 6 +
+ src/lib.rs | 4 +-
+ tests/test_arithmetics.rp | 12 +-
+ ...er_protocol.rp => test_buffer_protocol.rs} | 2 +-
+ tests/{test_bytes.rp => test_bytes.rs} | 0
+ tests/test_class_basics.rs | 17 +--
+ .../{test_class_new.rp => test_class_new.rs} | 0
+ ...compile_error.rp => test_compile_error.rs} | 0
+ tests/test_datetime.rp | 2 -
+ tests/{test_gc.rp => test_gc.rs} | 4 +-
+ ...getter_setter.rp => test_getter_setter.rs} | 0
+ tests/{test_sequence.rp => test_sequence.rs} | 2 +-
+ tests/{test_string.rp => test_string.rs} | 0
+ ...rguments.rp => test_variable_arguments.rs} | 0
+ tests/{test_various.rp => test_various.rs} | 3 +-
+ 21 files changed, 280 insertions(+), 79 deletions(-)
+ rename tests/{test_buffer_protocol.rp => test_buffer_protocol.rs} (98%)
+ rename tests/{test_bytes.rp => test_bytes.rs} (100%)
+ rename tests/{test_class_new.rp => test_class_new.rs} (100%)
+ rename tests/{test_compile_error.rp => test_compile_error.rs} (100%)
+ rename tests/{test_gc.rp => test_gc.rs} (98%)
+ rename tests/{test_getter_setter.rp => test_getter_setter.rs} (100%)
+ rename tests/{test_sequence.rp => test_sequence.rs} (99%)
+ rename tests/{test_string.rp => test_string.rs} (100%)
+ rename tests/{test_variable_arguments.rp => test_variable_arguments.rs} (100%)
+ rename tests/{test_various.rp => test_various.rs} (98%)
+
+diff --git a/.vscode/settings.json b/.vscode/settings.json
+index 2b5f84ecc..38768fd72 100644
+--- a/.vscode/settings.json
++++ b/.vscode/settings.json
+@@ -1,4 +1,5 @@
+ {
+ "rust.all_targets": false,
+- "editor.formatOnSave": true
++ "editor.formatOnSave": true,
++ "rust-analyzer.enableEnhancedTyping": false
+ }
+\ No newline at end of file
+diff --git a/pyo3-derive-backend/src/defs.rs b/pyo3-derive-backend/src/defs.rs
+index 52024c12b..06c1c6754 100644
+--- a/pyo3-derive-backend/src/defs.rs
++++ b/pyo3-derive-backend/src/defs.rs
+@@ -3,20 +3,12 @@ use crate::func::MethodProto;
+
+ pub struct Proto {
+ pub name: &'static str,
++ pub protocol_trait: &'static str,
++ pub impl_trait: &'static str,
+ pub methods: &'static [MethodProto],
+ pub py_methods: &'static [PyMethod],
+ }
+
+-impl Proto {
+- pub fn protocol_trait(&self) -> String {
+- format!("Py{}Protocol", self.name)
+- }
+-
+- pub fn _impl_trait(&self) -> String {
+- format!("Py{}ProtocolImpl", self.name)
+- }
+-}
+-
+ pub struct PyMethod {
+ pub name: &'static str,
+ pub proto: &'static str,
+@@ -24,12 +16,15 @@ pub struct PyMethod {
+
+ const OBJECT: Proto = Proto {
+ name: "Object",
++ protocol_trait: "pyo3::class::basic::PyObjectProtocol",
++ impl_trait: "pyo3::class::basic::PyObjectProtocolImpl",
+ methods: &[
+ MethodProto::Binary {
+ name: "__getattr__",
+ arg: "Name",
+ pyres: true,
+ proto: "pyo3::class::basic::PyObjectGetAttrProtocol",
++ default: "pyo3::class::basic::PyObjectGetAttrProtocol",
+ },
+ MethodProto::Ternary {
+ name: "__setattr__",
+@@ -37,49 +32,58 @@ const OBJECT: Proto = Proto {
+ arg2: "Value",
+ pyres: false,
+ proto: "pyo3::class::basic::PyObjectSetAttrProtocol",
++ default: "pyo3::class::basic::PyObjectSetAttrProtocol",
+ },
+ MethodProto::Binary {
+ name: "__delattr__",
+ arg: "Name",
+ pyres: true,
+ proto: "pyo3::class::basic::PyObjectDelAttrProtocol",
++ default: "pyo3::class::basic::PyObjectDelAttrProtocol",
+ },
+ MethodProto::Unary {
+ name: "__str__",
+ pyres: true,
+ proto: "pyo3::class::basic::PyObjectStrProtocol",
++ default: "pyo3::class::basic::PyObjectStrProtocol",
+ },
+ MethodProto::Unary {
+ name: "__repr__",
+ pyres: true,
+ proto: "pyo3::class::basic::PyObjectReprProtocol",
++ default: "pyo3::class::basic::PyObjectReprProtocol",
+ },
+ MethodProto::Binary {
+ name: "__format__",
+ arg: "Format",
+ pyres: true,
+ proto: "pyo3::class::basic::PyObjectFormatProtocol",
++ default: "pyo3::class::basic::PyObjectFormatProtocol",
+ },
+ MethodProto::Unary {
+ name: "__hash__",
+ pyres: false,
+ proto: "pyo3::class::basic::PyObjectHashProtocol",
++ default: "pyo3::class::basic::PyObjectHashProtocol",
+ },
+ MethodProto::Unary {
+ name: "__bytes__",
+ pyres: true,
+ proto: "pyo3::class::basic::PyObjectBytesProtocol",
++ default: "pyo3::class::basic::PyObjectBytesProtocol",
+ },
+ MethodProto::Unary {
+ name: "__bool__",
+ pyres: false,
+ proto: "pyo3::class::basic::PyObjectBoolProtocol",
++ default: "pyo3::class::basic::PyObjectBoolProtocol",
+ },
+ MethodProto::Binary {
+ name: "__richcmp__",
+ arg: "Other",
+ pyres: true,
+ proto: "pyo3::class::basic::PyObjectRichcmpProtocol",
++ default: "pyo3::class::basic::PyObjectRichcmpProtocol",
+ },
+ ],
+ py_methods: &[
+@@ -100,26 +104,32 @@ const OBJECT: Proto = Proto {
+
+ const ASYNC: Proto = Proto {
+ name: "Async",
++ protocol_trait: "pyo3::class::pyasync::PyAsyncProtocol",
++ impl_trait: "pyo3::class::pyasync::PyAsyncProtocolImpl",
+ methods: &[
+ MethodProto::Unary {
+ name: "__await__",
+ pyres: true,
+ proto: "pyo3::class::pyasync::PyAsyncAwaitProtocol",
++ default: "pyo3::class::pyasync::PyAsyncAwaitProtocol",
+ },
+ MethodProto::Unary {
+ name: "__aiter__",
+ pyres: true,
+ proto: "pyo3::class::pyasync::PyAsyncAiterProtocol",
++ default: "pyo3::class::pyasync::PyAsyncAiterProtocol",
+ },
+ MethodProto::Unary {
+ name: "__anext__",
+ pyres: true,
+ proto: "pyo3::class::pyasync::PyAsyncAnextProtocol",
++ default: "pyo3::class::pyasync::PyAsyncAnextProtocol",
+ },
+ MethodProto::Unary {
+ name: "__aenter__",
+ pyres: true,
+ proto: "pyo3::class::pyasync::PyAsyncAenterProtocol",
++ default: "pyo3::class::pyasync::PyAsyncAenterProtocol",
+ },
+ MethodProto::Quaternary {
+ name: "__aexit__",
+@@ -127,6 +137,7 @@ const ASYNC: Proto = Proto {
+ arg2: "ExcValue",
+ arg3: "Traceback",
+ proto: "pyo3::class::pyasync::PyAsyncAexitProtocol",
++ default: "pyo3::class::pyasync::PyAsyncAexitProtocol",
+ },
+ ],
+ py_methods: &[
+@@ -143,16 +154,20 @@ const ASYNC: Proto = Proto {
+
+ const BUFFER: Proto = Proto {
+ name: "Buffer",
++ protocol_trait: "pyo3::class::buffer::PyBufferProtocol",
++ impl_trait: "pyo3::class::buffer::PyBufferProtocolImpl",
+ methods: &[
+ MethodProto::Unary {
+ name: "bf_getbuffer",
+ pyres: false,
+ proto: "pyo3::class::buffer::PyBufferGetBufferProtocol",
++ default: "pyo3::class::buffer::PyBufferGetBufferProtocolImpl",
+ },
+ MethodProto::Unary {
+ name: "bf_releasebuffer",
+ pyres: false,
+ proto: "pyo3::class::buffer::PyBufferReleaseBufferProtocol",
++ default: "pyo3::class::buffer::PyBufferReleaseBufferProtocolImpl",
+ },
+ ],
+ py_methods: &[],
+@@ -160,11 +175,14 @@ const BUFFER: Proto = Proto {
+
+ const CONTEXT: Proto = Proto {
+ name: "Context",
++ protocol_trait: "pyo3::class::context::PyContextProtocol",
++ impl_trait: "pyo3::class::context::PyContextProtocolImpl",
+ methods: &[
+ MethodProto::Unary {
+ name: "__enter__",
+ pyres: true,
+ proto: "pyo3::class::context::PyContextEnterProtocol",
++ default: "pyo3::class::context::PyContextEnterProtocol",
+ },
+ MethodProto::Quaternary {
+ name: "__exit__",
+@@ -172,6 +190,7 @@ const CONTEXT: Proto = Proto {
+ arg2: "ExcValue",
+ arg3: "Traceback",
+ proto: "pyo3::class::context::PyContextExitProtocol",
++ default: "pyo3::class::context::PyContextExitProtocol",
+ },
+ ],
+ py_methods: &[
+@@ -188,14 +207,19 @@ const CONTEXT: Proto = Proto {
+
+ const GC: Proto = Proto {
+ name: "GC",
++ protocol_trait: "pyo3::class::gc::PyGCProtocol",
++ impl_trait: "pyo3::class::gc::PyGCProtocolImpl",
++
+ methods: &[
+ MethodProto::Free {
+ name: "__traverse__",
+ proto: "pyo3::class::gc::PyGCTraverseProtocol",
++ default: "pyo3::class::gc::PyGCTraverseProtocolImpl",
+ },
+ MethodProto::Free {
+ name: "__clear__",
+ proto: "pyo3::class::gc::PyGCClearProtocol",
++ default: "pyo3::class::gc::PyGCClearProtocolImpl",
+ },
+ ],
+ py_methods: &[],
+@@ -203,6 +227,9 @@ const GC: Proto = Proto {
+
+ const DESCR: Proto = Proto {
+ name: "Descriptor",
++ protocol_trait: "pyo3::class::descr::PyDescrProtocol",
++ impl_trait: "pyo3::class::descr::PyDescrProtocolImpl",
++
+ methods: &[
+ MethodProto::Ternary {
+ name: "__get__",
+@@ -210,6 +237,7 @@ const DESCR: Proto = Proto {
+ arg2: "Owner",
+ pyres: true,
+ proto: "pyo3::class::descr::PyDescrGetProtocol",
++ default: "pyo3::class::descr::PyDescrGetProtocol",
+ },
+ MethodProto::Ternary {
+ name: "__set__",
+@@ -217,18 +245,21 @@ const DESCR: Proto = Proto {
+ arg2: "Value",
+ pyres: true,
+ proto: "pyo3::class::descr::PyDescrSetProtocol",
++ default: "pyo3::class::descr::PyDescrSetProtocol",
+ },
+ MethodProto::Binary {
+ name: "__det__",
+ arg: "Inst",
+ pyres: false,
+ proto: "pyo3::class::descr::PyDescrDelProtocol",
++ default: "pyo3::class::descr::PyDescrDelProtocol",
+ },
+ MethodProto::Binary {
+ name: "__set_name__",
+ arg: "Inst",
+ pyres: false,
+ proto: "pyo3::class::descr::PyDescrSetNameProtocol",
++ default: "pyo3::class::descr::PyDescrSetNameProtocol",
+ },
+ ],
+ py_methods: &[
+@@ -245,34 +276,44 @@ const DESCR: Proto = Proto {
+
+ const ITER: Proto = Proto {
+ name: "Iter",
++ protocol_trait: "pyo3::class::iter::PyIterProtocol",
++ impl_trait: "pyo3::class::iter::PyIterProtocolImpl",
++
+ py_methods: &[],
+ methods: &[
+ MethodProto::Unary {
+ name: "__iter__",
+ pyres: true,
+ proto: "pyo3::class::iter::PyIterIterProtocol",
++ default: "pyo3::class::iter::PyIterIterProtocol",
+ },
+ MethodProto::Unary {
+ name: "__next__",
+ pyres: true,
+ proto: "pyo3::class::iter::PyIterNextProtocol",
++ default: "pyo3::class::iter::PyIterNextProtocol",
+ },
+ ],
+ };
+
+ const MAPPING: Proto = Proto {
+ name: "Mapping",
++ protocol_trait: "pyo3::class::mapping::PyMappingProtocol",
++ impl_trait: "pyo3::class::mapping::PyMappingProtocolImpl",
++
+ methods: &[
+ MethodProto::Unary {
+ name: "__len__",
+ pyres: false,
+ proto: "pyo3::class::mapping::PyMappingLenProtocol",
++ default: "pyo3::class::mapping::PyMappingLenProtocol",
+ },
+ MethodProto::Binary {
+ name: "__getitem__",
+ arg: "Key",
+ pyres: true,
+ proto: "pyo3::class::mapping::PyMappingGetItemProtocol",
++ default: "pyo3::class::mapping::PyMappingGetItemProtocol",
+ },
+ MethodProto::Ternary {
+ name: "__setitem__",
+@@ -280,28 +321,33 @@ const MAPPING: Proto = Proto {
+ arg2: "Value",
+ pyres: false,
+ proto: "pyo3::class::mapping::PyMappingSetItemProtocol",
++ default: "pyo3::class::mapping::PyMappingSetItemProtocol",
+ },
+ MethodProto::Binary {
+ name: "__delitem__",
+ arg: "Key",
+ pyres: false,
+ proto: "pyo3::class::mapping::PyMappingDelItemProtocol",
++ default: "pyo3::class::mapping::PyMappingDelItemProtocol",
+ },
+ MethodProto::Binary {
+ name: "__contains__",
+ arg: "Value",
+ pyres: false,
+ proto: "pyo3::class::mapping::PyMappingContainsProtocol",
++ default: "pyo3::class::mapping::PyMappingContainsProtocol",
+ },
+ MethodProto::Unary {
+ name: "__reversed__",
+ pyres: true,
+ proto: "pyo3::class::mapping::PyMappingReversedProtocol",
++ default: "pyo3::class::mapping::PyMappingReversedProtocol",
+ },
+ MethodProto::Unary {
+ name: "__iter__",
+ pyres: true,
+ proto: "pyo3::class::mapping::PyMappingIterProtocol",
++ default: "pyo3::class::mapping::PyMappingIterProtocol",
+ },
+ ],
+ py_methods: &[
+@@ -322,17 +368,22 @@ const MAPPING: Proto = Proto {
+
+ const SEQ: Proto = Proto {
+ name: "Sequence",
++ protocol_trait: "pyo3::class::sequence::PySequenceProtocol",
++ impl_trait: "pyo3::class::sequence::PySequenceProtocolImpl",
++
+ methods: &[
+ MethodProto::Unary {
+ name: "__len__",
+ pyres: false,
+ proto: "pyo3::class::sequence::PySequenceLenProtocol",
++ default: "pyo3::class::sequence::PySequenceLenProtocolImpl",
+ },
+ MethodProto::Binary {
+ name: "__getitem__",
+ arg: "Index",
+ pyres: true,
+ proto: "pyo3::class::sequence::PySequenceGetItemProtocol",
++ default: "pyo3::class::sequence::PySequenceGetItemProtocolImpl",
+ },
+ MethodProto::Ternary {
+ name: "__setitem__",
+@@ -340,42 +391,49 @@ const SEQ: Proto = Proto {
+ arg2: "Value",
+ pyres: false,
+ proto: "pyo3::class::sequence::PySequenceSetItemProtocol",
++ default: "pyo3::class::sequence::PySequenceSetItemProtocolImpl",
+ },
+ MethodProto::Binary {
+ name: "__delitem__",
+ arg: "Index",
+ pyres: false,
+ proto: "pyo3::class::sequence::PySequenceDelItemProtocol",
++ default: "pyo3::class::sequence::PySequenceDelItemProtocolImpl",
+ },
+ MethodProto::Binary {
+ name: "__contains__",
+ arg: "Item",
+ pyres: false,
+ proto: "pyo3::class::sequence::PySequenceContainsProtocol",
++ default: "pyo3::class::sequence::PySequenceContainsProtocolImpl",
+ },
+ MethodProto::Binary {
+ name: "__concat__",
+ arg: "Other",
+ pyres: true,
+ proto: "pyo3::class::sequence::PySequenceConcatProtocol",
++ default: "pyo3::class::sequence::PySequenceConcatProtocolImpl",
+ },
+ MethodProto::Binary {
+ name: "__repeat__",
+ arg: "Index",
+ pyres: true,
+ proto: "pyo3::class::sequence::PySequenceRepeatProtocol",
++ default: "pyo3::class::sequence::PySequenceRepeatProtocolImpl",
+ },
+ MethodProto::Binary {
+ name: "__inplace_concat__",
+ arg: "Other",
+ pyres: true,
+ proto: "pyo3::class::sequence::PySequenceInplaceConcatProtocol",
++ default: "pyo3::class::sequence::PySequenceInplaceConcatProtocolImpl",
+ },
+ MethodProto::Binary {
+ name: "__inplace_repeat__",
+ arg: "Index",
+ pyres: true,
+ proto: "pyo3::class::sequence::PySequenceInplaceRepeatProtocol",
++ default: "pyo3::class::sequence::PySequenceInplaceRepeatProtocolImpl",
+ },
+ ],
+ py_methods: &[],
+@@ -383,6 +441,9 @@ const SEQ: Proto = Proto {
+
+ const NUM: Proto = Proto {
+ name: "Number",
++ protocol_trait: "pyo3::class::number::PyNumberProtocol",
++ impl_trait: "pyo3::class::number::PyNumberProtocolImpl",
++
+ methods: &[
+ MethodProto::BinaryS {
+ name: "__add__",
+@@ -390,6 +451,7 @@ const NUM: Proto = Proto {
+ arg2: "Right",
+ pyres: true,
+ proto: "pyo3::class::number::PyNumberAddProtocol",
++ default: "pyo3::class::number::PyNumberAddProtocol",
+ },
+ MethodProto::BinaryS {
+ name: "__sub__",
+@@ -397,6 +459,7 @@ const NUM: Proto = Proto {
+ arg2: "Right",
+ pyres: true,
+ proto: "pyo3::class::number::PyNumberSubProtocol",
++ default: "pyo3::class::number::PyNumberSubProtocol",
+ },
+ MethodProto::BinaryS {
+ name: "__mul__",
+@@ -404,6 +467,7 @@ const NUM: Proto = Proto {
+ arg2: "Right",
+ pyres: true,
+ proto: "pyo3::class::number::PyNumberMulProtocol",
++ default: "pyo3::class::number::PyNumberMulProtocol",
+ },
+ MethodProto::BinaryS {
+ name: "__matmul__",
+@@ -411,6 +475,7 @@ const NUM: Proto = Proto {
+ arg2: "Right",
+ pyres: true,
+ proto: "pyo3::class::number::PyNumberMatmulProtocol",
++ default: "pyo3::class::number::PyNumberMatmulProtocol",
+ },
+ MethodProto::BinaryS {
+ name: "__truediv__",
+@@ -418,6 +483,7 @@ const NUM: Proto = Proto {
+ arg2: "Right",
+ pyres: true,
+ proto: "pyo3::class::number::PyNumberTruedivProtocol",
++ default: "pyo3::class::number::PyNumberTruedivProtocol",
+ },
+ MethodProto::BinaryS {
+ name: "__floordiv__",
+@@ -425,6 +491,7 @@ const NUM: Proto = Proto {
+ arg2: "Right",
+ pyres: true,
+ proto: "pyo3::class::number::PyNumberFloordivProtocol",
++ default: "pyo3::class::number::PyNumberFloordivProtocol",
+ },
+ MethodProto::BinaryS {
+ name: "__mod__",
+@@ -432,6 +499,7 @@ const NUM: Proto = Proto {
+ arg2: "Right",
+ pyres: true,
+ proto: "pyo3::class::number::PyNumberModProtocol",
++ default: "pyo3::class::number::PyNumberModProtocol",
+ },
+ MethodProto::BinaryS {
+ name: "__divmod__",
+@@ -439,6 +507,7 @@ const NUM: Proto = Proto {
+ arg2: "Right",
+ pyres: true,
+ proto: "pyo3::class::number::PyNumberDivmodProtocol",
++ default: "pyo3::class::number::PyNumberDivmodProtocol",
+ },
+ MethodProto::TernaryS {
+ name: "__pow__",
+@@ -447,6 +516,7 @@ const NUM: Proto = Proto {
+ arg3: "Modulo",
+ pyres: true,
+ proto: "pyo3::class::number::PyNumberPowProtocol",
++ default: "pyo3::class::number::PyNumberPowProtocol",
+ },
+ MethodProto::BinaryS {
+ name: "__lshift__",
+@@ -454,6 +524,7 @@ const NUM: Proto = Proto {
+ arg2: "Right",
+ pyres: true,
+ proto: "pyo3::class::number::PyNumberLShiftProtocol",
++ default: "pyo3::class::number::PyNumberLShiftProtocol",
+ },
+ MethodProto::BinaryS {
+ name: "__rshift__",
+@@ -461,6 +532,7 @@ const NUM: Proto = Proto {
+ arg2: "Right",
+ pyres: true,
+ proto: "pyo3::class::number::PyNumberRShiftProtocol",
++ default: "pyo3::class::number::PyNumberRShiftProtocol",
+ },
+ MethodProto::BinaryS {
+ name: "__and__",
+@@ -468,6 +540,7 @@ const NUM: Proto = Proto {
+ arg2: "Right",
+ pyres: true,
+ proto: "pyo3::class::number::PyNumberAndProtocol",
++ default: "pyo3::class::number::PyNumberAndProtocol",
+ },
+ MethodProto::BinaryS {
+ name: "__xor__",
+@@ -475,6 +548,7 @@ const NUM: Proto = Proto {
+ arg2: "Right",
+ pyres: true,
+ proto: "pyo3::class::number::PyNumberXorProtocol",
++ default: "pyo3::class::number::PyNumberXorProtocol",
+ },
+ MethodProto::BinaryS {
+ name: "__or__",
+@@ -482,54 +556,63 @@ const NUM: Proto = Proto {
+ arg2: "Right",
+ pyres: true,
+ proto: "pyo3::class::number::PyNumberOrProtocol",
++ default: "pyo3::class::number::PyNumberOrProtocol",
+ },
+ MethodProto::Binary {
+ name: "__radd__",
+ arg: "Other",
+ pyres: true,
+ proto: "pyo3::class::number::PyNumberRAddProtocol",
++ default: "pyo3::class::number::PyNumberRAddProtocol",
+ },
+ MethodProto::Binary {
+ name: "__rsub__",
+ arg: "Other",
+ pyres: true,
+ proto: "pyo3::class::number::PyNumberRSubProtocol",
++ default: "pyo3::class::number::PyNumberRSubProtocol",
+ },
+ MethodProto::Binary {
+ name: "__rmul__",
+ arg: "Other",
+ pyres: true,
+ proto: "pyo3::class::number::PyNumberRMulProtocol",
++ default: "pyo3::class::number::PyNumberRMulProtocol",
+ },
+ MethodProto::Binary {
+ name: "__rmatmul__",
+ arg: "Other",
+ pyres: true,
+ proto: "pyo3::class::number::PyNumberRMatmulProtocol",
++ default: "pyo3::class::number::PyNumberRMatmulProtocol",
+ },
+ MethodProto::Binary {
+ name: "__rtruediv__",
+ arg: "Other",
+ pyres: true,
+ proto: "pyo3::class::number::PyNumberRTruedivProtocol",
++ default: "pyo3::class::number::PyNumberRTruedivProtocol",
+ },
+ MethodProto::Binary {
+ name: "__rfloordiv__",
+ arg: "Other",
+ pyres: true,
+ proto: "pyo3::class::number::PyNumberRFloordivProtocol",
++ default: "pyo3::class::number::PyNumberRFloordivProtocol",
+ },
+ MethodProto::Binary {
+ name: "__rmod__",
+ arg: "Other",
+ pyres: true,
+ proto: "pyo3::class::number::PyNumberRModProtocol",
++ default: "pyo3::class::number::PyNumberRModProtocol",
+ },
+ MethodProto::Binary {
+ name: "__rdivmod__",
+ arg: "Other",
+ pyres: true,
+ proto: "pyo3::class::number::PyNumberRDivmodProtocol",
++ default: "pyo3::class::number::PyNumberRDivmodProtocol",
+ },
+ MethodProto::Ternary {
+ name: "__rpow__",
+@@ -537,78 +620,91 @@ const NUM: Proto = Proto {
+ arg2: "Modulo",
+ pyres: true,
+ proto: "pyo3::class::number::PyNumberRPowProtocol",
++ default: "pyo3::class::number::PyNumberRPowProtocol",
+ },
+ MethodProto::Binary {
+ name: "__rlshift__",
+ arg: "Other",
+ pyres: true,
+ proto: "pyo3::class::number::PyNumberRLShiftProtocol",
++ default: "pyo3::class::number::PyNumberRLShiftProtocol",
+ },
+ MethodProto::Binary {
+ name: "__rrshift__",
+ arg: "Other",
+ pyres: true,
+ proto: "pyo3::class::number::PyNumberRRShiftProtocol",
++ default: "pyo3::class::number::PyNumberRRShiftProtocol",
+ },
+ MethodProto::Binary {
+ name: "__rand__",
+ arg: "Other",
+ pyres: true,
+ proto: "pyo3::class::number::PyNumberRAndProtocol",
++ default: "pyo3::class::number::PyNumberRAndProtocol",
+ },
+ MethodProto::Binary {
+ name: "__rxor__",
+ arg: "Other",
+ pyres: true,
+ proto: "pyo3::class::number::PyNumberRXorProtocol",
++ default: "pyo3::class::number::PyNumberRXorProtocol",
+ },
+ MethodProto::Binary {
+ name: "__ror__",
+ arg: "Other",
+ pyres: true,
+ proto: "pyo3::class::number::PyNumberROrProtocol",
++ default: "pyo3::class::number::PyNumberROrProtocol",
+ },
+ MethodProto::Binary {
+ name: "__iadd__",
+ arg: "Other",
+ pyres: false,
+ proto: "pyo3::class::number::PyNumberIAddProtocol",
++ default: "pyo3::class::number::PyNumberIAddProtocol",
+ },
+ MethodProto::Binary {
+ name: "__isub__",
+ arg: "Other",
+ pyres: false,
+ proto: "pyo3::class::number::PyNumberISubProtocol",
++ default: "pyo3::class::number::PyNumberISubProtocol",
+ },
+ MethodProto::Binary {
+ name: "__imul__",
+ arg: "Other",
+ pyres: false,
+ proto: "pyo3::class::number::PyNumberIMulProtocol",
++ default: "pyo3::class::number::PyNumberIMulProtocol",
+ },
+ MethodProto::Binary {
+ name: "__imatmul__",
+ arg: "Other",
+ pyres: false,
+ proto: "pyo3::class::number::PyNumberIMatmulProtocol",
++ default: "pyo3::class::number::PyNumberIMatmulProtocol",
+ },
+ MethodProto::Binary {
+ name: "__itruediv__",
+ arg: "Other",
+ pyres: false,
+ proto: "pyo3::class::number::PyNumberITruedivProtocol",
++ default: "pyo3::class::number::PyNumberITruedivProtocol",
+ },
+ MethodProto::Binary {
+ name: "__ifloordiv__",
+ arg: "Other",
+ pyres: false,
+ proto: "pyo3::class::number::PyNumberIFloordivProtocol",
++ default: "pyo3::class::number::PyNumberIFloordivProtocol",
+ },
+ MethodProto::Binary {
+ name: "__imod__",
+ arg: "Other",
+ pyres: false,
+ proto: "pyo3::class::number::PyNumberIModProtocol",
++ default: "pyo3::class::number::PyNumberIModProtocol",
+ },
+ MethodProto::Ternary {
+ name: "__ipow__",
+@@ -616,81 +712,96 @@ const NUM: Proto = Proto {
+ arg2: "Modulo",
+ pyres: false,
+ proto: "pyo3::class::number::PyNumberIPowProtocol",
++ default: "pyo3::class::number::PyNumberIPowProtocol",
+ },
+ MethodProto::Binary {
+ name: "__ilshift__",
+ arg: "Other",
+ pyres: false,
+ proto: "pyo3::class::number::PyNumberILShiftProtocol",
++ default: "pyo3::class::number::PyNumberILShiftProtocol",
+ },
+ MethodProto::Binary {
+ name: "__irshift__",
+ arg: "Other",
+ pyres: false,
+ proto: "pyo3::class::number::PyNumberIRShiftProtocol",
++ default: "pyo3::class::number::PyNumberIRShiftProtocol",
+ },
+ MethodProto::Binary {
+ name: "__iand__",
+ arg: "Other",
+ pyres: false,
+ proto: "pyo3::class::number::PyNumberIAndProtocol",
++ default: "pyo3::class::number::PyNumberIAndProtocol",
+ },
+ MethodProto::Binary {
+ name: "__ixor__",
+ arg: "Other",
+ pyres: false,
+ proto: "pyo3::class::number::PyNumberIXorProtocol",
++ default: "pyo3::class::number::PyNumberIXorProtocol",
+ },
+ MethodProto::Binary {
+ name: "__ior__",
+ arg: "Other",
+ pyres: false,
+ proto: "pyo3::class::number::PyNumberIOrProtocol",
++ default: "pyo3::class::number::PyNumberIOrProtocol",
+ },
+ MethodProto::Unary {
+ name: "__neg__",
+ pyres: true,
+ proto: "pyo3::class::number::PyNumberNegProtocol",
++ default: "pyo3::class::number::PyNumberNegProtocol",
+ },
+ MethodProto::Unary {
+ name: "__pos__",
+ pyres: true,
+ proto: "pyo3::class::number::PyNumberPosProtocol",
++ default: "pyo3::class::number::PyNumberPosProtocol",
+ },
+ MethodProto::Unary {
+ name: "__abs__",
+ pyres: true,
+ proto: "pyo3::class::number::PyNumberAbsProtocol",
++ default: "pyo3::class::number::PyNumberAbsProtocol",
+ },
+ MethodProto::Unary {
+ name: "__invert__",
+ pyres: true,
+ proto: "pyo3::class::number::PyNumberInvertProtocol",
++ default: "pyo3::class::number::PyNumberInvertProtocol",
+ },
+ MethodProto::Unary {
+ name: "__complex__",
+ pyres: true,
+ proto: "pyo3::class::number::PyNumberComplexProtocol",
++ default: "pyo3::class::number::PyNumberComplexProtocol",
+ },
+ MethodProto::Unary {
+ name: "__int__",
+ pyres: true,
+ proto: "pyo3::class::number::PyNumberIntProtocol",
++ default: "pyo3::class::number::PyNumberIntProtocol",
+ },
+ MethodProto::Unary {
+ name: "__float__",
+ pyres: true,
+ proto: "pyo3::class::number::PyNumberFloatProtocol",
++ default: "pyo3::class::number::PyNumberFloatProtocol",
+ },
+ MethodProto::Unary {
+ name: "__round__",
+ pyres: true,
+ proto: "pyo3::class::number::PyNumberRoundProtocol",
++ default: "pyo3::class::number::PyNumberRoundProtocol",
+ },
+ MethodProto::Unary {
+ name: "__index__",
+ pyres: true,
+ proto: "pyo3::class::number::PyNumberIndexProtocol",
++ default: "pyo3::class::number::PyNumberIndexProtocol",
+ },
+ ],
+ py_methods: &[
+@@ -765,8 +876,12 @@ const PROTOCOLS: &[Proto] = &[
+ OBJECT, ASYNC, MAPPING, ITER, CONTEXT, SEQ, NUM, DESCR, BUFFER, GC,
+ ];
+
++pub fn all_protocols() -> &'static [Proto] {
++ PROTOCOLS
++}
++
+ pub fn find_protocol(protocol_trait: &str) -> Option<&'static Proto> {
+ PROTOCOLS
+ .iter()
+- .find(|p| p.protocol_trait() == protocol_trait)
++ .find(|p| p.protocol_trait.ends_with(protocol_trait))
+ }
+diff --git a/pyo3-derive-backend/src/func.rs b/pyo3-derive-backend/src/func.rs
+index 2b7f69aca..ce06716f4 100644
+--- a/pyo3-derive-backend/src/func.rs
++++ b/pyo3-derive-backend/src/func.rs
+@@ -12,17 +12,20 @@ pub enum MethodProto {
+ Free {
+ name: &'static str,
+ proto: &'static str,
++ default: &'static str,
+ },
+ Unary {
+ name: &'static str,
+ pyres: bool,
+ proto: &'static str,
++ default: &'static str,
+ },
+ Binary {
+ name: &'static str,
+ arg: &'static str,
+ pyres: bool,
+ proto: &'static str,
++ default: &'static str,
+ },
+ BinaryS {
+ name: &'static str,
+@@ -30,6 +33,7 @@ pub enum MethodProto {
+ arg2: &'static str,
+ pyres: bool,
+ proto: &'static str,
++ default: &'static str,
+ },
+ Ternary {
+ name: &'static str,
+@@ -37,6 +41,7 @@ pub enum MethodProto {
+ arg2: &'static str,
+ pyres: bool,
+ proto: &'static str,
++ default: &'static str,
+ },
+ TernaryS {
+ name: &'static str,
+@@ -45,6 +50,7 @@ pub enum MethodProto {
+ arg3: &'static str,
+ pyres: bool,
+ proto: &'static str,
++ default: &'static str,
+ },
+ Quaternary {
+ name: &'static str,
+@@ -52,6 +58,7 @@ pub enum MethodProto {
+ arg2: &'static str,
+ arg3: &'static str,
+ proto: &'static str,
++ default: &'static str,
+ },
+ }
+
+@@ -69,6 +76,31 @@ impl PartialEq<str> for MethodProto {
+ }
+ }
+
++impl MethodProto {
++ pub fn get_proto(&self) -> &'static str {
++ match *self {
++ MethodProto::Free { proto: p, .. } => p,
++ MethodProto::Unary { proto: p, .. } => p,
++ MethodProto::Binary { proto: p, .. } => p,
++ MethodProto::BinaryS { proto: p, .. } => p,
++ MethodProto::Ternary { proto: p, .. } => p,
++ MethodProto::TernaryS { proto: p, .. } => p,
++ MethodProto::Quaternary { proto: p, .. } => p,
++ }
++ }
++ pub fn get_default(&self) -> &'static str {
++ match *self {
++ MethodProto::Free { default: d, .. } => d,
++ MethodProto::Unary { default: d, .. } => d,
++ MethodProto::Binary { default: d, .. } => d,
++ MethodProto::BinaryS { default: d, .. } => d,
++ MethodProto::Ternary { default: d, .. } => d,
++ MethodProto::TernaryS { default: d, .. } => d,
++ MethodProto::Quaternary { default: d, .. } => d,
++ }
++ }
++}
++
+ pub fn impl_method_proto(
+ cls: &syn::Type,
+ sig: &mut syn::Signature,
+@@ -119,6 +151,7 @@ pub fn impl_method_proto(
+ arg,
+ pyres,
+ proto,
++ default: _,
+ } => {
+ if sig.inputs.len() <= 1 {
+ println!("Not enough arguments for {}", name);
+@@ -164,6 +197,7 @@ pub fn impl_method_proto(
+ arg2,
+ pyres,
+ proto,
++ default: _,
+ } => {
+ if sig.inputs.len() <= 1 {
+ print_err(format!("Not enough arguments {}", name), quote!(sig));
+@@ -213,6 +247,7 @@ pub fn impl_method_proto(
+ arg2,
+ pyres,
+ proto,
++ default: _,
+ } => {
+ if sig.inputs.len() <= 2 {
+ print_err(format!("Not enough arguments {}", name), quote!(sig));
+@@ -266,6 +301,7 @@ pub fn impl_method_proto(
+ arg3,
+ pyres,
+ proto,
++ default: _,
+ } => {
+ if sig.inputs.len() <= 2 {
+ print_err(format!("Not enough arguments {}", name), quote!(sig));
+@@ -322,6 +358,7 @@ pub fn impl_method_proto(
+ arg2,
+ arg3,
+ proto,
++ default: _,
+ } => {
+ if sig.inputs.len() <= 3 {
+ print_err(format!("Not enough arguments {}", name), quote!(sig));
+diff --git a/pyo3-derive-backend/src/pyclass.rs b/pyo3-derive-backend/src/pyclass.rs
+index 3ac5d4cde..59a0ab29f 100644
+--- a/pyo3-derive-backend/src/pyclass.rs
++++ b/pyo3-derive-backend/src/pyclass.rs
+@@ -1,10 +1,10 @@
+ // Copyright (c) 2017-present PyO3 Project and Contributors
+-
++use crate::defs;
+ use crate::method::{FnArg, FnSpec, FnType};
+ use crate::pymethod::{impl_py_getter_def, impl_py_setter_def, impl_wrap_getter, impl_wrap_setter};
+ use crate::utils;
+ use proc_macro2::{Span, TokenStream};
+-use quote::quote;
++use quote::{format_ident, quote};
+ use syn::parse::{Parse, ParseStream};
+ use syn::punctuated::Punctuated;
+ use syn::{parse_quote, Expr, Token};
+@@ -326,6 +326,14 @@ fn impl_class(
+ extra
+ };
+
++ let extra = {
++ let default_impls = impl_default_protocols(&cls, &attr);
++ quote! {
++ #default_impls
++ #extra
++ }
++ };
++
+ // insert space for weak ref
+ let mut has_weakref = false;
+ let mut has_dict = false;
+@@ -414,6 +422,9 @@ fn impl_class(
+ }
+ }
+
++ //impl<T: pyo3::type_object::PyTypeInfo> pyo3::AsPyRefDispatch<T> for #cls {}
++ //impl pyo3::ManagedPyRefDispatch for #cls {}
++
+ #inventory_impl
+
+ #extra
+@@ -531,3 +542,22 @@ fn check_generics(class: &mut syn::ItemStruct) -> syn::Result<()> {
+ ))
+ }
+ }
++
++fn impl_default_protocols(cls: &syn::Ident, attr: &PyClassArgs) -> TokenStream {
++ let impls: Vec<TokenStream> = defs::all_protocols()
++ .iter()
++ .filter_map(|proto| {
++ if attr
++ .protocols
++ .iter()
++ .any(|x| proto.protocol_trait.ends_with(&x.to_string()))
++ {
++ None
++ } else {
++ let impl_trait: syn::Path = syn::parse_str(proto.impl_trait).unwrap();
++ Some(quote! { impl #impl_trait for #cls {} })
++ }
++ })
++ .collect();
++ quote! { #(#impls)* }
++}
+diff --git a/pyo3-derive-backend/src/pyproto.rs b/pyo3-derive-backend/src/pyproto.rs
+index 41f1deaf9..a73232e1f 100644
+--- a/pyo3-derive-backend/src/pyproto.rs
++++ b/pyo3-derive-backend/src/pyproto.rs
+@@ -1,7 +1,7 @@
+ // Copyright (c) 2017-present PyO3 Project and Contributors
+
+ use crate::defs;
+-use crate::func::impl_method_proto;
++use crate::func::{impl_method_proto, MethodProto};
+ use crate::method::FnSpec;
+ use crate::pymethod;
+ use proc_macro2::Span;
+@@ -53,49 +53,70 @@ fn impl_proto_impl(
+ let mut tokens = TokenStream::new();
+ let mut py_methods = Vec::new();
+
++ let mut unimpl_methods: Vec<&MethodProto> = proto.methods.iter().collect();
++ let mut unimpl_py_methods: Vec<&defs::PyMethod> = proto.py_methods.iter().collect();
++
+ for iimpl in impls.iter_mut() {
+ if let syn::ImplItem::Method(ref mut met) = iimpl {
+- for m in proto.methods {
+- if m == met.sig.ident.to_string().as_str() {
+- impl_method_proto(ty, &mut met.sig, m).to_tokens(&mut tokens);
+- }
+- }
+- for m in proto.py_methods {
+- let ident = met.sig.ident.clone();
+- if m.name == ident.to_string().as_str() {
+- let name = syn::Ident::new(m.name, Span::call_site());
+- let proto: syn::Path = syn::parse_str(m.proto).unwrap();
+-
+- let fn_spec = match FnSpec::parse(&ident, &met.sig, &mut met.attrs) {
+- Ok(fn_spec) => fn_spec,
+- Err(err) => return err.to_compile_error(),
+- };
+- let meth = pymethod::impl_proto_wrap(ty, &ident, &fn_spec);
+-
+- py_methods.push(quote! {
+- impl #proto for #ty
+- {
+- #[inline]
+- fn #name() -> Option<pyo3::class::methods::PyMethodDef> {
+- #meth
+-
+- Some(pyo3::class::PyMethodDef {
+- ml_name: stringify!(#name),
+- ml_meth: pyo3::class::PyMethodType::PyCFunctionWithKeywords(__wrap),
+- ml_flags: pyo3::ffi::METH_VARARGS | pyo3::ffi::METH_KEYWORDS,
+- ml_doc: ""
+- })
+- }
++ let method_name = met.sig.ident.to_string();
++ // Find the method in unimpl_methods, remove it and implement it
++ unimpl_methods
++ .iter()
++ .position(|m| *m == method_name.as_str())
++ .map(|idx| {
++ let method = unimpl_methods.swap_remove(idx);
++ impl_method_proto(ty, &mut met.sig, method).to_tokens(&mut tokens);
++ });
++
++ // MJDFIXME - undo this change
++ let py_method_name = &met.sig.ident;
++ let method = unimpl_py_methods
++ .iter()
++ .position(|m| m.name == py_method_name.to_string().as_str())
++ .map(|idx| unimpl_py_methods.swap_remove(idx));
++
++ if let Some(m) = method {
++ let name = syn::Ident::new(m.name, Span::call_site());
++ let proto: syn::Path = syn::parse_str(m.proto).unwrap();
++
++ let fn_spec = match FnSpec::parse(&py_method_name, &met.sig, &mut met.attrs) {
++ Ok(fn_spec) => fn_spec,
++ Err(err) => return err.to_compile_error(),
++ };
++ let meth = pymethod::impl_proto_wrap(ty, &py_method_name, &fn_spec);
++
++ py_methods.push(quote! {
++ impl #proto for #ty
++ {
++ #[inline]
++ fn #name() -> Option<pyo3::class::methods::PyMethodDef> {
++ #meth
++
++ Some(pyo3::class::PyMethodDef {
++ ml_name: stringify!(#name),
++ ml_meth: pyo3::class::PyMethodType::PyCFunctionWithKeywords(__wrap),
++ ml_flags: pyo3::ffi::METH_VARARGS | pyo3::ffi::METH_KEYWORDS,
++ ml_doc: ""
++ })
+ }
+- });
+- }
+- }
++ }
++ });
++ };
+ }
+ }
+
++ let default_impls: Vec<_> = unimpl_methods
++ .iter()
++ .map(|m| {
++ let proto: syn::Path = syn::parse_str(m.get_default()).unwrap();
++ quote! { impl #proto for #ty {} }
++ })
++ .collect();
+ quote! {
+ #tokens
+
+ #(#py_methods)*
++
++ #(#default_impls)*
+ }
+ }
+diff --git a/src/buffer.rs b/src/buffer.rs
+index 91c317f6e..cdb305ad4 100644
+--- a/src/buffer.rs
++++ b/src/buffer.rs
+@@ -710,8 +710,9 @@ mod test {
+ fn test_array_buffer() {
+ let gil = Python::acquire_gil();
+ let py = gil.python();
+- let array = py
+- .import("array")
++ let arr = py.import("array");
++ println!("{:?}", arr);
++ let array = arr
+ .unwrap()
+ .call_method("array", ("f", (1.0, 1.5, 2.0, 2.5)), None)
+ .unwrap();
+diff --git a/src/class/buffer.rs b/src/class/buffer.rs
+index 32d1a25af..48ecc58ce 100644
+--- a/src/class/buffer.rs
++++ b/src/class/buffer.rs
+@@ -91,3 +91,9 @@ where
+ Some(wrap::<T>)
+ }
+ }
++
++pub trait PyBufferReleaseBufferProtocolImpl {
++ fn cb_bf_releasebuffer() -> Option<ffi::releasebufferproc> {
++ None
++ }
++}
+diff --git a/src/lib.rs b/src/lib.rs
+index 65fb611db..49e71ef6d 100755
+--- a/src/lib.rs
++++ b/src/lib.rs
+@@ -122,7 +122,9 @@ pub use crate::conversion::{
+ };
+ pub use crate::err::{PyDowncastError, PyErr, PyErrArguments, PyErrValue, PyResult};
+ pub use crate::gil::{init_once, GILGuard, GILPool};
+-pub use crate::instance::{AsPyRef, ManagedPyRef, Py, PyNativeType, PyRef, PyRefMut};
++pub use crate::instance::{
++ AsPyRef, AsPyRefDispatch, ManagedPyRef, ManagedPyRefDispatch, Py, PyNativeType, PyRef, PyRefMut,
++};
+ pub use crate::object::PyObject;
+ pub use crate::objectprotocol::ObjectProtocol;
+ pub use crate::python::{prepare_freethreaded_python, Python};
+diff --git a/tests/test_arithmetics.rp b/tests/test_arithmetics.rp
+index 77e8b64fe..42e378b5c 100644
+--- a/tests/test_arithmetics.rp
++++ b/tests/test_arithmetics.rp
+@@ -8,7 +8,7 @@ use pyo3::types::PyAny;
+
+ mod common;
+
+-#[pyclass]
++#[pyclass(protocols=[PyNumberProtocol])]
+ struct UnaryArithmetic {}
+
+ #[pyproto]
+@@ -42,7 +42,7 @@ fn unary_arithmetic() {
+ py_run!(py, c, "assert ~c == 'invert'");
+ }
+
+-#[pyclass]
++#[pyclass(protocols=[PyNumberProtocol, PyObjectProtocol])]
+ struct BinaryArithmetic {}
+
+ #[pyproto]
+@@ -52,7 +52,7 @@ impl PyObjectProtocol for BinaryArithmetic {
+ }
+ }
+
+-#[pyclass]
++#[pyclass(protocols=[PyNumberProtocol, PyObjectProtocol])]
+ struct InPlaceOperations {
+ value: u32,
+ }
+@@ -188,7 +188,7 @@ fn binary_arithmetic() {
+ py_run!(py, c, "assert 1 | c == '1 | BA'");
+ }
+
+-#[pyclass]
++#[pyclass(protocols=[PyNumberProtocol])]
+ struct RhsArithmetic {}
+
+ #[pyproto]
+@@ -210,7 +210,7 @@ fn rhs_arithmetic() {
+ // py_run!(py, c, "assert 1 + c == '1 + RA'");
+ }
+
+-#[pyclass]
++#[pyclass(protocols=[PyObjectProtocol])]
+ struct RichComparisons {}
+
+ #[pyproto]
+@@ -231,7 +231,7 @@ impl PyObjectProtocol for RichComparisons {
+ }
+ }
+
+-#[pyclass]
++#[pyclass(protocols=[PyObjectProtocol])]
+ struct RichComparisons2 {}
+
+ #[pyproto]
+diff --git a/tests/test_buffer_protocol.rp b/tests/test_buffer_protocol.rs
+similarity index 98%
+rename from tests/test_buffer_protocol.rp
+rename to tests/test_buffer_protocol.rs
+index 64aa4b944..ecbc6038d 100644
+--- a/tests/test_buffer_protocol.rp
++++ b/tests/test_buffer_protocol.rs
+@@ -7,7 +7,7 @@ use std::ffi::CStr;
+ use std::os::raw::{c_int, c_void};
+ use std::ptr;
+
+-#[pyclass]
++#[pyclass(protocols=[PyBufferProtocol])]
+ struct TestClass {
+ vec: Vec<u8>,
+ }
+diff --git a/tests/test_class_basics.rs b/tests/test_class_basics.rs
+index c8e1a42df..7b3ff6bc8 100644
+--- a/tests/test_class_basics.rs
++++ b/tests/test_class_basics.rs
+@@ -5,20 +5,9 @@ use pyo3::type_object::initialize_type;
+
+ mod common;
+
+-#[pyclass(protocols=[PySequenceProtocol])]
++#[pyclass]
+ struct EmptyClass {}
+
+-impl class::gc::PyGCProtocolImpl for EmptyClass {}
+-impl class::buffer::PyBufferProtocolImpl for EmptyClass {}
+-impl class::context::PyContextProtocolImpl for EmptyClass {}
+-impl class::iter::PyIterProtocolImpl for EmptyClass {}
+-impl class::descr::PyDescrProtocolImpl for EmptyClass {}
+-impl class::basic::PyObjectProtocolImpl for EmptyClass {}
+-impl class::number::PyNumberProtocolImpl for EmptyClass {}
+-impl class::mapping::PyMappingProtocolImpl for EmptyClass {}
+-impl class::sequence::PySequenceProtocolImpl for EmptyClass {}
+-impl class::pyasync::PyAsyncProtocolImpl for EmptyClass {}
+-
+ #[test]
+ fn empty_class() {
+ let gil = Python::acquire_gil();
+@@ -29,7 +18,7 @@ fn empty_class() {
+
+ py_assert!(py, typeobj, "typeobj.__name__ == 'EmptyClass'");
+ }
+-/*
++
+ /// Line1
+ ///Line2
+ /// Line3
+@@ -89,4 +78,4 @@ fn empty_class_in_module() {
+ initialize_type::<EmptyClassInModule>(py, Some("test_module.nested")).unwrap();
+ let module: String = ty.getattr("__module__").unwrap().extract().unwrap();
+ assert_eq!(module, "test_module.nested");
+-}*/
++}
+diff --git a/tests/test_class_new.rp b/tests/test_class_new.rs
+similarity index 100%
+rename from tests/test_class_new.rp
+rename to tests/test_class_new.rs
+diff --git a/tests/test_compile_error.rp b/tests/test_compile_error.rs
+similarity index 100%
+rename from tests/test_compile_error.rp
+rename to tests/test_compile_error.rs
+diff --git a/tests/test_datetime.rp b/tests/test_datetime.rp
+index 2819f92c4..a8de5f638 100644
+--- a/tests/test_datetime.rp
++++ b/tests/test_datetime.rp
+@@ -1,5 +1,3 @@
+-#![feature(concat_idents)]
+-
+ use pyo3::ffi::*;
+ use pyo3::prelude::*;
+ use pyo3::types::{IntoPyDict, PyAny};
+diff --git a/tests/test_gc.rp b/tests/test_gc.rs
+similarity index 98%
+rename from tests/test_gc.rp
+rename to tests/test_gc.rs
+index 26465438a..fa0c3d9cf 100644
+--- a/tests/test_gc.rp
++++ b/tests/test_gc.rs
+@@ -132,7 +132,7 @@ fn create_pointers_in_drop() {
+ }
+
+ #[allow(dead_code)]
+-#[pyclass]
++#[pyclass(protocols=[PyGCProtocol])]
+ struct GCIntegration {
+ self_ref: RefCell<PyObject>,
+ dropped: TestDropCall,
+@@ -177,7 +177,7 @@ fn gc_integration() {
+ assert!(drop_called.load(Ordering::Relaxed));
+ }
+
+-#[pyclass(gc)]
++#[pyclass(gc, protocols=[PyGCProtocol])]
+ struct GCIntegration2 {}
+
+ #[pyproto]
+diff --git a/tests/test_getter_setter.rp b/tests/test_getter_setter.rs
+similarity index 100%
+rename from tests/test_getter_setter.rp
+rename to tests/test_getter_setter.rs
+diff --git a/tests/test_sequence.rp b/tests/test_sequence.rs
+similarity index 99%
+rename from tests/test_sequence.rp
+rename to tests/test_sequence.rs
+index 6241f33ec..861ba6988 100644
+--- a/tests/test_sequence.rp
++++ b/tests/test_sequence.rs
+@@ -6,7 +6,7 @@ use pyo3::types::IntoPyDict;
+ use pyo3::types::PyAny;
+ use pyo3::types::PyList;
+
+-#[pyclass]
++#[pyclass(protocols=[PySequenceProtocol])]
+ struct ByteSequence {
+ elements: Vec<u8>,
+ }
+diff --git a/tests/test_variable_arguments.rp b/tests/test_variable_arguments.rs
+similarity index 100%
+rename from tests/test_variable_arguments.rp
+rename to tests/test_variable_arguments.rs
+diff --git a/tests/test_various.rp b/tests/test_various.rs
+similarity index 98%
+rename from tests/test_various.rp
+rename to tests/test_various.rs
+index 655101db2..101bdabb0 100644
+--- a/tests/test_various.rp
++++ b/tests/test_various.rs
+@@ -33,7 +33,8 @@ fn mut_ref_arg() {
+ let d = [("inst1", &inst1), ("inst2", &inst2)].into_py_dict(py);
+
+ py.run("inst1.set_other(inst2)", None, Some(d)).unwrap();
+- assert_eq!(inst2.as_ref(py).n, 100);
++ // MJDFIXME
++ //assert_eq!(inst2.as_ref(py).n, 100);
+ }
+
+ #[pyclass]
diff --git a/srcpkgs/anki/files/pyo3-patches/0017-specialization-c27d10fcd8932c3d83fe73b07412969cc42ff686.patch b/srcpkgs/anki/files/pyo3-patches/0017-specialization-c27d10fcd8932c3d83fe73b07412969cc42ff686.patch
new file mode 100644
index 00000000000..c9946de5852
--- /dev/null
+++ b/srcpkgs/anki/files/pyo3-patches/0017-specialization-c27d10fcd8932c3d83fe73b07412969cc42ff686.patch
@@ -0,0 +1,38 @@
+From c27d10fcd8932c3d83fe73b07412969cc42ff686 Mon Sep 17 00:00:00 2001
+From: Martin Donlon <github-martin@donlons.com>
+Date: Sun, 3 Nov 2019 19:29:06 -0800
+Subject: [PATCH] impl AsPyRefDispatch for every pyclass
+
+---
+ pyo3-derive-backend/src/pyclass.rs | 3 +--
+ tests/test_various.rs | 3 +--
+ 2 files changed, 2 insertions(+), 4 deletions(-)
+
+diff --git a/pyo3-derive-backend/src/pyclass.rs b/pyo3-derive-backend/src/pyclass.rs
+index 59a0ab29f..ea6c0f513 100644
+--- a/pyo3-derive-backend/src/pyclass.rs
++++ b/pyo3-derive-backend/src/pyclass.rs
+@@ -422,8 +422,7 @@ fn impl_class(
+ }
+ }
+
+- //impl<T: pyo3::type_object::PyTypeInfo> pyo3::AsPyRefDispatch<T> for #cls {}
+- //impl pyo3::ManagedPyRefDispatch for #cls {}
++ impl pyo3::AsPyRefDispatch<#cls> for Py<#cls> {}
+
+ #inventory_impl
+
+diff --git a/tests/test_various.rs b/tests/test_various.rs
+index 101bdabb0..655101db2 100644
+--- a/tests/test_various.rs
++++ b/tests/test_various.rs
+@@ -33,8 +33,7 @@ fn mut_ref_arg() {
+ let d = [("inst1", &inst1), ("inst2", &inst2)].into_py_dict(py);
+
+ py.run("inst1.set_other(inst2)", None, Some(d)).unwrap();
+- // MJDFIXME
+- //assert_eq!(inst2.as_ref(py).n, 100);
++ assert_eq!(inst2.as_ref(py).n, 100);
+ }
+
+ #[pyclass]
diff --git a/srcpkgs/anki/files/pyo3-patches/0018-specialization-d6102a4b93b16ba9b7b43a1c73614efbcb6e9814.patch b/srcpkgs/anki/files/pyo3-patches/0018-specialization-d6102a4b93b16ba9b7b43a1c73614efbcb6e9814.patch
new file mode 100644
index 00000000000..a66cb076d41
--- /dev/null
+++ b/srcpkgs/anki/files/pyo3-patches/0018-specialization-d6102a4b93b16ba9b7b43a1c73614efbcb6e9814.patch
@@ -0,0 +1,732 @@
+From d6102a4b93b16ba9b7b43a1c73614efbcb6e9814 Mon Sep 17 00:00:00 2001
+From: Martin Donlon <github-martin@donlons.com>
+Date: Mon, 4 Nov 2019 21:13:08 -0800
+Subject: [PATCH] Hack and slash to get arithmetic tests working
+
+---
+ pyo3-derive-backend/src/defs.rs | 127 +++++++++---------
+ src/class/basic.rs | 14 +-
+ src/class/number.rs | 28 ----
+ ...est_arithmetics.rp => test_arithmetics.rs} | 3 -
+ 4 files changed, 75 insertions(+), 97 deletions(-)
+ rename tests/{test_arithmetics.rp => test_arithmetics.rs} (99%)
+
+diff --git a/pyo3-derive-backend/src/defs.rs b/pyo3-derive-backend/src/defs.rs
+index 06c1c6754..d793c9628 100644
+--- a/pyo3-derive-backend/src/defs.rs
++++ b/pyo3-derive-backend/src/defs.rs
+@@ -24,7 +24,7 @@ const OBJECT: Proto = Proto {
+ arg: "Name",
+ pyres: true,
+ proto: "pyo3::class::basic::PyObjectGetAttrProtocol",
+- default: "pyo3::class::basic::PyObjectGetAttrProtocol",
++ default: "pyo3::class::basic::GetAttrProtocolImpl",
+ },
+ MethodProto::Ternary {
+ name: "__setattr__",
+@@ -32,58 +32,65 @@ const OBJECT: Proto = Proto {
+ arg2: "Value",
+ pyres: false,
+ proto: "pyo3::class::basic::PyObjectSetAttrProtocol",
+- default: "pyo3::class::basic::PyObjectSetAttrProtocol",
++ default: "pyo3::class::basic::tp_setattro_impl::SetAttr",
+ },
+ MethodProto::Binary {
+ name: "__delattr__",
+ arg: "Name",
+ pyres: true,
+ proto: "pyo3::class::basic::PyObjectDelAttrProtocol",
+- default: "pyo3::class::basic::PyObjectDelAttrProtocol",
++ default: "pyo3::class::basic::tp_setattro_impl::DelAttr",
+ },
+ MethodProto::Unary {
+ name: "__str__",
+ pyres: true,
+ proto: "pyo3::class::basic::PyObjectStrProtocol",
+- default: "pyo3::class::basic::PyObjectStrProtocol",
++ default: "pyo3::class::basic::StrProtocolImpl",
+ },
+ MethodProto::Unary {
+ name: "__repr__",
+ pyres: true,
+ proto: "pyo3::class::basic::PyObjectReprProtocol",
+- default: "pyo3::class::basic::PyObjectReprProtocol",
++ default: "pyo3::class::basic::ReprProtocolImpl",
+ },
+ MethodProto::Binary {
+ name: "__format__",
+ arg: "Format",
+ pyres: true,
+ proto: "pyo3::class::basic::PyObjectFormatProtocol",
+- default: "pyo3::class::basic::PyObjectFormatProtocol",
++ default: "pyo3::class::basic::FormatProtocolImpl",
+ },
+ MethodProto::Unary {
+ name: "__hash__",
+ pyres: false,
+ proto: "pyo3::class::basic::PyObjectHashProtocol",
+- default: "pyo3::class::basic::PyObjectHashProtocol",
++ default: "pyo3::class::basic::HashProtocolImpl",
+ },
+ MethodProto::Unary {
+ name: "__bytes__",
+ pyres: true,
+ proto: "pyo3::class::basic::PyObjectBytesProtocol",
+- default: "pyo3::class::basic::PyObjectBytesProtocol",
++ default: "pyo3::class::basic::BytesProtocolImpl",
++ },
++ MethodProto::Unary {
++ // MJDFIXME ???
++ name: "__unicode__",
++ pyres: true,
++ proto: "pyo3::class::basic::PyObjectUnicodeProtocol",
++ default: "pyo3::class::basic::UnicodeProtocolImpl",
+ },
+ MethodProto::Unary {
+ name: "__bool__",
+ pyres: false,
+ proto: "pyo3::class::basic::PyObjectBoolProtocol",
+- default: "pyo3::class::basic::PyObjectBoolProtocol",
++ default: "pyo3::class::basic::BoolProtocolImpl",
+ },
+ MethodProto::Binary {
+ name: "__richcmp__",
+ arg: "Other",
+ pyres: true,
+ proto: "pyo3::class::basic::PyObjectRichcmpProtocol",
+- default: "pyo3::class::basic::PyObjectRichcmpProtocol",
++ default: "pyo3::class::basic::RichcmpProtocolImpl",
+ },
+ ],
+ py_methods: &[
+@@ -451,7 +458,7 @@ const NUM: Proto = Proto {
+ arg2: "Right",
+ pyres: true,
+ proto: "pyo3::class::number::PyNumberAddProtocol",
+- default: "pyo3::class::number::PyNumberAddProtocol",
++ default: "pyo3::class::number::PyNumberAddProtocolImpl",
+ },
+ MethodProto::BinaryS {
+ name: "__sub__",
+@@ -459,7 +466,7 @@ const NUM: Proto = Proto {
+ arg2: "Right",
+ pyres: true,
+ proto: "pyo3::class::number::PyNumberSubProtocol",
+- default: "pyo3::class::number::PyNumberSubProtocol",
++ default: "pyo3::class::number::PyNumberSubProtocolImpl",
+ },
+ MethodProto::BinaryS {
+ name: "__mul__",
+@@ -467,7 +474,7 @@ const NUM: Proto = Proto {
+ arg2: "Right",
+ pyres: true,
+ proto: "pyo3::class::number::PyNumberMulProtocol",
+- default: "pyo3::class::number::PyNumberMulProtocol",
++ default: "pyo3::class::number::PyNumberMulProtocolImpl",
+ },
+ MethodProto::BinaryS {
+ name: "__matmul__",
+@@ -475,7 +482,7 @@ const NUM: Proto = Proto {
+ arg2: "Right",
+ pyres: true,
+ proto: "pyo3::class::number::PyNumberMatmulProtocol",
+- default: "pyo3::class::number::PyNumberMatmulProtocol",
++ default: "pyo3::class::number::PyNumberMatmulProtocolImpl",
+ },
+ MethodProto::BinaryS {
+ name: "__truediv__",
+@@ -483,7 +490,7 @@ const NUM: Proto = Proto {
+ arg2: "Right",
+ pyres: true,
+ proto: "pyo3::class::number::PyNumberTruedivProtocol",
+- default: "pyo3::class::number::PyNumberTruedivProtocol",
++ default: "pyo3::class::number::PyNumberTruedivProtocolImpl",
+ },
+ MethodProto::BinaryS {
+ name: "__floordiv__",
+@@ -491,7 +498,7 @@ const NUM: Proto = Proto {
+ arg2: "Right",
+ pyres: true,
+ proto: "pyo3::class::number::PyNumberFloordivProtocol",
+- default: "pyo3::class::number::PyNumberFloordivProtocol",
++ default: "pyo3::class::number::PyNumberFloordivProtocolImpl",
+ },
+ MethodProto::BinaryS {
+ name: "__mod__",
+@@ -499,7 +506,7 @@ const NUM: Proto = Proto {
+ arg2: "Right",
+ pyres: true,
+ proto: "pyo3::class::number::PyNumberModProtocol",
+- default: "pyo3::class::number::PyNumberModProtocol",
++ default: "pyo3::class::number::PyNumberModProtocolImpl",
+ },
+ MethodProto::BinaryS {
+ name: "__divmod__",
+@@ -507,7 +514,7 @@ const NUM: Proto = Proto {
+ arg2: "Right",
+ pyres: true,
+ proto: "pyo3::class::number::PyNumberDivmodProtocol",
+- default: "pyo3::class::number::PyNumberDivmodProtocol",
++ default: "pyo3::class::number::PyNumberDivmodProtocolImpl",
+ },
+ MethodProto::TernaryS {
+ name: "__pow__",
+@@ -516,7 +523,7 @@ const NUM: Proto = Proto {
+ arg3: "Modulo",
+ pyres: true,
+ proto: "pyo3::class::number::PyNumberPowProtocol",
+- default: "pyo3::class::number::PyNumberPowProtocol",
++ default: "pyo3::class::number::PyNumberPowProtocolImpl",
+ },
+ MethodProto::BinaryS {
+ name: "__lshift__",
+@@ -524,7 +531,7 @@ const NUM: Proto = Proto {
+ arg2: "Right",
+ pyres: true,
+ proto: "pyo3::class::number::PyNumberLShiftProtocol",
+- default: "pyo3::class::number::PyNumberLShiftProtocol",
++ default: "pyo3::class::number::PyNumberLShiftProtocolImpl",
+ },
+ MethodProto::BinaryS {
+ name: "__rshift__",
+@@ -532,7 +539,7 @@ const NUM: Proto = Proto {
+ arg2: "Right",
+ pyres: true,
+ proto: "pyo3::class::number::PyNumberRShiftProtocol",
+- default: "pyo3::class::number::PyNumberRShiftProtocol",
++ default: "pyo3::class::number::PyNumberRShiftProtocolImpl",
+ },
+ MethodProto::BinaryS {
+ name: "__and__",
+@@ -540,7 +547,7 @@ const NUM: Proto = Proto {
+ arg2: "Right",
+ pyres: true,
+ proto: "pyo3::class::number::PyNumberAndProtocol",
+- default: "pyo3::class::number::PyNumberAndProtocol",
++ default: "pyo3::class::number::PyNumberAndProtocolImpl",
+ },
+ MethodProto::BinaryS {
+ name: "__xor__",
+@@ -548,7 +555,7 @@ const NUM: Proto = Proto {
+ arg2: "Right",
+ pyres: true,
+ proto: "pyo3::class::number::PyNumberXorProtocol",
+- default: "pyo3::class::number::PyNumberXorProtocol",
++ default: "pyo3::class::number::PyNumberXorProtocolImpl",
+ },
+ MethodProto::BinaryS {
+ name: "__or__",
+@@ -556,63 +563,63 @@ const NUM: Proto = Proto {
+ arg2: "Right",
+ pyres: true,
+ proto: "pyo3::class::number::PyNumberOrProtocol",
+- default: "pyo3::class::number::PyNumberOrProtocol",
++ default: "pyo3::class::number::PyNumberOrProtocolImpl",
+ },
+ MethodProto::Binary {
+ name: "__radd__",
+ arg: "Other",
+ pyres: true,
+ proto: "pyo3::class::number::PyNumberRAddProtocol",
+- default: "pyo3::class::number::PyNumberRAddProtocol",
++ default: "pyo3::class::number::PyNumberRAddProtocolImpl",
+ },
+ MethodProto::Binary {
+ name: "__rsub__",
+ arg: "Other",
+ pyres: true,
+ proto: "pyo3::class::number::PyNumberRSubProtocol",
+- default: "pyo3::class::number::PyNumberRSubProtocol",
++ default: "pyo3::class::number::PyNumberRSubProtocolImpl",
+ },
+ MethodProto::Binary {
+ name: "__rmul__",
+ arg: "Other",
+ pyres: true,
+ proto: "pyo3::class::number::PyNumberRMulProtocol",
+- default: "pyo3::class::number::PyNumberRMulProtocol",
++ default: "pyo3::class::number::PyNumberRMulProtocolImpl",
+ },
+ MethodProto::Binary {
+ name: "__rmatmul__",
+ arg: "Other",
+ pyres: true,
+ proto: "pyo3::class::number::PyNumberRMatmulProtocol",
+- default: "pyo3::class::number::PyNumberRMatmulProtocol",
++ default: "pyo3::class::number::PyNumberRMatmulProtocolImpl",
+ },
+ MethodProto::Binary {
+ name: "__rtruediv__",
+ arg: "Other",
+ pyres: true,
+ proto: "pyo3::class::number::PyNumberRTruedivProtocol",
+- default: "pyo3::class::number::PyNumberRTruedivProtocol",
++ default: "pyo3::class::number::PyNumberRTruedivProtocolImpl",
+ },
+ MethodProto::Binary {
+ name: "__rfloordiv__",
+ arg: "Other",
+ pyres: true,
+ proto: "pyo3::class::number::PyNumberRFloordivProtocol",
+- default: "pyo3::class::number::PyNumberRFloordivProtocol",
++ default: "pyo3::class::number::PyNumberRFloordivProtocolImpl",
+ },
+ MethodProto::Binary {
+ name: "__rmod__",
+ arg: "Other",
+ pyres: true,
+ proto: "pyo3::class::number::PyNumberRModProtocol",
+- default: "pyo3::class::number::PyNumberRModProtocol",
++ default: "pyo3::class::number::PyNumberRModProtocolImpl",
+ },
+ MethodProto::Binary {
+ name: "__rdivmod__",
+ arg: "Other",
+ pyres: true,
+ proto: "pyo3::class::number::PyNumberRDivmodProtocol",
+- default: "pyo3::class::number::PyNumberRDivmodProtocol",
++ default: "pyo3::class::number::PyNumberRDivmodProtocolImpl",
+ },
+ MethodProto::Ternary {
+ name: "__rpow__",
+@@ -620,91 +627,91 @@ const NUM: Proto = Proto {
+ arg2: "Modulo",
+ pyres: true,
+ proto: "pyo3::class::number::PyNumberRPowProtocol",
+- default: "pyo3::class::number::PyNumberRPowProtocol",
++ default: "pyo3::class::number::PyNumberRPowProtocolImpl",
+ },
+ MethodProto::Binary {
+ name: "__rlshift__",
+ arg: "Other",
+ pyres: true,
+ proto: "pyo3::class::number::PyNumberRLShiftProtocol",
+- default: "pyo3::class::number::PyNumberRLShiftProtocol",
++ default: "pyo3::class::number::PyNumberRLShiftProtocolImpl",
+ },
+ MethodProto::Binary {
+ name: "__rrshift__",
+ arg: "Other",
+ pyres: true,
+ proto: "pyo3::class::number::PyNumberRRShiftProtocol",
+- default: "pyo3::class::number::PyNumberRRShiftProtocol",
++ default: "pyo3::class::number::PyNumberRRShiftProtocolImpl",
+ },
+ MethodProto::Binary {
+ name: "__rand__",
+ arg: "Other",
+ pyres: true,
+ proto: "pyo3::class::number::PyNumberRAndProtocol",
+- default: "pyo3::class::number::PyNumberRAndProtocol",
++ default: "pyo3::class::number::PyNumberRAndProtocolImpl",
+ },
+ MethodProto::Binary {
+ name: "__rxor__",
+ arg: "Other",
+ pyres: true,
+ proto: "pyo3::class::number::PyNumberRXorProtocol",
+- default: "pyo3::class::number::PyNumberRXorProtocol",
++ default: "pyo3::class::number::PyNumberRXorProtocolImpl",
+ },
+ MethodProto::Binary {
+ name: "__ror__",
+ arg: "Other",
+ pyres: true,
+ proto: "pyo3::class::number::PyNumberROrProtocol",
+- default: "pyo3::class::number::PyNumberROrProtocol",
++ default: "pyo3::class::number::PyNumberROrProtocolImpl",
+ },
+ MethodProto::Binary {
+ name: "__iadd__",
+ arg: "Other",
+ pyres: false,
+ proto: "pyo3::class::number::PyNumberIAddProtocol",
+- default: "pyo3::class::number::PyNumberIAddProtocol",
++ default: "pyo3::class::number::PyNumberIAddProtocolImpl",
+ },
+ MethodProto::Binary {
+ name: "__isub__",
+ arg: "Other",
+ pyres: false,
+ proto: "pyo3::class::number::PyNumberISubProtocol",
+- default: "pyo3::class::number::PyNumberISubProtocol",
++ default: "pyo3::class::number::PyNumberISubProtocolImpl",
+ },
+ MethodProto::Binary {
+ name: "__imul__",
+ arg: "Other",
+ pyres: false,
+ proto: "pyo3::class::number::PyNumberIMulProtocol",
+- default: "pyo3::class::number::PyNumberIMulProtocol",
++ default: "pyo3::class::number::PyNumberIMulProtocolImpl",
+ },
+ MethodProto::Binary {
+ name: "__imatmul__",
+ arg: "Other",
+ pyres: false,
+ proto: "pyo3::class::number::PyNumberIMatmulProtocol",
+- default: "pyo3::class::number::PyNumberIMatmulProtocol",
++ default: "pyo3::class::number::PyNumberIMatmulProtocolImpl",
+ },
+ MethodProto::Binary {
+ name: "__itruediv__",
+ arg: "Other",
+ pyres: false,
+ proto: "pyo3::class::number::PyNumberITruedivProtocol",
+- default: "pyo3::class::number::PyNumberITruedivProtocol",
++ default: "pyo3::class::number::PyNumberITruedivProtocolImpl",
+ },
+ MethodProto::Binary {
+ name: "__ifloordiv__",
+ arg: "Other",
+ pyres: false,
+ proto: "pyo3::class::number::PyNumberIFloordivProtocol",
+- default: "pyo3::class::number::PyNumberIFloordivProtocol",
++ default: "pyo3::class::number::PyNumberIFloordivProtocolImpl",
+ },
+ MethodProto::Binary {
+ name: "__imod__",
+ arg: "Other",
+ pyres: false,
+ proto: "pyo3::class::number::PyNumberIModProtocol",
+- default: "pyo3::class::number::PyNumberIModProtocol",
++ default: "pyo3::class::number::PyNumberIModProtocolImpl",
+ },
+ MethodProto::Ternary {
+ name: "__ipow__",
+@@ -712,96 +719,96 @@ const NUM: Proto = Proto {
+ arg2: "Modulo",
+ pyres: false,
+ proto: "pyo3::class::number::PyNumberIPowProtocol",
+- default: "pyo3::class::number::PyNumberIPowProtocol",
++ default: "pyo3::class::number::PyNumberIPowProtocolImpl",
+ },
+ MethodProto::Binary {
+ name: "__ilshift__",
+ arg: "Other",
+ pyres: false,
+ proto: "pyo3::class::number::PyNumberILShiftProtocol",
+- default: "pyo3::class::number::PyNumberILShiftProtocol",
++ default: "pyo3::class::number::PyNumberILShiftProtocolImpl",
+ },
+ MethodProto::Binary {
+ name: "__irshift__",
+ arg: "Other",
+ pyres: false,
+ proto: "pyo3::class::number::PyNumberIRShiftProtocol",
+- default: "pyo3::class::number::PyNumberIRShiftProtocol",
++ default: "pyo3::class::number::PyNumberIRShiftProtocolImpl",
+ },
+ MethodProto::Binary {
+ name: "__iand__",
+ arg: "Other",
+ pyres: false,
+ proto: "pyo3::class::number::PyNumberIAndProtocol",
+- default: "pyo3::class::number::PyNumberIAndProtocol",
++ default: "pyo3::class::number::PyNumberIAndProtocolImpl",
+ },
+ MethodProto::Binary {
+ name: "__ixor__",
+ arg: "Other",
+ pyres: false,
+ proto: "pyo3::class::number::PyNumberIXorProtocol",
+- default: "pyo3::class::number::PyNumberIXorProtocol",
++ default: "pyo3::class::number::PyNumberIXorProtocolImpl",
+ },
+ MethodProto::Binary {
+ name: "__ior__",
+ arg: "Other",
+ pyres: false,
+ proto: "pyo3::class::number::PyNumberIOrProtocol",
+- default: "pyo3::class::number::PyNumberIOrProtocol",
++ default: "pyo3::class::number::PyNumberIOrProtocolImpl",
+ },
+ MethodProto::Unary {
+ name: "__neg__",
+ pyres: true,
+ proto: "pyo3::class::number::PyNumberNegProtocol",
+- default: "pyo3::class::number::PyNumberNegProtocol",
++ default: "pyo3::class::number::PyNumberNegProtocolImpl",
+ },
+ MethodProto::Unary {
+ name: "__pos__",
+ pyres: true,
+ proto: "pyo3::class::number::PyNumberPosProtocol",
+- default: "pyo3::class::number::PyNumberPosProtocol",
++ default: "pyo3::class::number::PyNumberPosProtocolImpl",
+ },
+ MethodProto::Unary {
+ name: "__abs__",
+ pyres: true,
+ proto: "pyo3::class::number::PyNumberAbsProtocol",
+- default: "pyo3::class::number::PyNumberAbsProtocol",
++ default: "pyo3::class::number::PyNumberAbsProtocolImpl",
+ },
+ MethodProto::Unary {
+ name: "__invert__",
+ pyres: true,
+ proto: "pyo3::class::number::PyNumberInvertProtocol",
+- default: "pyo3::class::number::PyNumberInvertProtocol",
++ default: "pyo3::class::number::PyNumberInvertProtocolImpl",
+ },
+ MethodProto::Unary {
+ name: "__complex__",
+ pyres: true,
+ proto: "pyo3::class::number::PyNumberComplexProtocol",
+- default: "pyo3::class::number::PyNumberComplexProtocol",
++ default: "pyo3::class::number::PyNumberComplexProtocolImpl",
+ },
+ MethodProto::Unary {
+ name: "__int__",
+ pyres: true,
+ proto: "pyo3::class::number::PyNumberIntProtocol",
+- default: "pyo3::class::number::PyNumberIntProtocol",
++ default: "pyo3::class::number::PyNumberIntProtocolImpl",
+ },
+ MethodProto::Unary {
+ name: "__float__",
+ pyres: true,
+ proto: "pyo3::class::number::PyNumberFloatProtocol",
+- default: "pyo3::class::number::PyNumberFloatProtocol",
++ default: "pyo3::class::number::PyNumberFloatProtocolImpl",
+ },
+ MethodProto::Unary {
+ name: "__round__",
+ pyres: true,
+ proto: "pyo3::class::number::PyNumberRoundProtocol",
+- default: "pyo3::class::number::PyNumberRoundProtocol",
++ default: "pyo3::class::number::PyNumberRoundProtocolImpl",
+ },
+ MethodProto::Unary {
+ name: "__index__",
+ pyres: true,
+ proto: "pyo3::class::number::PyNumberIndexProtocol",
+- default: "pyo3::class::number::PyNumberIndexProtocol",
++ default: "pyo3::class::number::PyNumberIndexProtocolImpl",
+ },
+ ],
+ py_methods: &[
+diff --git a/src/class/basic.rs b/src/class/basic.rs
+index f87a0d029..15d682886 100644
+--- a/src/class/basic.rs
++++ b/src/class/basic.rs
+@@ -166,13 +166,15 @@ pub trait PyObjectProtocolImpl {
+ impl<'p, T> PyObjectProtocolImpl for T
+ where
+ T: PyObjectProtocol<'p>
+- + PyObjectSetAttrProtocol<'p>
+ + GetAttrProtocolImpl
+ + StrProtocolImpl
+ + ReprProtocolImpl
+ + HashProtocolImpl
+ + RichcmpProtocolImpl
+ + BoolProtocolImpl
++ + FormatProtocolImpl
++ + BytesProtocolImpl
++ + UnicodeProtocolImpl
+ + tp_setattro_impl::DelAttr
+ + tp_setattro_impl::SetAttr
+ + tp_setattro_impl::SetDelAttr,
+@@ -253,7 +255,7 @@ where
+ /// and may support deleting attributes (by implementing PyObjectDelAttrProtocol)
+ /// and we need to generate a single extern c function that supports only setting, only deleting
+ /// or both, and return None in case none of the two is supported.
+-mod tp_setattro_impl {
++pub mod tp_setattro_impl {
+ use super::*;
+
+ /// setattrofunc PyTypeObject.tp_setattro
+@@ -314,6 +316,9 @@ mod tp_setattro_impl {
+ }
+ }
+
++ impl<T> SetDelAttr for T {}
++
++ /* MJDFIXME
+ impl<T> SetDelAttr for T
+ where
+ T: for<'p> PyObjectSetAttrProtocol<'p> + for<'p> PyObjectDelAttrProtocol<'p>,
+@@ -327,7 +332,7 @@ mod tp_setattro_impl {
+ __delattr__
+ )
+ }
+- }
++ } */
+ }
+
+ pub trait StrProtocolImpl {
+@@ -376,7 +381,6 @@ pub trait FormatProtocolImpl {
+ None
+ }
+ }
+-impl<'p, T> FormatProtocolImpl for T where T: PyObjectProtocol<'p> {}
+
+ #[doc(hidden)]
+ pub trait BytesProtocolImpl {
+@@ -384,7 +388,6 @@ pub trait BytesProtocolImpl {
+ None
+ }
+ }
+-impl<'p, T> BytesProtocolImpl for T where T: PyObjectProtocol<'p> {}
+
+ #[doc(hidden)]
+ pub trait UnicodeProtocolImpl {
+@@ -392,7 +395,6 @@ pub trait UnicodeProtocolImpl {
+ None
+ }
+ }
+-impl<'p, T> UnicodeProtocolImpl for T where T: PyObjectProtocol<'p> {}
+
+ pub trait HashProtocolImpl {
+ fn tp_hash() -> Option<ffi::hashfunc> {
+diff --git a/src/class/number.rs b/src/class/number.rs
+index 796a1c7ea..faad83039 100644
+--- a/src/class/number.rs
++++ b/src/class/number.rs
+@@ -1273,8 +1273,6 @@ pub trait PyNumberRAddProtocolImpl {
+ }
+ }
+
+-impl<'p, T> PyNumberRAddProtocolImpl for T where T: PyNumberProtocol<'p> {}
+-
+ #[doc(hidden)]
+ pub trait PyNumberRSubProtocolImpl {
+ fn __rsub__() -> Option<PyMethodDef> {
+@@ -1282,8 +1280,6 @@ pub trait PyNumberRSubProtocolImpl {
+ }
+ }
+
+-impl<'p, T> PyNumberRSubProtocolImpl for T where T: PyNumberProtocol<'p> {}
+-
+ #[doc(hidden)]
+ pub trait PyNumberRMulProtocolImpl {
+ fn __rmul__() -> Option<PyMethodDef> {
+@@ -1291,8 +1287,6 @@ pub trait PyNumberRMulProtocolImpl {
+ }
+ }
+
+-impl<'p, T> PyNumberRMulProtocolImpl for T where T: PyNumberProtocol<'p> {}
+-
+ #[doc(hidden)]
+ pub trait PyNumberRMatmulProtocolImpl {
+ fn __rmatmul__() -> Option<PyMethodDef> {
+@@ -1300,8 +1294,6 @@ pub trait PyNumberRMatmulProtocolImpl {
+ }
+ }
+
+-impl<'p, T> PyNumberRMatmulProtocolImpl for T where T: PyNumberProtocol<'p> {}
+-
+ #[doc(hidden)]
+ pub trait PyNumberRTruedivProtocolImpl {
+ fn __rtruediv__() -> Option<PyMethodDef> {
+@@ -1309,8 +1301,6 @@ pub trait PyNumberRTruedivProtocolImpl {
+ }
+ }
+
+-impl<'p, T> PyNumberRTruedivProtocolImpl for T where T: PyNumberProtocol<'p> {}
+-
+ #[doc(hidden)]
+ pub trait PyNumberRFloordivProtocolImpl {
+ fn __rfloordiv__() -> Option<PyMethodDef> {
+@@ -1318,8 +1308,6 @@ pub trait PyNumberRFloordivProtocolImpl {
+ }
+ }
+
+-impl<'p, T> PyNumberRFloordivProtocolImpl for T where T: PyNumberProtocol<'p> {}
+-
+ #[doc(hidden)]
+ pub trait PyNumberRModProtocolImpl {
+ fn __rmod__() -> Option<PyMethodDef> {
+@@ -1327,8 +1315,6 @@ pub trait PyNumberRModProtocolImpl {
+ }
+ }
+
+-impl<'p, T> PyNumberRModProtocolImpl for T where T: PyNumberProtocol<'p> {}
+-
+ #[doc(hidden)]
+ pub trait PyNumberRDivmodProtocolImpl {
+ fn __rdivmod__() -> Option<PyMethodDef> {
+@@ -1336,8 +1322,6 @@ pub trait PyNumberRDivmodProtocolImpl {
+ }
+ }
+
+-impl<'p, T> PyNumberRDivmodProtocolImpl for T where T: PyNumberProtocol<'p> {}
+-
+ #[doc(hidden)]
+ pub trait PyNumberRPowProtocolImpl {
+ fn __rpow__() -> Option<PyMethodDef> {
+@@ -1345,8 +1329,6 @@ pub trait PyNumberRPowProtocolImpl {
+ }
+ }
+
+-impl<'p, T> PyNumberRPowProtocolImpl for T where T: PyNumberProtocol<'p> {}
+-
+ #[doc(hidden)]
+ pub trait PyNumberRLShiftProtocolImpl {
+ fn __rlshift__() -> Option<PyMethodDef> {
+@@ -1354,8 +1336,6 @@ pub trait PyNumberRLShiftProtocolImpl {
+ }
+ }
+
+-impl<'p, T> PyNumberRLShiftProtocolImpl for T where T: PyNumberProtocol<'p> {}
+-
+ #[doc(hidden)]
+ pub trait PyNumberRRShiftProtocolImpl {
+ fn __rrshift__() -> Option<PyMethodDef> {
+@@ -1363,8 +1343,6 @@ pub trait PyNumberRRShiftProtocolImpl {
+ }
+ }
+
+-impl<'p, T> PyNumberRRShiftProtocolImpl for T where T: PyNumberProtocol<'p> {}
+-
+ #[doc(hidden)]
+ pub trait PyNumberRAndProtocolImpl {
+ fn __rand__() -> Option<PyMethodDef> {
+@@ -1372,8 +1350,6 @@ pub trait PyNumberRAndProtocolImpl {
+ }
+ }
+
+-impl<'p, T> PyNumberRAndProtocolImpl for T where T: PyNumberProtocol<'p> {}
+-
+ #[doc(hidden)]
+ pub trait PyNumberRXorProtocolImpl {
+ fn __rxor__() -> Option<PyMethodDef> {
+@@ -1381,8 +1357,6 @@ pub trait PyNumberRXorProtocolImpl {
+ }
+ }
+
+-impl<'p, T> PyNumberRXorProtocolImpl for T where T: PyNumberProtocol<'p> {}
+-
+ #[doc(hidden)]
+ pub trait PyNumberROrProtocolImpl {
+ fn __ror__() -> Option<PyMethodDef> {
+@@ -1390,8 +1364,6 @@ pub trait PyNumberROrProtocolImpl {
+ }
+ }
+
+-impl<'p, T> PyNumberROrProtocolImpl for T where T: PyNumberProtocol<'p> {}
+-
+ pub trait PyNumberNegProtocolImpl {
+ fn nb_negative() -> Option<ffi::unaryfunc> {
+ None
+diff --git a/tests/test_arithmetics.rp b/tests/test_arithmetics.rs
+similarity index 99%
+rename from tests/test_arithmetics.rp
+rename to tests/test_arithmetics.rs
+index 42e378b5c..2fb25adf5 100644
+--- a/tests/test_arithmetics.rp
++++ b/tests/test_arithmetics.rs
+@@ -1,5 +1,3 @@
+-#![feature(specialization)]
+-
+ use pyo3::class::basic::CompareOp;
+ use pyo3::class::*;
+ use pyo3::prelude::*;
+@@ -16,7 +14,6 @@ impl PyNumberProtocol for UnaryArithmetic {
+ fn __neg__(&self) -> PyResult<&'static str> {
+ Ok("neg")
+ }
+-
+ fn __pos__(&self) -> PyResult<&'static str> {
+ Ok("pos")
+ }
diff --git a/srcpkgs/anki/files/pyo3-patches/0019-specialization-ac0158f18c02de6ab9dd9a6b96fd97a935d6f9b5.patch b/srcpkgs/anki/files/pyo3-patches/0019-specialization-ac0158f18c02de6ab9dd9a6b96fd97a935d6f9b5.patch
new file mode 100644
index 00000000000..20781e716f9
--- /dev/null
+++ b/srcpkgs/anki/files/pyo3-patches/0019-specialization-ac0158f18c02de6ab9dd9a6b96fd97a935d6f9b5.patch
@@ -0,0 +1,1321 @@
+From ac0158f18c02de6ab9dd9a6b96fd97a935d6f9b5 Mon Sep 17 00:00:00 2001
+From: Martin Donlon <github-martin@donlons.com>
+Date: Sun, 17 Nov 2019 08:23:49 -0800
+Subject: [PATCH] But default impls into a separate array in defs rather than
+ storing them in the MethodProto
+
+---
+ pyo3-derive-backend/src/defs.rs | 500 ++++++++++++++----
+ pyo3-derive-backend/src/func.rs | 23 -
+ pyo3-derive-backend/src/pyproto.rs | 17 +-
+ .../{test_dict_iter.rp => test_dict_iter.rs} | 0
+ tests/test_dunder.rp | 26 +-
+ 5 files changed, 426 insertions(+), 140 deletions(-)
+ rename tests/{test_dict_iter.rp => test_dict_iter.rs} (100%)
+
+diff --git a/pyo3-derive-backend/src/defs.rs b/pyo3-derive-backend/src/defs.rs
+index d793c9628..f7ac2da01 100644
+--- a/pyo3-derive-backend/src/defs.rs
++++ b/pyo3-derive-backend/src/defs.rs
+@@ -7,6 +7,7 @@ pub struct Proto {
+ pub impl_trait: &'static str,
+ pub methods: &'static [MethodProto],
+ pub py_methods: &'static [PyMethod],
++ pub default_impls: &'static [DefaultImpl],
+ }
+
+ pub struct PyMethod {
+@@ -14,6 +15,11 @@ pub struct PyMethod {
+ pub proto: &'static str,
+ }
+
++pub struct DefaultImpl {
++ pub name: &'static str,
++ pub default: &'static str,
++}
++
+ const OBJECT: Proto = Proto {
+ name: "Object",
+ protocol_trait: "pyo3::class::basic::PyObjectProtocol",
+@@ -24,7 +30,6 @@ const OBJECT: Proto = Proto {
+ arg: "Name",
+ pyres: true,
+ proto: "pyo3::class::basic::PyObjectGetAttrProtocol",
+- default: "pyo3::class::basic::GetAttrProtocolImpl",
+ },
+ MethodProto::Ternary {
+ name: "__setattr__",
+@@ -32,65 +37,49 @@ const OBJECT: Proto = Proto {
+ arg2: "Value",
+ pyres: false,
+ proto: "pyo3::class::basic::PyObjectSetAttrProtocol",
+- default: "pyo3::class::basic::tp_setattro_impl::SetAttr",
+ },
+ MethodProto::Binary {
+ name: "__delattr__",
+ arg: "Name",
+ pyres: true,
+ proto: "pyo3::class::basic::PyObjectDelAttrProtocol",
+- default: "pyo3::class::basic::tp_setattro_impl::DelAttr",
+ },
+ MethodProto::Unary {
+ name: "__str__",
+ pyres: true,
+ proto: "pyo3::class::basic::PyObjectStrProtocol",
+- default: "pyo3::class::basic::StrProtocolImpl",
+ },
+ MethodProto::Unary {
+ name: "__repr__",
+ pyres: true,
+ proto: "pyo3::class::basic::PyObjectReprProtocol",
+- default: "pyo3::class::basic::ReprProtocolImpl",
+ },
+ MethodProto::Binary {
+ name: "__format__",
+ arg: "Format",
+ pyres: true,
+ proto: "pyo3::class::basic::PyObjectFormatProtocol",
+- default: "pyo3::class::basic::FormatProtocolImpl",
+ },
+ MethodProto::Unary {
+ name: "__hash__",
+ pyres: false,
+ proto: "pyo3::class::basic::PyObjectHashProtocol",
+- default: "pyo3::class::basic::HashProtocolImpl",
+ },
+ MethodProto::Unary {
+ name: "__bytes__",
+ pyres: true,
+ proto: "pyo3::class::basic::PyObjectBytesProtocol",
+- default: "pyo3::class::basic::BytesProtocolImpl",
+- },
+- MethodProto::Unary {
+- // MJDFIXME ???
+- name: "__unicode__",
+- pyres: true,
+- proto: "pyo3::class::basic::PyObjectUnicodeProtocol",
+- default: "pyo3::class::basic::UnicodeProtocolImpl",
+ },
+ MethodProto::Unary {
+ name: "__bool__",
+ pyres: false,
+ proto: "pyo3::class::basic::PyObjectBoolProtocol",
+- default: "pyo3::class::basic::BoolProtocolImpl",
+ },
+ MethodProto::Binary {
+ name: "__richcmp__",
+ arg: "Other",
+ pyres: true,
+ proto: "pyo3::class::basic::PyObjectRichcmpProtocol",
+- default: "pyo3::class::basic::RichcmpProtocolImpl",
+ },
+ ],
+ py_methods: &[
+@@ -107,6 +96,52 @@ const OBJECT: Proto = Proto {
+ proto: "pyo3::class::basic::UnicodeProtocolImpl",
+ },
+ ],
++ default_impls: &[
++ DefaultImpl {
++ name: "__getattr__",
++ default: "pyo3::class::basic::GetAttrProtocolImpl",
++ },
++ DefaultImpl {
++ name: "__setattr__",
++ default: "pyo3::class::basic::tp_setattro_impl::SetAttr",
++ },
++ DefaultImpl {
++ name: "__delattr__",
++ default: "pyo3::class::basic::tp_setattro_impl::DelAttr",
++ },
++ DefaultImpl {
++ name: "__str__",
++ default: "pyo3::class::basic::StrProtocolImpl",
++ },
++ DefaultImpl {
++ name: "__repr__",
++ default: "pyo3::class::basic::ReprProtocolImpl",
++ },
++ DefaultImpl {
++ name: "__format__",
++ default: "pyo3::class::basic::FormatProtocolImpl",
++ },
++ DefaultImpl {
++ name: "__hash__",
++ default: "pyo3::class::basic::HashProtocolImpl",
++ },
++ DefaultImpl {
++ name: "__bytes__",
++ default: "pyo3::class::basic::BytesProtocolImpl",
++ },
++ DefaultImpl {
++ name: "__unicode__",
++ default: "pyo3::class::basic::UnicodeProtocolImpl",
++ },
++ DefaultImpl {
++ name: "__bool__",
++ default: "pyo3::class::basic::BoolProtocolImpl",
++ },
++ DefaultImpl {
++ name: "__richcmp__",
++ default: "pyo3::class::basic::RichcmpProtocolImpl",
++ },
++ ],
+ };
+
+ const ASYNC: Proto = Proto {
+@@ -118,25 +153,21 @@ const ASYNC: Proto = Proto {
+ name: "__await__",
+ pyres: true,
+ proto: "pyo3::class::pyasync::PyAsyncAwaitProtocol",
+- default: "pyo3::class::pyasync::PyAsyncAwaitProtocol",
+ },
+ MethodProto::Unary {
+ name: "__aiter__",
+ pyres: true,
+ proto: "pyo3::class::pyasync::PyAsyncAiterProtocol",
+- default: "pyo3::class::pyasync::PyAsyncAiterProtocol",
+ },
+ MethodProto::Unary {
+ name: "__anext__",
+ pyres: true,
+ proto: "pyo3::class::pyasync::PyAsyncAnextProtocol",
+- default: "pyo3::class::pyasync::PyAsyncAnextProtocol",
+ },
+ MethodProto::Unary {
+ name: "__aenter__",
+ pyres: true,
+ proto: "pyo3::class::pyasync::PyAsyncAenterProtocol",
+- default: "pyo3::class::pyasync::PyAsyncAenterProtocol",
+ },
+ MethodProto::Quaternary {
+ name: "__aexit__",
+@@ -144,7 +175,6 @@ const ASYNC: Proto = Proto {
+ arg2: "ExcValue",
+ arg3: "Traceback",
+ proto: "pyo3::class::pyasync::PyAsyncAexitProtocol",
+- default: "pyo3::class::pyasync::PyAsyncAexitProtocol",
+ },
+ ],
+ py_methods: &[
+@@ -157,6 +187,28 @@ const ASYNC: Proto = Proto {
+ proto: "pyo3::class::pyasync::PyAsyncAexitProtocolImpl",
+ },
+ ],
++ default_impls: &[
++ DefaultImpl {
++ name: "__await__",
++ default: "pyo3::class::pyasync::PyAsyncAwaitProtocol",
++ },
++ DefaultImpl {
++ name: "__aiter__",
++ default: "pyo3::class::pyasync::PyAsyncAiterProtocol",
++ },
++ DefaultImpl {
++ name: "__anext__",
++ default: "pyo3::class::pyasync::PyAsyncAnextProtocol",
++ },
++ DefaultImpl {
++ name: "__aenter__",
++ default: "pyo3::class::pyasync::PyAsyncAenterProtocol",
++ },
++ DefaultImpl {
++ name: "__aexit__",
++ default: "pyo3::class::pyasync::PyAsyncAexitProtocol",
++ },
++ ],
+ };
+
+ const BUFFER: Proto = Proto {
+@@ -168,16 +220,24 @@ const BUFFER: Proto = Proto {
+ name: "bf_getbuffer",
+ pyres: false,
+ proto: "pyo3::class::buffer::PyBufferGetBufferProtocol",
+- default: "pyo3::class::buffer::PyBufferGetBufferProtocolImpl",
+ },
+ MethodProto::Unary {
+ name: "bf_releasebuffer",
+ pyres: false,
+ proto: "pyo3::class::buffer::PyBufferReleaseBufferProtocol",
+- default: "pyo3::class::buffer::PyBufferReleaseBufferProtocolImpl",
+ },
+ ],
+ py_methods: &[],
++ default_impls: &[
++ DefaultImpl {
++ name: "bf_getbuffer",
++ default: "pyo3::class::buffer::PyBufferGetBufferProtocolImpl",
++ },
++ DefaultImpl {
++ name: "bf_releasebuffer",
++ default: "pyo3::class::buffer::PyBufferReleaseBufferProtocolImpl",
++ },
++ ],
+ };
+
+ const CONTEXT: Proto = Proto {
+@@ -189,7 +249,6 @@ const CONTEXT: Proto = Proto {
+ name: "__enter__",
+ pyres: true,
+ proto: "pyo3::class::context::PyContextEnterProtocol",
+- default: "pyo3::class::context::PyContextEnterProtocol",
+ },
+ MethodProto::Quaternary {
+ name: "__exit__",
+@@ -197,7 +256,6 @@ const CONTEXT: Proto = Proto {
+ arg2: "ExcValue",
+ arg3: "Traceback",
+ proto: "pyo3::class::context::PyContextExitProtocol",
+- default: "pyo3::class::context::PyContextExitProtocol",
+ },
+ ],
+ py_methods: &[
+@@ -210,6 +268,16 @@ const CONTEXT: Proto = Proto {
+ proto: "pyo3::class::context::PyContextExitProtocolImpl",
+ },
+ ],
++ default_impls: &[
++ DefaultImpl {
++ name: "__enter__",
++ default: "pyo3::class::context::PyContextEnterProtocol",
++ },
++ DefaultImpl {
++ name: "__exit__",
++ default: "pyo3::class::context::PyContextExitProtocol",
++ },
++ ],
+ };
+
+ const GC: Proto = Proto {
+@@ -221,15 +289,23 @@ const GC: Proto = Proto {
+ MethodProto::Free {
+ name: "__traverse__",
+ proto: "pyo3::class::gc::PyGCTraverseProtocol",
+- default: "pyo3::class::gc::PyGCTraverseProtocolImpl",
+ },
+ MethodProto::Free {
+ name: "__clear__",
+ proto: "pyo3::class::gc::PyGCClearProtocol",
+- default: "pyo3::class::gc::PyGCClearProtocolImpl",
+ },
+ ],
+ py_methods: &[],
++ default_impls: &[
++ DefaultImpl {
++ name: "__traverse__",
++ default: "pyo3::class::gc::PyGCTraverseProtocolImpl",
++ },
++ DefaultImpl {
++ name: "__clear__",
++ default: "pyo3::class::gc::PyGCClearProtocolImpl",
++ },
++ ],
+ };
+
+ const DESCR: Proto = Proto {
+@@ -244,7 +320,6 @@ const DESCR: Proto = Proto {
+ arg2: "Owner",
+ pyres: true,
+ proto: "pyo3::class::descr::PyDescrGetProtocol",
+- default: "pyo3::class::descr::PyDescrGetProtocol",
+ },
+ MethodProto::Ternary {
+ name: "__set__",
+@@ -252,21 +327,18 @@ const DESCR: Proto = Proto {
+ arg2: "Value",
+ pyres: true,
+ proto: "pyo3::class::descr::PyDescrSetProtocol",
+- default: "pyo3::class::descr::PyDescrSetProtocol",
+ },
+ MethodProto::Binary {
+ name: "__det__",
+ arg: "Inst",
+ pyres: false,
+ proto: "pyo3::class::descr::PyDescrDelProtocol",
+- default: "pyo3::class::descr::PyDescrDelProtocol",
+ },
+ MethodProto::Binary {
+ name: "__set_name__",
+ arg: "Inst",
+ pyres: false,
+ proto: "pyo3::class::descr::PyDescrSetNameProtocol",
+- default: "pyo3::class::descr::PyDescrSetNameProtocol",
+ },
+ ],
+ py_methods: &[
+@@ -279,6 +351,24 @@ const DESCR: Proto = Proto {
+ proto: "pyo3::class::context::PyDescrNameProtocolImpl",
+ },
+ ],
++ default_impls: &[
++ DefaultImpl {
++ name: "__get__",
++ default: "pyo3::class::descr::PyDescrGetProtocol",
++ },
++ DefaultImpl {
++ name: "__set__",
++ default: "pyo3::class::descr::PyDescrSetProtocol",
++ },
++ DefaultImpl {
++ name: "__det__",
++ default: "pyo3::class::descr::PyDescrDelProtocol",
++ },
++ DefaultImpl {
++ name: "__set_name__",
++ default: "pyo3::class::descr::PyDescrSetNameProtocol",
++ },
++ ],
+ };
+
+ const ITER: Proto = Proto {
+@@ -292,12 +382,20 @@ const ITER: Proto = Proto {
+ name: "__iter__",
+ pyres: true,
+ proto: "pyo3::class::iter::PyIterIterProtocol",
+- default: "pyo3::class::iter::PyIterIterProtocol",
+ },
+ MethodProto::Unary {
+ name: "__next__",
+ pyres: true,
+ proto: "pyo3::class::iter::PyIterNextProtocol",
++ },
++ ],
++ default_impls: &[
++ DefaultImpl {
++ name: "__iter__",
++ default: "pyo3::class::iter::PyIterIterProtocol",
++ },
++ DefaultImpl {
++ name: "__next__",
+ default: "pyo3::class::iter::PyIterNextProtocol",
+ },
+ ],
+@@ -313,14 +411,12 @@ const MAPPING: Proto = Proto {
+ name: "__len__",
+ pyres: false,
+ proto: "pyo3::class::mapping::PyMappingLenProtocol",
+- default: "pyo3::class::mapping::PyMappingLenProtocol",
+ },
+ MethodProto::Binary {
+ name: "__getitem__",
+ arg: "Key",
+ pyres: true,
+ proto: "pyo3::class::mapping::PyMappingGetItemProtocol",
+- default: "pyo3::class::mapping::PyMappingGetItemProtocol",
+ },
+ MethodProto::Ternary {
+ name: "__setitem__",
+@@ -328,33 +424,28 @@ const MAPPING: Proto = Proto {
+ arg2: "Value",
+ pyres: false,
+ proto: "pyo3::class::mapping::PyMappingSetItemProtocol",
+- default: "pyo3::class::mapping::PyMappingSetItemProtocol",
+ },
+ MethodProto::Binary {
+ name: "__delitem__",
+ arg: "Key",
+ pyres: false,
+ proto: "pyo3::class::mapping::PyMappingDelItemProtocol",
+- default: "pyo3::class::mapping::PyMappingDelItemProtocol",
+ },
+ MethodProto::Binary {
+ name: "__contains__",
+ arg: "Value",
+ pyres: false,
+ proto: "pyo3::class::mapping::PyMappingContainsProtocol",
+- default: "pyo3::class::mapping::PyMappingContainsProtocol",
+ },
+ MethodProto::Unary {
+ name: "__reversed__",
+ pyres: true,
+ proto: "pyo3::class::mapping::PyMappingReversedProtocol",
+- default: "pyo3::class::mapping::PyMappingReversedProtocol",
+ },
+ MethodProto::Unary {
+ name: "__iter__",
+ pyres: true,
+ proto: "pyo3::class::mapping::PyMappingIterProtocol",
+- default: "pyo3::class::mapping::PyMappingIterProtocol",
+ },
+ ],
+ py_methods: &[
+@@ -371,6 +462,36 @@ const MAPPING: Proto = Proto {
+ proto: "pyo3::class::mapping::PyMappingReversedProtocolImpl",
+ },
+ ],
++ default_impls: &[
++ DefaultImpl {
++ name: "__len__",
++ default: "pyo3::class::mapping::PyMappingLenProtocolImpl",
++ },
++ DefaultImpl {
++ name: "__getitem__",
++ default: "pyo3::class::mapping::PyMappingGetItemProtocolImpl",
++ },
++ DefaultImpl {
++ name: "__setitem__",
++ default: "pyo3::class::mapping::PyMappingSetItemProtocolImpl",
++ },
++ DefaultImpl {
++ name: "__delitem__",
++ default: "pyo3::class::mapping::PyMappingDelItemProtocolNotImpl",
++ },
++ DefaultImpl {
++ name: "__contains__",
++ default: "pyo3::class::mapping::PyMappingContainsProtocolImpl",
++ },
++ DefaultImpl {
++ name: "__reversed__",
++ default: "pyo3::class::mapping::PyMappingReversedProtocolImpl",
++ },
++ DefaultImpl {
++ name: "__iter__",
++ default: "pyo3::class::mapping::PyMappingIterProtocolImpl",
++ },
++ ],
+ };
+
+ const SEQ: Proto = Proto {
+@@ -383,14 +504,12 @@ const SEQ: Proto = Proto {
+ name: "__len__",
+ pyres: false,
+ proto: "pyo3::class::sequence::PySequenceLenProtocol",
+- default: "pyo3::class::sequence::PySequenceLenProtocolImpl",
+ },
+ MethodProto::Binary {
+ name: "__getitem__",
+ arg: "Index",
+ pyres: true,
+ proto: "pyo3::class::sequence::PySequenceGetItemProtocol",
+- default: "pyo3::class::sequence::PySequenceGetItemProtocolImpl",
+ },
+ MethodProto::Ternary {
+ name: "__setitem__",
+@@ -398,52 +517,83 @@ const SEQ: Proto = Proto {
+ arg2: "Value",
+ pyres: false,
+ proto: "pyo3::class::sequence::PySequenceSetItemProtocol",
+- default: "pyo3::class::sequence::PySequenceSetItemProtocolImpl",
+ },
+ MethodProto::Binary {
+ name: "__delitem__",
+ arg: "Index",
+ pyres: false,
+ proto: "pyo3::class::sequence::PySequenceDelItemProtocol",
+- default: "pyo3::class::sequence::PySequenceDelItemProtocolImpl",
+ },
+ MethodProto::Binary {
+ name: "__contains__",
+ arg: "Item",
+ pyres: false,
+ proto: "pyo3::class::sequence::PySequenceContainsProtocol",
+- default: "pyo3::class::sequence::PySequenceContainsProtocolImpl",
+ },
+ MethodProto::Binary {
+ name: "__concat__",
+ arg: "Other",
+ pyres: true,
+ proto: "pyo3::class::sequence::PySequenceConcatProtocol",
+- default: "pyo3::class::sequence::PySequenceConcatProtocolImpl",
+ },
+ MethodProto::Binary {
+ name: "__repeat__",
+ arg: "Index",
+ pyres: true,
+ proto: "pyo3::class::sequence::PySequenceRepeatProtocol",
+- default: "pyo3::class::sequence::PySequenceRepeatProtocolImpl",
+ },
+ MethodProto::Binary {
+ name: "__inplace_concat__",
+ arg: "Other",
+ pyres: true,
+ proto: "pyo3::class::sequence::PySequenceInplaceConcatProtocol",
+- default: "pyo3::class::sequence::PySequenceInplaceConcatProtocolImpl",
+ },
+ MethodProto::Binary {
+ name: "__inplace_repeat__",
+ arg: "Index",
+ pyres: true,
+ proto: "pyo3::class::sequence::PySequenceInplaceRepeatProtocol",
+- default: "pyo3::class::sequence::PySequenceInplaceRepeatProtocolImpl",
+ },
+ ],
+ py_methods: &[],
++ default_impls: &[
++ DefaultImpl {
++ name: "__len__",
++ default: "pyo3::class::sequence::PySequenceLenProtocolImpl",
++ },
++ DefaultImpl {
++ name: "__getitem__",
++ default: "pyo3::class::sequence::PySequenceGetItemProtocolImpl",
++ },
++ DefaultImpl {
++ name: "__setitem__",
++ default: "pyo3::class::sequence::PySequenceSetItemProtocolImpl",
++ },
++ DefaultImpl {
++ name: "__delitem__",
++ default: "pyo3::class::sequence::PySequenceDelItemProtocolImpl",
++ },
++ DefaultImpl {
++ name: "__contains__",
++ default: "pyo3::class::sequence::PySequenceContainsProtocolImpl",
++ },
++ DefaultImpl {
++ name: "__concat__",
++ default: "pyo3::class::sequence::PySequenceConcatProtocolImpl",
++ },
++ DefaultImpl {
++ name: "__repeat__",
++ default: "pyo3::class::sequence::PySequenceRepeatProtocolImpl",
++ },
++ DefaultImpl {
++ name: "__inplace_concat__",
++ default: "pyo3::class::sequence::PySequenceInplaceConcatProtocolImpl",
++ },
++ DefaultImpl {
++ name: "__inplace_repeat__",
++ default: "pyo3::class::sequence::PySequenceInplaceRepeatProtocolImpl",
++ },
++ ],
+ };
+
+ const NUM: Proto = Proto {
+@@ -458,7 +608,6 @@ const NUM: Proto = Proto {
+ arg2: "Right",
+ pyres: true,
+ proto: "pyo3::class::number::PyNumberAddProtocol",
+- default: "pyo3::class::number::PyNumberAddProtocolImpl",
+ },
+ MethodProto::BinaryS {
+ name: "__sub__",
+@@ -466,7 +615,6 @@ const NUM: Proto = Proto {
+ arg2: "Right",
+ pyres: true,
+ proto: "pyo3::class::number::PyNumberSubProtocol",
+- default: "pyo3::class::number::PyNumberSubProtocolImpl",
+ },
+ MethodProto::BinaryS {
+ name: "__mul__",
+@@ -474,7 +622,6 @@ const NUM: Proto = Proto {
+ arg2: "Right",
+ pyres: true,
+ proto: "pyo3::class::number::PyNumberMulProtocol",
+- default: "pyo3::class::number::PyNumberMulProtocolImpl",
+ },
+ MethodProto::BinaryS {
+ name: "__matmul__",
+@@ -482,7 +629,6 @@ const NUM: Proto = Proto {
+ arg2: "Right",
+ pyres: true,
+ proto: "pyo3::class::number::PyNumberMatmulProtocol",
+- default: "pyo3::class::number::PyNumberMatmulProtocolImpl",
+ },
+ MethodProto::BinaryS {
+ name: "__truediv__",
+@@ -490,7 +636,6 @@ const NUM: Proto = Proto {
+ arg2: "Right",
+ pyres: true,
+ proto: "pyo3::class::number::PyNumberTruedivProtocol",
+- default: "pyo3::class::number::PyNumberTruedivProtocolImpl",
+ },
+ MethodProto::BinaryS {
+ name: "__floordiv__",
+@@ -498,7 +643,6 @@ const NUM: Proto = Proto {
+ arg2: "Right",
+ pyres: true,
+ proto: "pyo3::class::number::PyNumberFloordivProtocol",
+- default: "pyo3::class::number::PyNumberFloordivProtocolImpl",
+ },
+ MethodProto::BinaryS {
+ name: "__mod__",
+@@ -506,7 +650,6 @@ const NUM: Proto = Proto {
+ arg2: "Right",
+ pyres: true,
+ proto: "pyo3::class::number::PyNumberModProtocol",
+- default: "pyo3::class::number::PyNumberModProtocolImpl",
+ },
+ MethodProto::BinaryS {
+ name: "__divmod__",
+@@ -514,7 +657,6 @@ const NUM: Proto = Proto {
+ arg2: "Right",
+ pyres: true,
+ proto: "pyo3::class::number::PyNumberDivmodProtocol",
+- default: "pyo3::class::number::PyNumberDivmodProtocolImpl",
+ },
+ MethodProto::TernaryS {
+ name: "__pow__",
+@@ -523,7 +665,6 @@ const NUM: Proto = Proto {
+ arg3: "Modulo",
+ pyres: true,
+ proto: "pyo3::class::number::PyNumberPowProtocol",
+- default: "pyo3::class::number::PyNumberPowProtocolImpl",
+ },
+ MethodProto::BinaryS {
+ name: "__lshift__",
+@@ -531,7 +672,6 @@ const NUM: Proto = Proto {
+ arg2: "Right",
+ pyres: true,
+ proto: "pyo3::class::number::PyNumberLShiftProtocol",
+- default: "pyo3::class::number::PyNumberLShiftProtocolImpl",
+ },
+ MethodProto::BinaryS {
+ name: "__rshift__",
+@@ -539,7 +679,6 @@ const NUM: Proto = Proto {
+ arg2: "Right",
+ pyres: true,
+ proto: "pyo3::class::number::PyNumberRShiftProtocol",
+- default: "pyo3::class::number::PyNumberRShiftProtocolImpl",
+ },
+ MethodProto::BinaryS {
+ name: "__and__",
+@@ -547,7 +686,6 @@ const NUM: Proto = Proto {
+ arg2: "Right",
+ pyres: true,
+ proto: "pyo3::class::number::PyNumberAndProtocol",
+- default: "pyo3::class::number::PyNumberAndProtocolImpl",
+ },
+ MethodProto::BinaryS {
+ name: "__xor__",
+@@ -555,7 +693,6 @@ const NUM: Proto = Proto {
+ arg2: "Right",
+ pyres: true,
+ proto: "pyo3::class::number::PyNumberXorProtocol",
+- default: "pyo3::class::number::PyNumberXorProtocolImpl",
+ },
+ MethodProto::BinaryS {
+ name: "__or__",
+@@ -563,63 +700,54 @@ const NUM: Proto = Proto {
+ arg2: "Right",
+ pyres: true,
+ proto: "pyo3::class::number::PyNumberOrProtocol",
+- default: "pyo3::class::number::PyNumberOrProtocolImpl",
+ },
+ MethodProto::Binary {
+ name: "__radd__",
+ arg: "Other",
+ pyres: true,
+ proto: "pyo3::class::number::PyNumberRAddProtocol",
+- default: "pyo3::class::number::PyNumberRAddProtocolImpl",
+ },
+ MethodProto::Binary {
+ name: "__rsub__",
+ arg: "Other",
+ pyres: true,
+ proto: "pyo3::class::number::PyNumberRSubProtocol",
+- default: "pyo3::class::number::PyNumberRSubProtocolImpl",
+ },
+ MethodProto::Binary {
+ name: "__rmul__",
+ arg: "Other",
+ pyres: true,
+ proto: "pyo3::class::number::PyNumberRMulProtocol",
+- default: "pyo3::class::number::PyNumberRMulProtocolImpl",
+ },
+ MethodProto::Binary {
+ name: "__rmatmul__",
+ arg: "Other",
+ pyres: true,
+ proto: "pyo3::class::number::PyNumberRMatmulProtocol",
+- default: "pyo3::class::number::PyNumberRMatmulProtocolImpl",
+ },
+ MethodProto::Binary {
+ name: "__rtruediv__",
+ arg: "Other",
+ pyres: true,
+ proto: "pyo3::class::number::PyNumberRTruedivProtocol",
+- default: "pyo3::class::number::PyNumberRTruedivProtocolImpl",
+ },
+ MethodProto::Binary {
+ name: "__rfloordiv__",
+ arg: "Other",
+ pyres: true,
+ proto: "pyo3::class::number::PyNumberRFloordivProtocol",
+- default: "pyo3::class::number::PyNumberRFloordivProtocolImpl",
+ },
+ MethodProto::Binary {
+ name: "__rmod__",
+ arg: "Other",
+ pyres: true,
+ proto: "pyo3::class::number::PyNumberRModProtocol",
+- default: "pyo3::class::number::PyNumberRModProtocolImpl",
+ },
+ MethodProto::Binary {
+ name: "__rdivmod__",
+ arg: "Other",
+ pyres: true,
+ proto: "pyo3::class::number::PyNumberRDivmodProtocol",
+- default: "pyo3::class::number::PyNumberRDivmodProtocolImpl",
+ },
+ MethodProto::Ternary {
+ name: "__rpow__",
+@@ -627,91 +755,78 @@ const NUM: Proto = Proto {
+ arg2: "Modulo",
+ pyres: true,
+ proto: "pyo3::class::number::PyNumberRPowProtocol",
+- default: "pyo3::class::number::PyNumberRPowProtocolImpl",
+ },
+ MethodProto::Binary {
+ name: "__rlshift__",
+ arg: "Other",
+ pyres: true,
+ proto: "pyo3::class::number::PyNumberRLShiftProtocol",
+- default: "pyo3::class::number::PyNumberRLShiftProtocolImpl",
+ },
+ MethodProto::Binary {
+ name: "__rrshift__",
+ arg: "Other",
+ pyres: true,
+ proto: "pyo3::class::number::PyNumberRRShiftProtocol",
+- default: "pyo3::class::number::PyNumberRRShiftProtocolImpl",
+ },
+ MethodProto::Binary {
+ name: "__rand__",
+ arg: "Other",
+ pyres: true,
+ proto: "pyo3::class::number::PyNumberRAndProtocol",
+- default: "pyo3::class::number::PyNumberRAndProtocolImpl",
+ },
+ MethodProto::Binary {
+ name: "__rxor__",
+ arg: "Other",
+ pyres: true,
+ proto: "pyo3::class::number::PyNumberRXorProtocol",
+- default: "pyo3::class::number::PyNumberRXorProtocolImpl",
+ },
+ MethodProto::Binary {
+ name: "__ror__",
+ arg: "Other",
+ pyres: true,
+ proto: "pyo3::class::number::PyNumberROrProtocol",
+- default: "pyo3::class::number::PyNumberROrProtocolImpl",
+ },
+ MethodProto::Binary {
+ name: "__iadd__",
+ arg: "Other",
+ pyres: false,
+ proto: "pyo3::class::number::PyNumberIAddProtocol",
+- default: "pyo3::class::number::PyNumberIAddProtocolImpl",
+ },
+ MethodProto::Binary {
+ name: "__isub__",
+ arg: "Other",
+ pyres: false,
+ proto: "pyo3::class::number::PyNumberISubProtocol",
+- default: "pyo3::class::number::PyNumberISubProtocolImpl",
+ },
+ MethodProto::Binary {
+ name: "__imul__",
+ arg: "Other",
+ pyres: false,
+ proto: "pyo3::class::number::PyNumberIMulProtocol",
+- default: "pyo3::class::number::PyNumberIMulProtocolImpl",
+ },
+ MethodProto::Binary {
+ name: "__imatmul__",
+ arg: "Other",
+ pyres: false,
+ proto: "pyo3::class::number::PyNumberIMatmulProtocol",
+- default: "pyo3::class::number::PyNumberIMatmulProtocolImpl",
+ },
+ MethodProto::Binary {
+ name: "__itruediv__",
+ arg: "Other",
+ pyres: false,
+ proto: "pyo3::class::number::PyNumberITruedivProtocol",
+- default: "pyo3::class::number::PyNumberITruedivProtocolImpl",
+ },
+ MethodProto::Binary {
+ name: "__ifloordiv__",
+ arg: "Other",
+ pyres: false,
+ proto: "pyo3::class::number::PyNumberIFloordivProtocol",
+- default: "pyo3::class::number::PyNumberIFloordivProtocolImpl",
+ },
+ MethodProto::Binary {
+ name: "__imod__",
+ arg: "Other",
+ pyres: false,
+ proto: "pyo3::class::number::PyNumberIModProtocol",
+- default: "pyo3::class::number::PyNumberIModProtocolImpl",
+ },
+ MethodProto::Ternary {
+ name: "__ipow__",
+@@ -719,96 +834,81 @@ const NUM: Proto = Proto {
+ arg2: "Modulo",
+ pyres: false,
+ proto: "pyo3::class::number::PyNumberIPowProtocol",
+- default: "pyo3::class::number::PyNumberIPowProtocolImpl",
+ },
+ MethodProto::Binary {
+ name: "__ilshift__",
+ arg: "Other",
+ pyres: false,
+ proto: "pyo3::class::number::PyNumberILShiftProtocol",
+- default: "pyo3::class::number::PyNumberILShiftProtocolImpl",
+ },
+ MethodProto::Binary {
+ name: "__irshift__",
+ arg: "Other",
+ pyres: false,
+ proto: "pyo3::class::number::PyNumberIRShiftProtocol",
+- default: "pyo3::class::number::PyNumberIRShiftProtocolImpl",
+ },
+ MethodProto::Binary {
+ name: "__iand__",
+ arg: "Other",
+ pyres: false,
+ proto: "pyo3::class::number::PyNumberIAndProtocol",
+- default: "pyo3::class::number::PyNumberIAndProtocolImpl",
+ },
+ MethodProto::Binary {
+ name: "__ixor__",
+ arg: "Other",
+ pyres: false,
+ proto: "pyo3::class::number::PyNumberIXorProtocol",
+- default: "pyo3::class::number::PyNumberIXorProtocolImpl",
+ },
+ MethodProto::Binary {
+ name: "__ior__",
+ arg: "Other",
+ pyres: false,
+ proto: "pyo3::class::number::PyNumberIOrProtocol",
+- default: "pyo3::class::number::PyNumberIOrProtocolImpl",
+ },
+ MethodProto::Unary {
+ name: "__neg__",
+ pyres: true,
+ proto: "pyo3::class::number::PyNumberNegProtocol",
+- default: "pyo3::class::number::PyNumberNegProtocolImpl",
+ },
+ MethodProto::Unary {
+ name: "__pos__",
+ pyres: true,
+ proto: "pyo3::class::number::PyNumberPosProtocol",
+- default: "pyo3::class::number::PyNumberPosProtocolImpl",
+ },
+ MethodProto::Unary {
+ name: "__abs__",
+ pyres: true,
+ proto: "pyo3::class::number::PyNumberAbsProtocol",
+- default: "pyo3::class::number::PyNumberAbsProtocolImpl",
+ },
+ MethodProto::Unary {
+ name: "__invert__",
+ pyres: true,
+ proto: "pyo3::class::number::PyNumberInvertProtocol",
+- default: "pyo3::class::number::PyNumberInvertProtocolImpl",
+ },
+ MethodProto::Unary {
+ name: "__complex__",
+ pyres: true,
+ proto: "pyo3::class::number::PyNumberComplexProtocol",
+- default: "pyo3::class::number::PyNumberComplexProtocolImpl",
+ },
+ MethodProto::Unary {
+ name: "__int__",
+ pyres: true,
+ proto: "pyo3::class::number::PyNumberIntProtocol",
+- default: "pyo3::class::number::PyNumberIntProtocolImpl",
+ },
+ MethodProto::Unary {
+ name: "__float__",
+ pyres: true,
+ proto: "pyo3::class::number::PyNumberFloatProtocol",
+- default: "pyo3::class::number::PyNumberFloatProtocolImpl",
+ },
+ MethodProto::Unary {
+ name: "__round__",
+ pyres: true,
+ proto: "pyo3::class::number::PyNumberRoundProtocol",
+- default: "pyo3::class::number::PyNumberRoundProtocolImpl",
+ },
+ MethodProto::Unary {
+ name: "__index__",
+ pyres: true,
+ proto: "pyo3::class::number::PyNumberIndexProtocol",
+- default: "pyo3::class::number::PyNumberIndexProtocolImpl",
+ },
+ ],
+ py_methods: &[
+@@ -877,6 +977,208 @@ const NUM: Proto = Proto {
+ proto: "pyo3::class::number::PyNumberRoundProtocolImpl",
+ },
+ ],
++ default_impls: &[
++ DefaultImpl {
++ name: "__add__",
++ default: "pyo3::class::number::PyNumberAddProtocolImpl",
++ },
++ DefaultImpl {
++ name: "__sub__",
++ default: "pyo3::class::number::PyNumberSubProtocolImpl",
++ },
++ DefaultImpl {
++ name: "__mul__",
++ default: "pyo3::class::number::PyNumberMulProtocolImpl",
++ },
++ DefaultImpl {
++ name: "__matmul__",
++ default: "pyo3::class::number::PyNumberMatmulProtocolImpl",
++ },
++ DefaultImpl {
++ name: "__truediv__",
++ default: "pyo3::class::number::PyNumberTruedivProtocolImpl",
++ },
++ DefaultImpl {
++ name: "__floordiv__",
++ default: "pyo3::class::number::PyNumberFloordivProtocolImpl",
++ },
++ DefaultImpl {
++ name: "__mod__",
++ default: "pyo3::class::number::PyNumberModProtocolImpl",
++ },
++ DefaultImpl {
++ name: "__divmod__",
++ default: "pyo3::class::number::PyNumberDivmodProtocolImpl",
++ },
++ DefaultImpl {
++ name: "__pow__",
++ default: "pyo3::class::number::PyNumberPowProtocolImpl",
++ },
++ DefaultImpl {
++ name: "__lshift__",
++ default: "pyo3::class::number::PyNumberLShiftProtocolImpl",
++ },
++ DefaultImpl {
++ name: "__rshift__",
++ default: "pyo3::class::number::PyNumberRShiftProtocolImpl",
++ },
++ DefaultImpl {
++ name: "__and__",
++ default: "pyo3::class::number::PyNumberAndProtocolImpl",
++ },
++ DefaultImpl {
++ name: "__xor__",
++ default: "pyo3::class::number::PyNumberXorProtocolImpl",
++ },
++ DefaultImpl {
++ name: "__or__",
++ default: "pyo3::class::number::PyNumberOrProtocolImpl",
++ },
++ DefaultImpl {
++ name: "__radd__",
++ default: "pyo3::class::number::PyNumberRAddProtocolImpl",
++ },
++ DefaultImpl {
++ name: "__rsub__",
++ default: "pyo3::class::number::PyNumberRSubProtocolImpl",
++ },
++ DefaultImpl {
++ name: "__rmul__",
++ default: "pyo3::class::number::PyNumberRMulProtocolImpl",
++ },
++ DefaultImpl {
++ name: "__rmatmul__",
++ default: "pyo3::class::number::PyNumberRMatmulProtocolImpl",
++ },
++ DefaultImpl {
++ name: "__rtruediv__",
++ default: "pyo3::class::number::PyNumberRTruedivProtocolImpl",
++ },
++ DefaultImpl {
++ name: "__rfloordiv__",
++ default: "pyo3::class::number::PyNumberRFloordivProtocolImpl",
++ },
++ DefaultImpl {
++ name: "__rmod__",
++ default: "pyo3::class::number::PyNumberRModProtocolImpl",
++ },
++ DefaultImpl {
++ name: "__rdivmod__",
++ default: "pyo3::class::number::PyNumberRDivmodProtocolImpl",
++ },
++ DefaultImpl {
++ name: "__rpow__",
++ default: "pyo3::class::number::PyNumberRPowProtocolImpl",
++ },
++ DefaultImpl {
++ name: "__rlshift__",
++ default: "pyo3::class::number::PyNumberRLShiftProtocolImpl",
++ },
++ DefaultImpl {
++ name: "__rrshift__",
++ default: "pyo3::class::number::PyNumberRRShiftProtocolImpl",
++ },
++ DefaultImpl {
++ name: "__rand__",
++ default: "pyo3::class::number::PyNumberRAndProtocolImpl",
++ },
++ DefaultImpl {
++ name: "__rxor__",
++ default: "pyo3::class::number::PyNumberRXorProtocolImpl",
++ },
++ DefaultImpl {
++ name: "__ror__",
++ default: "pyo3::class::number::PyNumberROrProtocolImpl",
++ },
++ DefaultImpl {
++ name: "__iadd__",
++ default: "pyo3::class::number::PyNumberIAddProtocolImpl",
++ },
++ DefaultImpl {
++ name: "__isub__",
++ default: "pyo3::class::number::PyNumberISubProtocolImpl",
++ },
++ DefaultImpl {
++ name: "__imul__",
++ default: "pyo3::class::number::PyNumberIMulProtocolImpl",
++ },
++ DefaultImpl {
++ name: "__imatmul__",
++ default: "pyo3::class::number::PyNumberIMatmulProtocolImpl",
++ },
++ DefaultImpl {
++ name: "__itruediv__",
++ default: "pyo3::class::number::PyNumberITruedivProtocolImpl",
++ },
++ DefaultImpl {
++ name: "__ifloordiv__",
++ default: "pyo3::class::number::PyNumberIFloordivProtocolImpl",
++ },
++ DefaultImpl {
++ name: "__imod__",
++ default: "pyo3::class::number::PyNumberIModProtocolImpl",
++ },
++ DefaultImpl {
++ name: "__ipow__",
++ default: "pyo3::class::number::PyNumberIPowProtocolImpl",
++ },
++ DefaultImpl {
++ name: "__ilshift__",
++ default: "pyo3::class::number::PyNumberILShiftProtocolImpl",
++ },
++ DefaultImpl {
++ name: "__irshift__",
++ default: "pyo3::class::number::PyNumberIRShiftProtocolImpl",
++ },
++ DefaultImpl {
++ name: "__iand__",
++ default: "pyo3::class::number::PyNumberIAndProtocolImpl",
++ },
++ DefaultImpl {
++ name: "__ixor__",
++ default: "pyo3::class::number::PyNumberIXorProtocolImpl",
++ },
++ DefaultImpl {
++ name: "__ior__",
++ default: "pyo3::class::number::PyNumberIOrProtocolImpl",
++ },
++ DefaultImpl {
++ name: "__neg__",
++ default: "pyo3::class::number::PyNumberNegProtocolImpl",
++ },
++ DefaultImpl {
++ name: "__pos__",
++ default: "pyo3::class::number::PyNumberPosProtocolImpl",
++ },
++ DefaultImpl {
++ name: "__abs__",
++ default: "pyo3::class::number::PyNumberAbsProtocolImpl",
++ },
++ DefaultImpl {
++ name: "__invert__",
++ default: "pyo3::class::number::PyNumberInvertProtocolImpl",
++ },
++ DefaultImpl {
++ name: "__complex__",
++ default: "pyo3::class::number::PyNumberComplexProtocolImpl",
++ },
++ DefaultImpl {
++ name: "__int__",
++ default: "pyo3::class::number::PyNumberIntProtocolImpl",
++ },
++ DefaultImpl {
++ name: "__float__",
++ default: "pyo3::class::number::PyNumberFloatProtocolImpl",
++ },
++ DefaultImpl {
++ name: "__round__",
++ default: "pyo3::class::number::PyNumberRoundProtocolImpl",
++ },
++ DefaultImpl {
++ name: "__index__",
++ default: "pyo3::class::number::PyNumberIndexProtocolImpl",
++ },
++ ],
+ };
+
+ const PROTOCOLS: &[Proto] = &[
+diff --git a/pyo3-derive-backend/src/func.rs b/pyo3-derive-backend/src/func.rs
+index ce06716f4..05aede490 100644
+--- a/pyo3-derive-backend/src/func.rs
++++ b/pyo3-derive-backend/src/func.rs
+@@ -12,20 +12,17 @@ pub enum MethodProto {
+ Free {
+ name: &'static str,
+ proto: &'static str,
+- default: &'static str,
+ },
+ Unary {
+ name: &'static str,
+ pyres: bool,
+ proto: &'static str,
+- default: &'static str,
+ },
+ Binary {
+ name: &'static str,
+ arg: &'static str,
+ pyres: bool,
+ proto: &'static str,
+- default: &'static str,
+ },
+ BinaryS {
+ name: &'static str,
+@@ -33,7 +30,6 @@ pub enum MethodProto {
+ arg2: &'static str,
+ pyres: bool,
+ proto: &'static str,
+- default: &'static str,
+ },
+ Ternary {
+ name: &'static str,
+@@ -41,7 +37,6 @@ pub enum MethodProto {
+ arg2: &'static str,
+ pyres: bool,
+ proto: &'static str,
+- default: &'static str,
+ },
+ TernaryS {
+ name: &'static str,
+@@ -50,7 +45,6 @@ pub enum MethodProto {
+ arg3: &'static str,
+ pyres: bool,
+ proto: &'static str,
+- default: &'static str,
+ },
+ Quaternary {
+ name: &'static str,
+@@ -58,7 +52,6 @@ pub enum MethodProto {
+ arg2: &'static str,
+ arg3: &'static str,
+ proto: &'static str,
+- default: &'static str,
+ },
+ }
+
+@@ -88,17 +81,6 @@ impl MethodProto {
+ MethodProto::Quaternary { proto: p, .. } => p,
+ }
+ }
+- pub fn get_default(&self) -> &'static str {
+- match *self {
+- MethodProto::Free { default: d, .. } => d,
+- MethodProto::Unary { default: d, .. } => d,
+- MethodProto::Binary { default: d, .. } => d,
+- MethodProto::BinaryS { default: d, .. } => d,
+- MethodProto::Ternary { default: d, .. } => d,
+- MethodProto::TernaryS { default: d, .. } => d,
+- MethodProto::Quaternary { default: d, .. } => d,
+- }
+- }
+ }
+
+ pub fn impl_method_proto(
+@@ -151,7 +133,6 @@ pub fn impl_method_proto(
+ arg,
+ pyres,
+ proto,
+- default: _,
+ } => {
+ if sig.inputs.len() <= 1 {
+ println!("Not enough arguments for {}", name);
+@@ -197,7 +178,6 @@ pub fn impl_method_proto(
+ arg2,
+ pyres,
+ proto,
+- default: _,
+ } => {
+ if sig.inputs.len() <= 1 {
+ print_err(format!("Not enough arguments {}", name), quote!(sig));
+@@ -247,7 +227,6 @@ pub fn impl_method_proto(
+ arg2,
+ pyres,
+ proto,
+- default: _,
+ } => {
+ if sig.inputs.len() <= 2 {
+ print_err(format!("Not enough arguments {}", name), quote!(sig));
+@@ -301,7 +280,6 @@ pub fn impl_method_proto(
+ arg3,
+ pyres,
+ proto,
+- default: _,
+ } => {
+ if sig.inputs.len() <= 2 {
+ print_err(format!("Not enough arguments {}", name), quote!(sig));
+@@ -358,7 +336,6 @@ pub fn impl_method_proto(
+ arg2,
+ arg3,
+ proto,
+- default: _,
+ } => {
+ if sig.inputs.len() <= 3 {
+ print_err(format!("Not enough arguments {}", name), quote!(sig));
+diff --git a/pyo3-derive-backend/src/pyproto.rs b/pyo3-derive-backend/src/pyproto.rs
+index a73232e1f..807be9052 100644
+--- a/pyo3-derive-backend/src/pyproto.rs
++++ b/pyo3-derive-backend/src/pyproto.rs
+@@ -9,6 +9,8 @@ use proc_macro2::TokenStream;
+ use quote::quote;
+ use quote::ToTokens;
+
++use std::collections::HashSet;
++
+ pub fn build_py_proto(ast: &mut syn::ItemImpl) -> syn::Result<TokenStream> {
+ if let Some((_, ref mut path, _)) = ast.trait_ {
+ let proto = if let Some(ref mut segment) = path.segments.last() {
+@@ -52,6 +54,7 @@ fn impl_proto_impl(
+ ) -> TokenStream {
+ let mut tokens = TokenStream::new();
+ let mut py_methods = Vec::new();
++ let mut implemented = HashSet::new();
+
+ let mut unimpl_methods: Vec<&MethodProto> = proto.methods.iter().collect();
+ let mut unimpl_py_methods: Vec<&defs::PyMethod> = proto.py_methods.iter().collect();
+@@ -59,6 +62,7 @@ fn impl_proto_impl(
+ for iimpl in impls.iter_mut() {
+ if let syn::ImplItem::Method(ref mut met) = iimpl {
+ let method_name = met.sig.ident.to_string();
++ implemented.insert(method_name.clone());
+ // Find the method in unimpl_methods, remove it and implement it
+ unimpl_methods
+ .iter()
+@@ -105,13 +109,18 @@ fn impl_proto_impl(
+ }
+ }
+
+- let default_impls: Vec<_> = unimpl_methods
++ let default_impls: Vec<_> = proto
++ .default_impls
+ .iter()
+- .map(|m| {
+- let proto: syn::Path = syn::parse_str(m.get_default()).unwrap();
+- quote! { impl #proto for #ty {} }
++ .filter_map(|def| match implemented.contains(def.name) {
++ true => None,
++ false => {
++ let proto: syn::Path = syn::parse_str(def.default).unwrap();
++ Some(quote! { impl #proto for #ty {} })
++ }
+ })
+ .collect();
++
+ quote! {
+ #tokens
+
+diff --git a/tests/test_dict_iter.rp b/tests/test_dict_iter.rs
+similarity index 100%
+rename from tests/test_dict_iter.rp
+rename to tests/test_dict_iter.rs
diff --git a/srcpkgs/anki/files/pyo3-patches/0020-remove-nightly-check.patch b/srcpkgs/anki/files/pyo3-patches/0020-remove-nightly-check.patch
new file mode 100644
index 00000000000..a92cfe08a5b
--- /dev/null
+++ b/srcpkgs/anki/files/pyo3-patches/0020-remove-nightly-check.patch
@@ -0,0 +1,17 @@
+--- a/build.rs 2020-06-01 19:27:44.819141296 +1000
++++ b/build.rs 2020-06-01 19:29:51.770147574 +1000
+@@ -539,14 +539,6 @@
+ MIN_VERSION, actual_version
+ )
+ }
+-
+- let actual_date = Date::read().expect("Failed to determine the rustc date");
+- if !actual_date.at_least(MIN_DATE) {
+- panic!(
+- "pyo3 requires at least rustc {}, while the current rustc date is {}",
+- MIN_DATE, actual_date
+- )
+- }
+ }
+
+ fn main() -> Result<(), String> {
diff --git a/srcpkgs/anki/patches/0001-aqt_data-fhs.patch b/srcpkgs/anki/patches/0001-aqt_data-fhs.patch
new file mode 100644
index 00000000000..ac0d29ec082
--- /dev/null
+++ b/srcpkgs/anki/patches/0001-aqt_data-fhs.patch
@@ -0,0 +1,45 @@
+From a0a9ac1aeb8b8678f1102aed81010a901ad8d9e1 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Johannes=20L=C3=B6thberg?= <johannes@kyriasis.com>
+Date: Sun, 29 Mar 2020 06:24:43 +0200
+Subject: [PATCH 1/4] Move aqt_data to sys.prefix/share
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+These files do _not_ belong right under sys.prefix.
+
+Signed-off-by: Johannes Löthberg <johannes@kyriasis.com>
+---
+ qt/aqt/utils.py | 2 +-
+ qt/setup.py | 2 +-
+ 2 files changed, 2 insertions(+), 2 deletions(-)
+
+diff --git qt/aqt/utils.py qt/aqt/utils.py
+index a0e12362..4d8c8c34 100644
+--- qt/aqt/utils.py
++++ qt/aqt/utils.py
+@@ -21,7 +21,7 @@ from aqt.theme import theme_manager
+
+ def aqt_data_folder() -> str:
+ # wheel install?
+- dir = os.path.join(sys.prefix, "aqt_data")
++ dir = os.path.join(sys.prefix,"share", "aqt_data")
+ if not os.path.exists(dir) or not os.listdir(dir):
+ # running in place?
+ dir = os.path.join(os.path.dirname(__file__), "..", "aqt_data")
+diff --git qt/setup.py qt/setup.py
+index 38f4e2b7..bdda3baa 100644
+--- qt/setup.py
++++ qt/setup.py
+@@ -8,7 +8,7 @@ import setuptools
+ def package_files(directory):
+ entries = []
+ for (path, directories, filenames) in os.walk(directory):
+- entries.append((path, [os.path.join(path, f) for f in filenames]))
++ entries.append((os.path.join("share", path), [os.path.join(path, f) for f in filenames]))
+ return entries
+
+
+--
+2.26.2
+
diff --git a/srcpkgs/anki/patches/0002-rust-nightly-fix.patch b/srcpkgs/anki/patches/0002-rust-nightly-fix.patch
new file mode 100644
index 00000000000..3d70aa36aad
--- /dev/null
+++ b/srcpkgs/anki/patches/0002-rust-nightly-fix.patch
@@ -0,0 +1,274 @@
+From fb578a0c2dc391f37de7cb6969c40f34d0de845c Mon Sep 17 00:00:00 2001
+From: Damien Elmes <gpg@ankiweb.net>
+Date: Fri, 24 Apr 2020 13:39:14 +1000
+Subject: [PATCH] switch to owned strings in ParsedTemplate
+
+will make it easier to cache the parsed results in the future,
+and handle field renames & other transformations
+---
+ rslib/src/notetype/cardgen.rs | 6 +-
+ rslib/src/notetype/templates.rs | 2 +-
+ rslib/src/template.rs | 98 +++++++++++++++++----------------
+ 3 files changed, 56 insertions(+), 50 deletions(-)
+
+Backported by fossy to stable. notetype patch is not needed.
+
+diff --git rslib/src/template.rs rslib/src/template.rs
+index 4479899009..ed5fe7e916 100644
+--- rslib/src/template.rs
++++ rslib/src/template.rs
+@@ -147,26 +147,26 @@ fn legacy_tokens(mut data: &str) -> impl Iterator<Item = TemplateResult<Token>>
+ //----------------------------------------
+
+ #[derive(Debug, PartialEq)]
+-enum ParsedNode<'a> {
+- Text(&'a str),
++enum ParsedNode {
++ Text(String),
+ Replacement {
+- key: &'a str,
+- filters: Vec<&'a str>,
++ key: String,
++ filters: Vec<String>,
+ },
+ Conditional {
+- key: &'a str,
+- children: Vec<ParsedNode<'a>>,
++ key: String,
++ children: Vec<ParsedNode>,
+ },
+ NegatedConditional {
+- key: &'a str,
+- children: Vec<ParsedNode<'a>>,
++ key: String,
++ children: Vec<ParsedNode>,
+ },
+ }
+
+ #[derive(Debug)]
+-pub struct ParsedTemplate<'a>(Vec<ParsedNode<'a>>);
++pub struct ParsedTemplate(Vec<ParsedNode>);
+
+-impl ParsedTemplate<'_> {
++impl ParsedTemplate {
+ /// Create a template from the provided text.
+ pub fn from_text(template: &str) -> TemplateResult<ParsedTemplate> {
+ let mut iter = tokens(template);
+@@ -177,26 +177,26 @@ impl ParsedTemplate<'_> {
+ fn parse_inner<'a, I: Iterator<Item = TemplateResult<Token<'a>>>>(
+ iter: &mut I,
+ open_tag: Option<&'a str>,
+-) -> TemplateResult<Vec<ParsedNode<'a>>> {
++) -> TemplateResult<Vec<ParsedNode>> {
+ let mut nodes = vec![];
+
+ while let Some(token) = iter.next() {
+ use Token::*;
+ nodes.push(match token? {
+- Text(t) => ParsedNode::Text(t),
++ Text(t) => ParsedNode::Text(t.into()),
+ Replacement(t) => {
+ let mut it = t.rsplit(':');
+ ParsedNode::Replacement {
+- key: it.next().unwrap(),
+- filters: it.collect(),
++ key: it.next().unwrap().into(),
++ filters: it.map(Into::into).collect(),
+ }
+ }
+ OpenConditional(t) => ParsedNode::Conditional {
+- key: t,
++ key: t.into(),
+ children: parse_inner(iter, Some(t))?,
+ },
+ OpenNegated(t) => ParsedNode::NegatedConditional {
+- key: t,
++ key: t.into(),
+ children: parse_inner(iter, Some(t))?,
+ },
+ CloseConditional(t) => {
+@@ -285,27 +285,27 @@ fn localized_template_error(i18n: &I18n, err: TemplateError) -> String {
+ // Checking if template is empty
+ //----------------------------------------
+
+-impl ParsedTemplate<'_> {
++impl ParsedTemplate {
+ /// true if provided fields are sufficient to render the template
+ pub fn renders_with_fields(&self, nonempty_fields: &HashSet<&str>) -> bool {
+ !template_is_empty(nonempty_fields, &self.0)
+ }
+ }
+
+-fn template_is_empty<'a>(nonempty_fields: &HashSet<&str>, nodes: &[ParsedNode<'a>]) -> bool {
++fn template_is_empty(nonempty_fields: &HashSet<&str>, nodes: &[ParsedNode]) -> bool {
+ use ParsedNode::*;
+ for node in nodes {
+ match node {
+ // ignore normal text
+ Text(_) => (),
+ Replacement { key, .. } => {
+- if nonempty_fields.contains(*key) {
++ if nonempty_fields.contains(key.as_str()) {
+ // a single replacement is enough
+ return false;
+ }
+ }
+ Conditional { key, children } => {
+- if !nonempty_fields.contains(*key) {
++ if !nonempty_fields.contains(key.as_str()) {
+ continue;
+ }
+ if !template_is_empty(nonempty_fields, children) {
+@@ -347,7 +347,7 @@ pub(crate) struct RenderContext<'a> {
+ pub card_ord: u16,
+ }
+
+-impl ParsedTemplate<'_> {
++impl ParsedTemplate {
+ /// Render the template with the provided fields.
+ ///
+ /// Replacements that use only standard filters will become part of
+@@ -373,10 +373,7 @@ fn render_into(
+ Text(text) => {
+ append_str_to_nodes(rendered_nodes, text);
+ }
+- Replacement {
+- key: key @ "FrontSide",
+- ..
+- } => {
++ Replacement { key, .. } if key == "FrontSide" => {
+ // defer FrontSide rendering to Python, as extra
+ // filters may be required
+ rendered_nodes.push(RenderedNode::Replacement {
+@@ -385,27 +382,36 @@ fn render_into(
+ current_text: "".into(),
+ });
+ }
+- Replacement { key: "", filters } if !filters.is_empty() => {
++ Replacement { key, filters } if key == "" && !filters.is_empty() => {
+ // if a filter is provided, we accept an empty field name to
+ // mean 'pass an empty string to the filter, and it will add
+ // its own text'
+ rendered_nodes.push(RenderedNode::Replacement {
+ field_name: "".to_string(),
+ current_text: "".to_string(),
+- filters: filters.iter().map(|&f| f.to_string()).collect(),
++ filters: filters.clone(),
+ })
+ }
+ Replacement { key, filters } => {
+ // apply built in filters if field exists
+- let (text, remaining_filters) = match context.fields.get(key) {
+- Some(text) => apply_filters(text, filters, key, context),
++ let (text, remaining_filters) = match context.fields.get(key.as_str()) {
++ Some(text) => apply_filters(
++ text,
++ filters
++ .iter()
++ .map(|s| s.as_str())
++ .collect::<Vec<_>>()
++ .as_slice(),
++ key,
++ context,
++ ),
+ None => {
+ // unknown field encountered
+ let filters_str = filters
+ .iter()
+ .rev()
+ .cloned()
+- .chain(iter::once(""))
++ .chain(iter::once("".into()))
+ .collect::<Vec<_>>()
+ .join(":");
+ return Err(TemplateError::FieldNotFound {
+@@ -427,12 +433,12 @@ fn render_into(
+ }
+ }
+ Conditional { key, children } => {
+- if context.nonempty_fields.contains(key) {
++ if context.nonempty_fields.contains(key.as_str()) {
+ render_into(rendered_nodes, children.as_ref(), context)?;
+ }
+ }
+ NegatedConditional { key, children } => {
+- if !context.nonempty_fields.contains(key) {
++ if !context.nonempty_fields.contains(key.as_str()) {
+ render_into(rendered_nodes, children.as_ref(), context)?;
+ }
+ }
+@@ -542,7 +548,7 @@ pub enum FieldRequirements {
+ None,
+ }
+
+-impl ParsedTemplate<'_> {
++impl ParsedTemplate {
+ /// Return fields required by template.
+ ///
+ /// This is not able to represent negated expressions or combinations of
+@@ -613,11 +619,11 @@
+ vec![
+- Text("foo "),
++ Text("foo ".into()),
+ Replacement {
+- key: "bar",
++ key: "bar".into(),
+ filters: vec![]
+ },
+- Text(" "),
++ Text(" ".into()),
+ Conditional {
+- key: "baz",
+- children: vec![Text(" quux ")]
++ key: "baz".into(),
++ children: vec![Text(" quux ".into())]
+ }
+ ]
+@@ -630,7 +636,7 @@ mod test {
+ assert_eq!(
+ tmpl.0,
+ vec![NegatedConditional {
+- key: "baz",
++ key: "baz".into(),
+ children: vec![]
+ }]
+ );
+@@ -643,7 +649,7 @@ mod test {
+ assert_eq!(
+ PT::from_text("{{ tag }}").unwrap().0,
+ vec![Replacement {
+- key: "tag",
++ key: "tag".into(),
+ filters: vec![]
+ }]
+ );
+@@ -651,7 +657,7 @@ mod test {
+ // stray closing characters (like in javascript) are ignored
+ assert_eq!(
+ PT::from_text("text }} more").unwrap().0,
+- vec![Text("text }} more")]
++ vec![Text("text }} more".into())]
+ );
+
+ PT::from_text("{{").unwrap_err();
+@@ -737,15 +743,15 @@ mod test {
+ assert_eq!(
+ PT::from_text(input).unwrap().0,
+ vec![
+- Text("\n"),
++ Text("\n".into()),
+ Replacement {
+- key: "Front",
++ key: "Front".into(),
+ filters: vec![]
+ },
+- Text("\n"),
++ Text("\n".into()),
+ Conditional {
+- key: "Back",
+- children: vec![Text("\n")]
++ key: "Back".into(),
++ children: vec![Text("\n".into())]
+ }
+ ]
+ );
diff --git a/srcpkgs/anki/patches/0003-rustc-cross-compile.patch b/srcpkgs/anki/patches/0003-rustc-cross-compile.patch
new file mode 100644
index 00000000000..15239ea4cf1
--- /dev/null
+++ b/srcpkgs/anki/patches/0003-rustc-cross-compile.patch
@@ -0,0 +1,11 @@
+--- rspy/Makefile 2020-05-23 12:02:29.758286838 +1000
++++ rspy/Makefile 2020-05-08 18:17:57.000000000 +1000
+@@ -69,7 +69,7 @@
+ .build/build: $(DEPS)
+ touch ../proto/backend.proto
+ ${BUILD_VARIABLES} \
+- maturin build -i "${PYTHON_FILE}" -o "$(OUTDIR)" $(BUILDFLAGS)
++ maturin build -i "${PYTHON_FILE}" -o "$(OUTDIR)" $(BUILDFLAGS) --target $(RUST_TARGET)
+ touch $@
+
+ check: .build/check
diff --git a/srcpkgs/anki/patches/0004-vendored-deps.patch b/srcpkgs/anki/patches/0004-vendored-deps.patch
new file mode 100644
index 00000000000..7ca936804fc
--- /dev/null
+++ b/srcpkgs/anki/patches/0004-vendored-deps.patch
@@ -0,0 +1,91 @@
+diff -u -r Makefile Makefile
+--- Makefile 2020-05-08 18:17:57.000000000 +1000
++++ Makefile 2020-05-19 18:40:54.345223164 +1000
+@@ -92,7 +92,7 @@
+ fi
+
+ .PHONY: develop
+-develop: pyenv buildhash prepare
++develop: buildhash prepare
+ @set -eu -o pipefail ${SHELLFLAGS}; \
+ . "${ACTIVATE_SCRIPT}"; \
+ for dir in $(DEVEL); do \
+diff -u -r pylib/Makefile pylib/Makefile
+--- pylib/Makefile 2020-05-08 18:17:57.000000000 +1000
++++ pylib/Makefile 2020-05-19 18:50:01.075182994 +1000
+@@ -52,7 +52,7 @@
+ python -m black anki/hooks.py
+ @touch $@
+
+-BUILD_STEPS := .build/vernum .build/run-deps .build/dev-deps .build/py-proto anki/buildinfo.py .build/hooks
++BUILD_STEPS := .build/vernum .build/py-proto anki/buildinfo.py .build/hooks
+
+ # Checking
+ ######################
+diff -u -r qt/Makefile qt/Makefile
+--- qt/Makefile 2020-05-08 18:17:57.000000000 +1000
++++ qt/Makefile 2020-05-19 18:50:17.520181786 +1000
+@@ -64,7 +64,7 @@
+ python -m black aqt/gui_hooks.py
+ @touch $@
+
+-BUILD_STEPS := .build/vernum .build/run-deps .build/dev-deps .build/js .build/ui aqt/buildinfo.py .build/hooks .build/i18n
++BUILD_STEPS := .build/vernum .build/js .build/ui aqt/buildinfo.py .build/hooks .build/i18n
+
+ # Checking
+ ######################
+--- Makefile 2020-05-08 18:17:57.000000000 +1000
++++ Makefile 2020-05-19 19:01:35.602131965 +1000
+@@ -122,7 +122,7 @@
+ @echo "Build complete."
+
+ .PHONY: build-rspy
+-build-rspy: pyenv buildhash
++build-rspy: buildhash
+ @set -eu -o pipefail ${SHELLFLAGS}; \
+ . "${ACTIVATE_SCRIPT}"; \
+ $(SUBMAKE) -C rspy build BUILDFLAGS="$(BUILDFLAGS)"
+--- Makefile 2020-05-19 19:41:44.191955000 +1000
++++ Makefile 2020-05-19 19:42:21.423952264 +1000
+@@ -124,19 +124,16 @@
+ .PHONY: build-rspy
+ build-rspy: buildhash
+ @set -eu -o pipefail ${SHELLFLAGS}; \
+- . "${ACTIVATE_SCRIPT}"; \
+ $(SUBMAKE) -C rspy build BUILDFLAGS="$(BUILDFLAGS)"
+
+ .PHONY: build-pylib
+ build-pylib:
+ @set -eu -o pipefail ${SHELLFLAGS}; \
+- . "${ACTIVATE_SCRIPT}"; \
+ $(SUBMAKE) -C pylib build
+
+ .PHONY: build-qt
+ build-qt:
+ @set -eu -o pipefail ${SHELLFLAGS}; \
+- . "${ACTIVATE_SCRIPT}"; \
+ $(SUBMAKE) -C qt build
+
+ .PHONY: clean
+--- pylib/Makefile 2020-05-22 08:46:14.988607539 +1000
++++ pylib/Makefile 2020-05-22 08:46:38.376605821 +1000
+@@ -41,7 +41,7 @@
+
+ PROTODEPS := $(wildcard ../proto/*.proto)
+
+-.build/py-proto: .build/dev-deps $(PROTODEPS)
++.build/py-proto: $(PROTODEPS)
+ protoc --proto_path=../proto --python_out=anki --mypy_out=anki $(PROTODEPS)
+ perl -i'' -pe 's/from fluent_pb2/from anki.fluent_pb2/' anki/backend_pb2.pyi
+ perl -i'' -pe 's/import fluent_pb2/import anki.fluent_pb2/' anki/backend_pb2.py
+--- rspy/Makefile 2020-05-31 08:59:03.810152342 +1000
++++ rspy/Makefile 2020-05-08 18:17:57.000000000 +1000
+@@ -51,7 +51,7 @@
+
+ develop: .build/develop
+
+-DEPS := .build/tools .build/vernum ../meta/buildhash \
++DEPS := .build/vernum ../meta/buildhash \
+ $(wildcard $(QT_FTL_TEMPLATES)/*.ftl) \
+ $(wildcard $(QT_FTL_LOCALES)/*/*.ftl) \
+ $(shell "${FIND}" ../rslib/src -name '*.rs') $(wildcard ../proto/*) \
diff --git a/srcpkgs/anki/patches/0005-patched-pyo3.patch b/srcpkgs/anki/patches/0005-patched-pyo3.patch
new file mode 100644
index 00000000000..15844cc15fe
--- /dev/null
+++ b/srcpkgs/anki/patches/0005-patched-pyo3.patch
@@ -0,0 +1,11 @@
+--- rspy/Cargo.toml 2020-05-08 18:17:57.000000000 +1000
++++ rspy/Cargo.toml.new 2020-05-30 17:46:26.548157472 +1000
+@@ -12,7 +12,7 @@
+ tokio = "0.2.11"
+
+ [dependencies.pyo3]
+-version = "0.8.0"
++path = "../../pyo3"
+ features = ["extension-module"]
+
+ [lib]
diff --git a/srcpkgs/anki/template b/srcpkgs/anki/template
index 680e008a9d4..f3e777a3395 100644
--- a/srcpkgs/anki/template
+++ b/srcpkgs/anki/template
@@ -1,23 +1,78 @@
# Template file for 'anki'
+#
+# NOTE: This template does use rust stable. It has a rather large
+# pyo3 patchset taken from github.com/wickerwaka/pyo3/removing-specialization
+# which allows it to operate on rust stable. But, it is currently on pyo3
+# 0.8.1. This patchset should ideally be rebased for the new version.
+# Preliminary tests found this would be slightly difficult. Anki dosen't
+# need a newer version.. yet.
+#
pkgname=anki
-version=2.1.15
-revision=2
-archs=noarch
+version=2.1.26
+_pyo3_version=0.8.1
+revision=1
build_style=gnu-makefile
pycompile_dirs="/usr/share/anki/anki /usr/share/anki/aqt"
+hostmakedepends="git python3 rust cargo maturin which protobuf
+ mypy-protobuf-python python3-stringcase black python3-wheel
+ rsync nodejs python3-PyQt5-devel-tools gettext
+ qt5-translations python3-pip strace"
depends="python3-PyQt5-webengine python3-requests python3-SQLAlchemy
python3-PyAudio python3-mpv python3-Markdown python3-send2trash
- python3-BeautifulSoup4 python3-decorator python3-jsonschema"
+ python3-BeautifulSoup4 python3-decorator python3-jsonschema
+ python3-protobuf"
short_desc="Spaced repetition flashcard program"
maintainer="Steve Prybylski <sa.prybylx@gmail.com>"
license="AGPL-3.0-or-later"
homepage="https://apps.ankiweb.net"
changelog="https://apps.ankiweb.net/docs/changes.html"
-distfiles="https://apps.ankiweb.net/downloads/current/anki-${version}-source.tgz"
-checksum=5a53760164c77d619f55107a13099cffe620566a7f610b61b6c4b52487f3bb89
-
+distfiles="https://github.com/ankitects/anki/archive/${version}.tar.gz
+ https://github.com/PyO3/pyo3/archive/v${_pyo3_version}.tar.gz"
+checksum="f5a0c41f3eebe0e77de9d46f2a5cbbe20f7c3a4787f0f02e1d33f298428acbdf
+ 437a5fcb54113da9e2999fb957c8948ca40f4f31081b6e8cf1d798033071eb57"
python_version=3
+post_extract() {
+ # Constant place for 0006-patched-pyo3.patch
+ mv "${XBPS_BUILDDIR}/pyo3-${_pyo3_version}" "${XBPS_BUILDDIR}/pyo3"
+}
+
+post_patch() {
+ # Apply patches for pyo3
+ cd "${XBPS_BUILDDIR}/pyo3"
+ for p in ${FILESDIR}/pyo3-patches/*.patch ; do
+ msg_normal "Applying ${p} to pyo3\n"
+ patch -Np1 -i ${p}
+ done
+}
+
+pre_build() {
+ mkdir -p dist
+ make prepare
+}
+
+do_build() {
+ RUSTFLAGS="-C target-feature=-crt-static" make build
+}
+
+do_install() {
+ pushd pylib
+ python3 setup.py install --prefix=/usr --root=${DESTDIR}
+ popd
+
+ pushd qt
+ python3 setup.py install --prefix=/usr --root=${DESTDIR}
+ popd
+
+ # maturin generates a .whl, this is all we can do
+ PIP_CONFIG_FILE=/dev/null pip3 install --isolated --root=${DESTDIR} --prefix=/usr --ignore-installed --no-deps dist/ankirspy*.whl
+
+ # Copied from arch's PKGBUILD
+ install -Dm755 qt/runanki "${DESTDIR}/usr/bin/anki"
+ install -Dm644 qt/anki.desktop "${DESTDIR}/usr/share/applications/anki.desktop"
+ install -Dm644 qt/anki.png "${DESTDIR}/usr/share/pixmaps/anki.png"
+}
+
post_install() {
vlicense LICENSE
}
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: WIP: anki: update to 2.1.26
2020-05-23 6:18 [PR PATCH] WIP: anki: update to 2.1.26 fosslinux
` (5 preceding siblings ...)
2020-06-01 9:58 ` fosslinux
@ 2020-06-01 9:59 ` fosslinux
2020-06-01 10:05 ` [PR PATCH] [Updated] " fosslinux
` (5 subsequent siblings)
12 siblings, 0 replies; 14+ messages in thread
From: fosslinux @ 2020-06-01 9:59 UTC (permalink / raw)
To: ml
[-- Attachment #1: Type: text/plain, Size: 407 bytes --]
New comment by fosslinux on void-packages repository
https://github.com/void-linux/void-packages/pull/22219#issuecomment-636753232
Comment:
Well, we can hardly have packages on rust nightly, as I have come to believe after a discussion on IRC, and especially not using rustup.
Luckily I found a patchset for pyo3!
So now it builds on rust stable. Now, this is just waiting on rust 1.44 to come out.
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PR PATCH] [Updated] WIP: anki: update to 2.1.26
2020-05-23 6:18 [PR PATCH] WIP: anki: update to 2.1.26 fosslinux
` (6 preceding siblings ...)
2020-06-01 9:59 ` fosslinux
@ 2020-06-01 10:05 ` fosslinux
2020-06-01 10:28 ` fosslinux
` (4 subsequent siblings)
12 siblings, 0 replies; 14+ messages in thread
From: fosslinux @ 2020-06-01 10:05 UTC (permalink / raw)
To: ml
[-- Attachment #1: Type: text/plain, Size: 2264 bytes --]
There is an updated pull request by fosslinux against master on the void-packages repository
https://github.com/fosslinux/void-packages anki-2.1.26
https://github.com/void-linux/void-packages/pull/22219
WIP: anki: update to 2.1.26
This has a wide variety of changes as if you have heard my ranting in #xbps it has turned into a Bad Build System - there is rust (nightly!), nodejs, python, etc etc, no proper install target...
A few things to note:
- python3-mypy is updated as mypy-protobuf needs the new version, otherwise the build failed.
- same thing with python-protobuf, but for anki and at runtime
- maturin is some weird build system at the intersection of rust and python.
- mypy-protobuf-python is what anki uses for binding python and rust together, partly.
- mypy-protobuf-go is the go implementation of mypy-protobuf-python that I thought should be packaged anywway.
- python-stringcase is a new dependency.
- anki is an archd package (not nocross), because the rust code is obviously platform specific.
- anki uses rustup. This is because it and some of its dependencies require archd code (notably pyo3). This is unavoidable, afaict.
Still todo:
- [x] Apply archlinux's aqt_build patch, which stops it from polluting /usr directly (:vomiting_face:)
- [x] Update python3-protobuf - hopefully will fix `AttributeError: module 'google.protobuf.descriptor' has no attribute '_internal_create_key'`.
- [x] Look into travis musl error. https://github.com/rust-lang/rust/issues/40174. Hopefully, using rust 1.44 as the rust version *should* fix this. What a PITA. I understand that this is because it works when I cross-compile to x86_64-musl from x86_64 but we need it to work native build from x86_64-musl for the builders...
- [x] Get off rustup and onto rust stable. Needs either a) pyo3 to work on stable or b) anki to be patched for rust-cpython.
- [ ] Blocked by rust 1.44.
- [ ] Travis wth on i686?
- [x] Make it open.
- [x] More extensive runtime testing.
- [ ] Runtime test on musl.
Questions:
- Is there any problems with removing `arch=nocross`?
- Does the rustup stuff look (somewhat) sane?
- Are the patches sane?
A patch file from https://github.com/void-linux/void-packages/pull/22219.patch is attached
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: github-pr-anki-2.1.26-22219.patch --]
[-- Type: text/x-diff, Size: 330183 bytes --]
From dc49d200c37f20e082261214f30c9f0ec0a316a3 Mon Sep 17 00:00:00 2001
From: fosslinux <fosslinux@aussies.space>
Date: Sat, 23 May 2020 14:33:01 +1000
Subject: [PATCH 1/6] python3-mypy: update to 0.770, claim maintainership
---
srcpkgs/python3-mypy/template | 7 +++----
1 file changed, 3 insertions(+), 4 deletions(-)
diff --git a/srcpkgs/python3-mypy/template b/srcpkgs/python3-mypy/template
index 5d7f93d5772..bde1e7f4be6 100644
--- a/srcpkgs/python3-mypy/template
+++ b/srcpkgs/python3-mypy/template
@@ -1,19 +1,18 @@
# Template file for 'python3-mypy'
pkgname=python3-mypy
-version=0.761
+version=0.770
revision=1
archs=noarch
wrksrc="mypy-${version}"
build_style=python3-module
-pycompile_module="mypy"
hostmakedepends="python3-setuptools"
depends="python3-mypy_extensions python3-typed-ast python3-typing_extensions"
short_desc="Optional static typing for Python3"
-maintainer="Orphaned <orphan@voidlinux.org>"
+maintainer="fosslinux <fosslinux@aussies.space>"
license="MIT"
homepage="https://github.com/python/mypy"
distfiles="${PYPI_SITE}/m/mypy/mypy-${version}.tar.gz"
-checksum=85baab8d74ec601e86134afe2bcccd87820f79d2f8d5798c889507d1088287bf
+checksum=8a627507ef9b307b46a1fea9513d5c98680ba09591253082b4c48697ba05a4ae
post_install() {
vlicense LICENSE
From 7c67feaeffb4ddbdef9fbe1a0459ac5ac5ecc439 Mon Sep 17 00:00:00 2001
From: fosslinux <fosslinux@aussies.space>
Date: Sat, 23 May 2020 14:34:38 +1000
Subject: [PATCH 2/6] New package: maturin-0.8.1
---
.../patches/cross-compile-setup-py.patch | 14 +++++++++++++
srcpkgs/maturin/template | 21 +++++++++++++++++++
2 files changed, 35 insertions(+)
create mode 100644 srcpkgs/maturin/patches/cross-compile-setup-py.patch
create mode 100644 srcpkgs/maturin/template
diff --git a/srcpkgs/maturin/patches/cross-compile-setup-py.patch b/srcpkgs/maturin/patches/cross-compile-setup-py.patch
new file mode 100644
index 00000000000..e57189cb7ab
--- /dev/null
+++ b/srcpkgs/maturin/patches/cross-compile-setup-py.patch
@@ -0,0 +1,14 @@
+--- setup.py 2020-04-30 22:36:01.000000000 +1000
++++ setup.py 2020-05-20 14:31:40.404994499 +1000
+@@ -56,9 +56,9 @@
+ "(https://www.rust-lang.org/tools/install) and try again"
+ )
+ subprocess.check_call(
+- ["cargo", "rustc", "--bin", "maturin", "--", "-C", "link-arg=-s"]
++ ["cargo", "rustc", "--bin", "maturin", "--release", "--target", os.environ["RUST_TARGET"], "--", "-C", "link-arg=-s", "-C", "linker=" + os.environ["CC"].split(" ", 1)[0]]
+ )
+- source = os.path.join(source_dir, "target", "debug", executable_name)
++ source = os.path.join(source_dir, "target", os.environ["RUST_TARGET"], "release", executable_name)
+ # run this after trying to build with cargo (as otherwise this leaves
+ # venv in a bad state: https://github.com/benfred/py-spy/issues/69)
+ install.run(self)
diff --git a/srcpkgs/maturin/template b/srcpkgs/maturin/template
new file mode 100644
index 00000000000..7eba36204f9
--- /dev/null
+++ b/srcpkgs/maturin/template
@@ -0,0 +1,21 @@
+# Template file for 'maturin'
+pkgname=maturin
+version=0.8.1
+revision=1
+build_style=python3-module
+hostmakedepends="cargo python3-setuptools python3-toml"
+makedepends="rust rust-std llvm9"
+short_desc="Build and publish crates with python bindings"
+maintainer="fosslinux <fosslinux@aussies.space>"
+license="Apache-2.0, MIT"
+homepage="https://github.com/PyO3/maturin"
+distfiles="https://github.com/PyO3/maturin/archive/v${version}.tar.gz"
+checksum=b72a9885cda3ba4e53906a43aab101acb790622218ade6405b2ddf1ef1461f8f
+
+post_install() {
+ # Dynamic detection of python version
+ PYTHON_VERSION=$(python3 --version | sed "s/^Python //" | rev | sed "s/^[0-9]*.//" | rev)
+ mkdir -p "${DESTDIR}/usr/lib/python${PYTHON_VERSION}/site-packages/"
+ mv "${DESTDIR}/maturin" "${DESTDIR}/usr/lib/python${PYTHON_VERSION}/site-packages/"
+ vlicense license-mit
+}
From 96de4dbb3c34bf4961ba0c1f601205b1215dc700 Mon Sep 17 00:00:00 2001
From: fosslinux <fosslinux@aussies.space>
Date: Sat, 23 May 2020 14:35:25 +1000
Subject: [PATCH 3/6] New package: mypy-protobuf-python-1.13
---
srcpkgs/mypy-protobuf-python/template | 23 +++++++++++++++++++++++
1 file changed, 23 insertions(+)
create mode 100644 srcpkgs/mypy-protobuf-python/template
diff --git a/srcpkgs/mypy-protobuf-python/template b/srcpkgs/mypy-protobuf-python/template
new file mode 100644
index 00000000000..391d75f0c9e
--- /dev/null
+++ b/srcpkgs/mypy-protobuf-python/template
@@ -0,0 +1,23 @@
+# Template file for 'mypy-protobuf-python'
+#
+# WARNING: THIS TEMPLATE SHOULD BE SYNCRONISED WITH mypy-protobuf-go
+#
+pkgname=mypy-protobuf-python
+version=1.13
+revision=1
+wrksrc="mypy-protobuf-${version}"
+build_wrksrc=python
+build_style=python3-module
+hostmakedepends="python3-setuptools"
+depends="python3-mypy python3-typing_extensions python3-protobuf protobuf"
+short_desc="Generate mypy stubs from protobufs - Python implementation"
+maintainer="fosslinux <fosslinux@aussies.space>"
+license="Apache-2.0"
+homepage="https://github.com/dropbox/mypy-protobuf"
+distfiles="https://github.com/dropbox/mypy-protobuf/archive/v${version}.tar.gz"
+checksum=7d86dfc076f8b51814fbfd3a66998a0b570fd1b82ebeda68ae6728cd538adb74
+
+post_install() {
+ # We are not windows, remove the batch file
+ rm "${DESTDIR}/usr/bin/protoc_gen_mypy.bat"
+}
From aeaa9e6a25d47eedecac921e56d647d93d3f46ad Mon Sep 17 00:00:00 2001
From: fosslinux <fosslinux@aussies.space>
Date: Sat, 23 May 2020 14:35:37 +1000
Subject: [PATCH 4/6] New package: mypy-protobuf-go-1.13
---
.../patches/remote-go-improt.patch | 11 +++++++++++
srcpkgs/mypy-protobuf-go/template | 19 +++++++++++++++++++
2 files changed, 30 insertions(+)
create mode 100644 srcpkgs/mypy-protobuf-go/patches/remote-go-improt.patch
create mode 100644 srcpkgs/mypy-protobuf-go/template
diff --git a/srcpkgs/mypy-protobuf-go/patches/remote-go-improt.patch b/srcpkgs/mypy-protobuf-go/patches/remote-go-improt.patch
new file mode 100644
index 00000000000..300504bc70d
--- /dev/null
+++ b/srcpkgs/mypy-protobuf-go/patches/remote-go-improt.patch
@@ -0,0 +1,11 @@
+--- go/src/protoc-gen-mypy/main.go.orig 2020-05-22 11:58:07.760761664 +1000
++++ go/src/protoc-gen-mypy/main.go 2020-05-22 11:58:00.595762190 +1000
+@@ -6,7 +6,7 @@
+ "sort"
+ "strings"
+
+- "proto/mypy"
++ "github.com/dropbox/mypy-protobuf/go/src/proto/mypy"
+
+ "github.com/gogo/protobuf/proto"
+ "github.com/gogo/protobuf/protoc-gen-gogo/descriptor"
diff --git a/srcpkgs/mypy-protobuf-go/template b/srcpkgs/mypy-protobuf-go/template
new file mode 100644
index 00000000000..8f00e43d8a8
--- /dev/null
+++ b/srcpkgs/mypy-protobuf-go/template
@@ -0,0 +1,19 @@
+# Template file for 'mypy-protobuf-go'
+#
+# WARNING: THIS TEMPLATE SHOULD BE SYNCRONISED WITH mypy-protobuf-python
+#
+pkgname=mypy-protobuf-go
+version=1.13
+revision=1
+wrksrc="mypy-protobuf-${version}"
+build_style=go
+go_import_path="github.com/dropbox/mypy-protobuf"
+go_package="${go_import_path}/go/src/protoc-gen-mypy"
+hostmakedepends="git"
+depends="protobuf"
+short_desc="Generate mypy stubs from protobufs - go implementation"
+maintainer="fosslinux <fosslinux@aussies.space>"
+license="Apache-2.0"
+homepage="https://github.com/dropbox/mypy-protobuf"
+distfiles="https://github.com/dropbox/mypy-protobuf/archive/v${version}.tar.gz"
+checksum=7d86dfc076f8b51814fbfd3a66998a0b570fd1b82ebeda68ae6728cd538adb74
From e6d8f76eeb38c0a55f56ca0c4800d1d6d3c71c75 Mon Sep 17 00:00:00 2001
From: fosslinux <fosslinux@aussies.space>
Date: Sat, 23 May 2020 14:33:36 +1000
Subject: [PATCH 5/6] New package: python-stringcase-1.2.0
---
srcpkgs/python-stringcase/template | 28 ++++++++++++++++++++++++++++
srcpkgs/python3-stringcase | 1 +
2 files changed, 29 insertions(+)
create mode 100644 srcpkgs/python-stringcase/template
create mode 120000 srcpkgs/python3-stringcase
diff --git a/srcpkgs/python-stringcase/template b/srcpkgs/python-stringcase/template
new file mode 100644
index 00000000000..849e677c784
--- /dev/null
+++ b/srcpkgs/python-stringcase/template
@@ -0,0 +1,28 @@
+# Template file for 'python-stringcase'
+pkgname=python-stringcase
+version=1.2.0
+revision=1
+wrksrc="stringcase-${version}"
+build_style=python-module
+hostmakedepends="python-devel python3-devel"
+makedepends="${hostmakedepends}"
+depends="python"
+short_desc="String case converter for Python2"
+maintainer="fosslinux <fosslinux@aussies.space>"
+license="MIT"
+homepage="https://github.com/okunishinishi/python-stringcase"
+distfiles="${PYPI_SITE}/s/stringcase/stringcase-${version}.tar.gz"
+checksum=48a06980661908efe8d9d34eab2b6c13aefa2163b3ced26972902e3bdfd87008
+
+post_install() {
+ vlicense LICENSE
+}
+
+python3-stringcase_package() {
+ depends="python3"
+ short_desc="${short_desc/Python2/Python3}"
+ pkg_install() {
+ vmove usr/lib/python3*
+ vlicense LICENSE
+ }
+}
diff --git a/srcpkgs/python3-stringcase b/srcpkgs/python3-stringcase
new file mode 120000
index 00000000000..53938bd1f0c
--- /dev/null
+++ b/srcpkgs/python3-stringcase
@@ -0,0 +1 @@
+python-stringcase
\ No newline at end of file
From 9fe95f38a28d042f1be3cc542646fddcd21c6c21 Mon Sep 17 00:00:00 2001
From: fosslinux <fosslinux@aussies.space>
Date: Sat, 23 May 2020 14:36:21 +1000
Subject: [PATCH 6/6] anki: update to 2.1.26
Has turned into a Bad Build System. Now uses rust nightly, python
(with bindings!), qt5, nodejs... the list goes on. There are quite
a few hacks and the like.
---
...1da60c6c00fc8cd930efa34113a602a830e2.patch | 118 +
...2423c8e293f843115f617d04213f04f63a77.patch | 134 ++
...13bce9c80b0e7ff37c5317705ce0acf32c15.patch | 1209 ++++++++++
...28e23ab3dab4eaa2277734019f1b8e0210c1.patch | 1978 +++++++++++++++++
...fec729e00355bbd067e5770a9e8e889280cf.patch | 1659 ++++++++++++++
...1da60c6c00fc8cd930efa34113a602a830e2.patch | 69 +
...2948d9147689701a24de2fcdffafc32ebe62.patch | 93 +
...c30b15f467c9f5ab139564be0099fba5b27f.patch | 159 ++
...7c2ad89dad6be5cf454fe0012d9aba9e60b2.patch | 1387 ++++++++++++
...10fcd8932c3d83fe73b07412969cc42ff686.patch | 38 +
...2a4b93b16ba9b7b43a1c73614efbcb6e9814.patch | 732 ++++++
...58f18c02de6ab9dd9a6b96fd97a935d6f9b5.patch | 1321 +++++++++++
.../0020-remove-nightly-check.patch | 17 +
srcpkgs/anki/patches/0001-aqt_data-fhs.patch | 45 +
.../anki/patches/0002-rust-nightly-fix.patch | 274 +++
.../patches/0003-rustc-cross-compile.patch | 11 +
srcpkgs/anki/patches/0004-vendored-deps.patch | 91 +
srcpkgs/anki/patches/0005-patched-pyo3.patch | 11 +
srcpkgs/anki/template | 69 +-
19 files changed, 9408 insertions(+), 7 deletions(-)
create mode 100644 srcpkgs/anki/files/pyo3-patches/0001-stub-tests-b0561da60c6c00fc8cd930efa34113a602a830e2.patch
create mode 100644 srcpkgs/anki/files/pyo3-patches/0002-sequence-prepatch-d57f2423c8e293f843115f617d04213f04f63a77.patch
create mode 100644 srcpkgs/anki/files/pyo3-patches/0010-specialization-cb1313bce9c80b0e7ff37c5317705ce0acf32c15.patch
create mode 100644 srcpkgs/anki/files/pyo3-patches/0011-specialization-89c028e23ab3dab4eaa2277734019f1b8e0210c1.patch
create mode 100644 srcpkgs/anki/files/pyo3-patches/0012-specialization-2f4dfec729e00355bbd067e5770a9e8e889280cf.patch
create mode 100644 srcpkgs/anki/files/pyo3-patches/0013-specialization-b0561da60c6c00fc8cd930efa34113a602a830e2.patch
create mode 100644 srcpkgs/anki/files/pyo3-patches/0014-specialization-c7e52948d9147689701a24de2fcdffafc32ebe62.patch
create mode 100644 srcpkgs/anki/files/pyo3-patches/0015-specialization-81f2c30b15f467c9f5ab139564be0099fba5b27f.patch
create mode 100644 srcpkgs/anki/files/pyo3-patches/0016-specialization-eb617c2ad89dad6be5cf454fe0012d9aba9e60b2.patch
create mode 100644 srcpkgs/anki/files/pyo3-patches/0017-specialization-c27d10fcd8932c3d83fe73b07412969cc42ff686.patch
create mode 100644 srcpkgs/anki/files/pyo3-patches/0018-specialization-d6102a4b93b16ba9b7b43a1c73614efbcb6e9814.patch
create mode 100644 srcpkgs/anki/files/pyo3-patches/0019-specialization-ac0158f18c02de6ab9dd9a6b96fd97a935d6f9b5.patch
create mode 100644 srcpkgs/anki/files/pyo3-patches/0020-remove-nightly-check.patch
create mode 100644 srcpkgs/anki/patches/0001-aqt_data-fhs.patch
create mode 100644 srcpkgs/anki/patches/0002-rust-nightly-fix.patch
create mode 100644 srcpkgs/anki/patches/0003-rustc-cross-compile.patch
create mode 100644 srcpkgs/anki/patches/0004-vendored-deps.patch
create mode 100644 srcpkgs/anki/patches/0005-patched-pyo3.patch
diff --git a/srcpkgs/anki/files/pyo3-patches/0001-stub-tests-b0561da60c6c00fc8cd930efa34113a602a830e2.patch b/srcpkgs/anki/files/pyo3-patches/0001-stub-tests-b0561da60c6c00fc8cd930efa34113a602a830e2.patch
new file mode 100644
index 00000000000..5a3f02afe94
--- /dev/null
+++ b/srcpkgs/anki/files/pyo3-patches/0001-stub-tests-b0561da60c6c00fc8cd930efa34113a602a830e2.patch
@@ -0,0 +1,118 @@
+From b0561da60c6c00fc8cd930efa34113a602a830e2 Mon Sep 17 00:00:00 2001
+From: Donlon <mdonlon@treyarch.com>
+Date: Wed, 30 Oct 2019 07:02:06 -0700
+Subject: [PATCH] Stubbed out a bunch of tests
+
+---
+ .../{test_arithmetics.rs => test_arithmetics.rp} | 0
+ ...uffer_protocol.rs => test_buffer_protocol.rp} | 0
+ tests/{test_bytes.rs => test_bytes.rp} | 0
+ tests/{test_class_new.rs => test_class_new.rp} | 0
+ ...st_compile_error.rs => test_compile_error.rp} | 0
+ tests/{test_datetime.rs => test_datetime.rp} | 0
+ tests/{test_dict_iter.rs => test_dict_iter.rp} | 0
+ tests/{test_dunder.rs => test_dunder.rp} | 0
+ tests/{test_exceptions.rs => test_exceptions.rp} | 0
+ tests/{test_gc.rs => test_gc.rp} | 0
+ ...st_getter_setter.rs => test_getter_setter.rp} | 0
+ .../{test_inheritance.rs => test_inheritance.rp} | 0
+ tests/{test_methods.rs => test_methods.rp} | 0
+ tests/{test_module.rs => test_module.rp} | 0
+ tests/{test_pyself.rs => test_pyself.rp} | 0
+ tests/{test_sequence.rs => test_sequence.rp} | 0
+ tests/{test_string.rs => test_string.rp} | 0
+ ...e_arguments.rs => test_variable_arguments.rp} | 0
+ tests/{test_various.rs => test_various.rp} | 0
+ rename tests/{test_arithmetics.rs => test_arithmetics.rp} (100%)
+ mode change 100755 => 100644
+ rename tests/{test_buffer_protocol.rs => test_buffer_protocol.rp} (100%)
+ rename tests/{test_bytes.rs => test_bytes.rp} (100%)
+ rename tests/{test_class_new.rs => test_class_new.rp} (100%)
+ rename tests/{test_compile_error.rs => test_compile_error.rp} (100%)
+ mode change 100755 => 100644
+ rename tests/{test_datetime.rs => test_datetime.rp} (100%)
+ rename tests/{test_dict_iter.rs => test_dict_iter.rp} (100%)
+ rename tests/{test_dunder.rs => test_dunder.rp} (100%)
+ mode change 100755 => 100644
+ rename tests/{test_exceptions.rs => test_exceptions.rp} (100%)
+ rename tests/{test_gc.rs => test_gc.rp} (100%)
+ rename tests/{test_getter_setter.rs => test_getter_setter.rp} (100%)
+ rename tests/{test_inheritance.rs => test_inheritance.rp} (100%)
+ rename tests/{test_methods.rs => test_methods.rp} (100%)
+ rename tests/{test_module.rs => test_module.rp} (100%)
+ rename tests/{test_pyself.rs => test_pyself.rp} (100%)
+ rename tests/{test_sequence.rs => test_sequence.rp} (100%)
+ rename tests/{test_string.rs => test_string.rp} (100%)
+ rename tests/{test_variable_arguments.rs => test_variable_arguments.rp} (100%)
+ rename tests/{test_various.rs => test_various.rp} (100%)
+
+diff --git a/tests/test_arithmetics.rs b/tests/test_arithmetics.rp
+old mode 100755
+new mode 100644
+similarity index 100%
+rename from tests/test_arithmetics.rs
+rename to tests/test_arithmetics.rp
+diff --git a/tests/test_buffer_protocol.rs b/tests/test_buffer_protocol.rp
+similarity index 100%
+rename from tests/test_buffer_protocol.rs
+rename to tests/test_buffer_protocol.rp
+diff --git a/tests/test_compile_error.rs b/tests/test_compile_error.rp
+old mode 100755
+new mode 100644
+similarity index 100%
+rename from tests/test_compile_error.rs
+rename to tests/test_compile_error.rp
+diff --git a/tests/test_datetime.rs b/tests/test_datetime.rp
+similarity index 100%
+rename from tests/test_datetime.rs
+rename to tests/test_datetime.rp
+diff --git a/tests/test_dict_iter.rs b/tests/test_dict_iter.rp
+similarity index 100%
+rename from tests/test_dict_iter.rs
+rename to tests/test_dict_iter.rp
+diff --git a/tests/test_dunder.rs b/tests/test_dunder.rp
+old mode 100755
+new mode 100644
+similarity index 100%
+rename from tests/test_dunder.rs
+rename to tests/test_dunder.rp
+diff --git a/tests/test_exceptions.rs b/tests/test_exceptions.rp
+similarity index 100%
+rename from tests/test_exceptions.rs
+rename to tests/test_exceptions.rp
+diff --git a/tests/test_gc.rs b/tests/test_gc.rp
+similarity index 100%
+rename from tests/test_gc.rs
+rename to tests/test_gc.rp
+diff --git a/tests/test_getter_setter.rs b/tests/test_getter_setter.rp
+similarity index 100%
+rename from tests/test_getter_setter.rs
+rename to tests/test_getter_setter.rp
+diff --git a/tests/test_inheritance.rs b/tests/test_inheritance.rp
+similarity index 100%
+rename from tests/test_inheritance.rs
+rename to tests/test_inheritance.rp
+diff --git a/tests/test_methods.rs b/tests/test_methods.rp
+similarity index 100%
+rename from tests/test_methods.rs
+rename to tests/test_methods.rp
+diff --git a/tests/test_module.rs b/tests/test_module.rp
+similarity index 100%
+rename from tests/test_module.rs
+rename to tests/test_module.rp
+diff --git a/tests/test_pyself.rs b/tests/test_pyself.rp
+similarity index 100%
+rename from tests/test_pyself.rs
+rename to tests/test_pyself.rp
+diff --git a/tests/test_sequence.rs b/tests/test_sequence.rp
+similarity index 100%
+rename from tests/test_sequence.rs
+rename to tests/test_sequence.rp
+diff --git a/tests/test_variable_arguments.rs b/tests/test_variable_arguments.rp
+similarity index 100%
+rename from tests/test_variable_arguments.rs
+rename to tests/test_variable_arguments.rp
+diff --git a/tests/test_various.rs b/tests/test_various.rp
+similarity index 100%
+rename from tests/test_various.rs
+rename to tests/test_various.rp
diff --git a/srcpkgs/anki/files/pyo3-patches/0002-sequence-prepatch-d57f2423c8e293f843115f617d04213f04f63a77.patch b/srcpkgs/anki/files/pyo3-patches/0002-sequence-prepatch-d57f2423c8e293f843115f617d04213f04f63a77.patch
new file mode 100644
index 00000000000..957690f295a
--- /dev/null
+++ b/srcpkgs/anki/files/pyo3-patches/0002-sequence-prepatch-d57f2423c8e293f843115f617d04213f04f63a77.patch
@@ -0,0 +1,134 @@
+diff --git a/src/class/sequence.rs b/src/class/sequence.rs
+index 0f9ca44b..5414704a 100644
+--- a/src/class/sequence.rs
++++ b/src/class/sequence.rs
+@@ -212,60 +212,6 @@ where
+ }
+ }
+
+-trait PySequenceSetItemProtocolImpl {
+- fn sq_ass_item() -> Option<ffi::ssizeobjargproc>;
+-}
+-
+-impl<'p, T> PySequenceSetItemProtocolImpl for T
+-where
+- T: PySequenceProtocol<'p>,
+-{
+- default fn sq_ass_item() -> Option<ffi::ssizeobjargproc> {
+- None
+- }
+-}
+-
+-impl<T> PySequenceSetItemProtocolImpl for T
+-where
+- T: for<'p> PySequenceSetItemProtocol<'p>,
+-{
+- fn sq_ass_item() -> Option<ffi::ssizeobjargproc> {
+- unsafe extern "C" fn wrap<T>(
+- slf: *mut ffi::PyObject,
+- key: ffi::Py_ssize_t,
+- value: *mut ffi::PyObject,
+- ) -> c_int
+- where
+- T: for<'p> PySequenceSetItemProtocol<'p>,
+- {
+- let py = Python::assume_gil_acquired();
+- let _pool = crate::GILPool::new(py);
+- let slf = py.mut_from_borrowed_ptr::<T>(slf);
+-
+- let result = if value.is_null() {
+- Err(PyErr::new::<exceptions::NotImplementedError, _>(format!(
+- "Item deletion not supported by {:?}",
+- stringify!(T)
+- )))
+- } else {
+- let value = py.from_borrowed_ptr::<PyAny>(value);
+- match value.extract() {
+- Ok(value) => slf.__setitem__(key.into(), value).into(),
+- Err(e) => Err(e),
+- }
+- };
+- match result {
+- Ok(_) => 0,
+- Err(e) => {
+- e.restore(py);
+- -1
+- }
+- }
+- }
+- Some(wrap::<T>)
+- }
+-}
+-
+ /// It can be possible to delete and set items (PySequenceSetItemProtocol and
+ /// PySequenceDelItemProtocol implemented), only to delete (PySequenceDelItemProtocol implemented)
+ /// or no deleting or setting is possible
+@@ -286,11 +232,68 @@ mod sq_ass_item_impl {
+ Some(del_set_item)
+ } else if let Some(del_item) = T::del_item() {
+ Some(del_item)
++ } else if let Some(set_item) = T::set_item() {
++ Some(set_item)
+ } else {
+ None
+ }
+ }
+
++ trait SetItem {
++ fn set_item() -> Option<ffi::ssizeobjargproc>;
++ }
++
++ impl<'p, T> SetItem for T
++ where
++ T: PySequenceProtocol<'p>,
++ {
++ default fn set_item() -> Option<ffi::ssizeobjargproc> {
++ None
++ }
++ }
++
++ impl<T> SetItem for T
++ where
++ T: for<'p> PySequenceSetItemProtocol<'p>,
++ {
++ fn set_item() -> Option<ffi::ssizeobjargproc> {
++ unsafe extern "C" fn wrap<T>(
++ slf: *mut ffi::PyObject,
++ key: ffi::Py_ssize_t,
++ value: *mut ffi::PyObject,
++ ) -> c_int
++ where
++ T: for<'p> PySequenceSetItemProtocol<'p>,
++ {
++ let py = Python::assume_gil_acquired();
++ let _pool = crate::GILPool::new(py);
++ let slf = py.mut_from_borrowed_ptr::<T>(slf);
++
++ let result = if value.is_null() {
++ Err(PyErr::new::<exceptions::NotImplementedError, _>(format!(
++ "Item deletion is not supported by {:?}",
++ stringify!(T)
++ )))
++ } else {
++ let value = py.from_borrowed_ptr::<PyAny>(value);
++ match value.extract() {
++ Ok(value) => slf.__setitem__(key.into(), value).into(),
++ Err(e) => Err(e),
++ }
++ };
++
++ match result {
++ Ok(_) => 0,
++ Err(e) => {
++ e.restore(py);
++ -1
++ }
++ }
++ }
++ Some(wrap::<T>)
++ }
++ }
++
+ trait DelItem {
+ fn del_item() -> Option<ffi::ssizeobjargproc>;
+ }
diff --git a/srcpkgs/anki/files/pyo3-patches/0010-specialization-cb1313bce9c80b0e7ff37c5317705ce0acf32c15.patch b/srcpkgs/anki/files/pyo3-patches/0010-specialization-cb1313bce9c80b0e7ff37c5317705ce0acf32c15.patch
new file mode 100644
index 00000000000..53cf0172ba2
--- /dev/null
+++ b/srcpkgs/anki/files/pyo3-patches/0010-specialization-cb1313bce9c80b0e7ff37c5317705ce0acf32c15.patch
@@ -0,0 +1,1209 @@
+From cb1313bce9c80b0e7ff37c5317705ce0acf32c15 Mon Sep 17 00:00:00 2001
+From: Martin Donlon <github-martin@donlons.com>
+Date: Fri, 25 Oct 2019 20:51:08 -0700
+Subject: [PATCH] Revert "Run `cargo fmt` on source code and update
+ `CHANGELOG.md`"
+
+This reverts commit 33bf37d3d8ca08d3af39de22547e32e7c8eb0f54.
+---
+ CHANGELOG.md | 1 -
+ pyo3-derive-backend/src/pymethod.rs | 6 +-
+ src/class/basic.rs | 55 ++-----
+ src/class/buffer.rs | 5 +-
+ src/class/context.rs | 10 +-
+ src/class/descr.rs | 10 +-
+ src/class/gc.rs | 10 +-
+ src/class/iter.rs | 10 +-
+ src/class/mapping.rs | 40 +----
+ src/class/number.rs | 245 ++++++----------------------
+ src/class/pyasync.rs | 25 +--
+ src/class/sequence.rs | 45 +----
+ src/conversion.rs | 5 +-
+ 13 files changed, 95 insertions(+), 372 deletions(-)
+
+diff --git a/CHANGELOG.md b/CHANGELOG.md
+index a3aff9b31..482e9b01d 100644
+--- a/CHANGELOG.md
++++ b/CHANGELOG.md
+@@ -27,7 +27,6 @@ and `PyString::to_string_lossy` [#642](https://github.com/PyO3/pyo3/pull/642).
+ ### Fixed
+
+ * Make sure the right Python interpreter is used in OSX builds. [#604](https://github.com/PyO3/pyo3/pull/604)
+- * Patch specialization being broken by Rust 1.40. [#614](https://github.com/PyO3/pyo3/issues/614)
+ * Fix a segfault around PyErr. [#597](https://github.com/PyO3/pyo3/pull/597)
+
+ ## [0.8.0] - 2018-09-05
+diff --git a/pyo3-derive-backend/src/pymethod.rs b/pyo3-derive-backend/src/pymethod.rs
+index 2f561cb9d..8c867a567 100644
+--- a/pyo3-derive-backend/src/pymethod.rs
++++ b/pyo3-derive-backend/src/pymethod.rs
+@@ -38,7 +38,7 @@ pub fn gen_py_method(
+ return Err(syn::Error::new_spanned(
+ spec.args[0].ty,
+ "Getter function can only have one argument of type pyo3::Python!",
+- ));
++ ))
+ }
+ };
+ impl_py_getter_def(name, doc, getter, &impl_wrap_getter(cls, name, takes_py))
+@@ -60,10 +60,10 @@ fn check_generic(name: &syn::Ident, sig: &syn::Signature) -> syn::Result<()> {
+ match param {
+ syn::GenericParam::Lifetime(_) => {}
+ syn::GenericParam::Type(_) => {
+- return Err(syn::Error::new_spanned(param, err_msg("type")));
++ return Err(syn::Error::new_spanned(param, err_msg("type")))
+ }
+ syn::GenericParam::Const(_) => {
+- return Err(syn::Error::new_spanned(param, err_msg("const")));
++ return Err(syn::Error::new_spanned(param, err_msg("const")))
+ }
+ }
+ }
+diff --git a/src/class/basic.rs b/src/class/basic.rs
+index 8c670bf82..29e19871f 100644
+--- a/src/class/basic.rs
++++ b/src/class/basic.rs
+@@ -202,10 +202,7 @@ trait GetAttrProtocolImpl {
+ fn tp_getattro() -> Option<ffi::binaryfunc>;
+ }
+
+-impl<'p, T> GetAttrProtocolImpl for T
+-where
+- T: PyObjectProtocol<'p>,
+-{
++impl<'p, T> GetAttrProtocolImpl for T where T: PyObjectProtocol<'p> {
+ default fn tp_getattro() -> Option<ffi::binaryfunc> {
+ None
+ }
+@@ -299,10 +296,7 @@ mod tp_setattro_impl {
+ fn del_attr() -> Option<ffi::setattrofunc>;
+ }
+
+- impl<'p, T> DelAttr for T
+- where
+- T: PyObjectProtocol<'p>,
+- {
++ impl<'p, T> DelAttr for T where T: PyObjectProtocol<'p> {
+ default fn del_attr() -> Option<ffi::setattrofunc> {
+ None
+ }
+@@ -321,10 +315,7 @@ mod tp_setattro_impl {
+ fn set_del_attr() -> Option<ffi::setattrofunc>;
+ }
+
+- impl<'p, T> SetDelAttr for T
+- where
+- T: PyObjectProtocol<'p>,
+- {
++ impl<'p, T> SetDelAttr for T where T: PyObjectProtocol<'p> {
+ default fn set_del_attr() -> Option<ffi::setattrofunc> {
+ None
+ }
+@@ -349,10 +340,7 @@ mod tp_setattro_impl {
+ trait StrProtocolImpl {
+ fn tp_str() -> Option<ffi::unaryfunc>;
+ }
+-impl<'p, T> StrProtocolImpl for T
+-where
+- T: PyObjectProtocol<'p>,
+-{
++impl<'p, T> StrProtocolImpl for T where T: PyObjectProtocol<'p> {
+ default fn tp_str() -> Option<ffi::unaryfunc> {
+ None
+ }
+@@ -374,10 +362,7 @@ where
+ trait ReprProtocolImpl {
+ fn tp_repr() -> Option<ffi::unaryfunc>;
+ }
+-impl<'p, T> ReprProtocolImpl for T
+-where
+- T: PyObjectProtocol<'p>,
+-{
++impl<'p, T> ReprProtocolImpl for T where T: PyObjectProtocol<'p> {
+ default fn tp_repr() -> Option<ffi::unaryfunc> {
+ None
+ }
+@@ -400,10 +385,7 @@ where
+ pub trait FormatProtocolImpl {
+ fn __format__() -> Option<PyMethodDef>;
+ }
+-impl<'p, T> FormatProtocolImpl for T
+-where
+- T: PyObjectProtocol<'p>,
+-{
++impl<'p, T> FormatProtocolImpl for T where T: PyObjectProtocol<'p> {
+ default fn __format__() -> Option<PyMethodDef> {
+ None
+ }
+@@ -413,10 +395,7 @@ where
+ pub trait BytesProtocolImpl {
+ fn __bytes__() -> Option<PyMethodDef>;
+ }
+-impl<'p, T> BytesProtocolImpl for T
+-where
+- T: PyObjectProtocol<'p>,
+-{
++impl<'p, T> BytesProtocolImpl for T where T: PyObjectProtocol<'p> {
+ default fn __bytes__() -> Option<PyMethodDef> {
+ None
+ }
+@@ -426,10 +405,7 @@ where
+ pub trait UnicodeProtocolImpl {
+ fn __unicode__() -> Option<PyMethodDef>;
+ }
+-impl<'p, T> UnicodeProtocolImpl for T
+-where
+- T: PyObjectProtocol<'p>,
+-{
++impl<'p, T> UnicodeProtocolImpl for T where T: PyObjectProtocol<'p> {
+ default fn __unicode__() -> Option<PyMethodDef> {
+ None
+ }
+@@ -438,10 +414,7 @@ where
+ trait HashProtocolImpl {
+ fn tp_hash() -> Option<ffi::hashfunc>;
+ }
+-impl<'p, T> HashProtocolImpl for T
+-where
+- T: PyObjectProtocol<'p>,
+-{
++impl<'p, T> HashProtocolImpl for T where T: PyObjectProtocol<'p> {
+ default fn tp_hash() -> Option<ffi::hashfunc> {
+ None
+ }
+@@ -464,10 +437,7 @@ where
+ trait BoolProtocolImpl {
+ fn nb_bool() -> Option<ffi::inquiry>;
+ }
+-impl<'p, T> BoolProtocolImpl for T
+-where
+- T: PyObjectProtocol<'p>,
+-{
++impl<'p, T> BoolProtocolImpl for T where T: PyObjectProtocol<'p> {
+ default fn nb_bool() -> Option<ffi::inquiry> {
+ None
+ }
+@@ -490,10 +460,7 @@ where
+ trait RichcmpProtocolImpl {
+ fn tp_richcompare() -> Option<ffi::richcmpfunc>;
+ }
+-impl<'p, T> RichcmpProtocolImpl for T
+-where
+- T: PyObjectProtocol<'p>,
+-{
++impl<'p, T> RichcmpProtocolImpl for T where T: PyObjectProtocol<'p> {
+ default fn tp_richcompare() -> Option<ffi::richcmpfunc> {
+ None
+ }
+diff --git a/src/class/buffer.rs b/src/class/buffer.rs
+index f0f462db9..c30f078cc 100644
+--- a/src/class/buffer.rs
++++ b/src/class/buffer.rs
+@@ -69,10 +69,7 @@ trait PyBufferGetBufferProtocolImpl {
+ fn cb_bf_getbuffer() -> Option<ffi::getbufferproc>;
+ }
+
+-impl<'p, T> PyBufferGetBufferProtocolImpl for T
+-where
+- T: PyBufferProtocol<'p>,
+-{
++impl<'p, T> PyBufferGetBufferProtocolImpl for T where T: PyBufferProtocol<'p> {
+ default fn cb_bf_getbuffer() -> Option<ffi::getbufferproc> {
+ None
+ }
+diff --git a/src/class/context.rs b/src/class/context.rs
+index 50aea33e9..2ad59768d 100644
+--- a/src/class/context.rs
++++ b/src/class/context.rs
+@@ -80,10 +80,7 @@ pub trait PyContextEnterProtocolImpl {
+ fn __enter__() -> Option<PyMethodDef>;
+ }
+
+-impl<'p, T> PyContextEnterProtocolImpl for T
+-where
+- T: PyContextProtocol<'p>,
+-{
++impl<'p, T> PyContextEnterProtocolImpl for T where T: PyContextProtocol<'p> {
+ default fn __enter__() -> Option<PyMethodDef> {
+ None
+ }
+@@ -94,10 +91,7 @@ pub trait PyContextExitProtocolImpl {
+ fn __exit__() -> Option<PyMethodDef>;
+ }
+
+-impl<'p, T> PyContextExitProtocolImpl for T
+-where
+- T: PyContextProtocol<'p>,
+-{
++impl<'p, T> PyContextExitProtocolImpl for T where T: PyContextProtocol<'p> {
+ default fn __exit__() -> Option<PyMethodDef> {
+ None
+ }
+diff --git a/src/class/descr.rs b/src/class/descr.rs
+index 57d9119ca..c7b5b9660 100644
+--- a/src/class/descr.rs
++++ b/src/class/descr.rs
+@@ -72,10 +72,7 @@ pub trait PyDescrSetNameProtocol<'p>: PyDescrProtocol<'p> {
+ trait PyDescrGetProtocolImpl {
+ fn tp_descr_get() -> Option<ffi::descrgetfunc>;
+ }
+-impl<'p, T> PyDescrGetProtocolImpl for T
+-where
+- T: PyDescrProtocol<'p>,
+-{
++impl<'p, T> PyDescrGetProtocolImpl for T where T: PyDescrProtocol<'p> {
+ default fn tp_descr_get() -> Option<ffi::descrgetfunc> {
+ None
+ }
+@@ -98,10 +95,7 @@ where
+ trait PyDescrSetProtocolImpl {
+ fn tp_descr_set() -> Option<ffi::descrsetfunc>;
+ }
+-impl<'p, T> PyDescrSetProtocolImpl for T
+-where
+- T: PyDescrProtocol<'p>,
+-{
++impl<'p, T> PyDescrSetProtocolImpl for T where T: PyDescrProtocol<'p> {
+ default fn tp_descr_set() -> Option<ffi::descrsetfunc> {
+ None
+ }
+diff --git a/src/class/gc.rs b/src/class/gc.rs
+index 591b686af..4b69c9643 100644
+--- a/src/class/gc.rs
++++ b/src/class/gc.rs
+@@ -68,10 +68,7 @@ trait PyGCTraverseProtocolImpl {
+ fn tp_traverse() -> Option<ffi::traverseproc>;
+ }
+
+-impl<'p, T> PyGCTraverseProtocolImpl for T
+-where
+- T: PyGCProtocol<'p>,
+-{
++impl<'p, T> PyGCTraverseProtocolImpl for T where T: PyGCProtocol<'p> {
+ default fn tp_traverse() -> Option<ffi::traverseproc> {
+ None
+ }
+@@ -115,10 +112,7 @@ trait PyGCClearProtocolImpl {
+ fn tp_clear() -> Option<ffi::inquiry>;
+ }
+
+-impl<'p, T> PyGCClearProtocolImpl for T
+-where
+- T: PyGCProtocol<'p>,
+-{
++impl<'p, T> PyGCClearProtocolImpl for T where T: PyGCProtocol<'p> {
+ default fn tp_clear() -> Option<ffi::inquiry> {
+ None
+ }
+diff --git a/src/class/iter.rs b/src/class/iter.rs
+index a528289dd..fcf76f2e5 100644
+--- a/src/class/iter.rs
++++ b/src/class/iter.rs
+@@ -66,10 +66,7 @@ trait PyIterIterProtocolImpl {
+ fn tp_iter() -> Option<ffi::getiterfunc>;
+ }
+
+-impl<'p, T> PyIterIterProtocolImpl for T
+-where
+- T: PyIterProtocol<'p>,
+-{
++impl<'p, T> PyIterIterProtocolImpl for T where T: PyIterProtocol<'p> {
+ default fn tp_iter() -> Option<ffi::getiterfunc> {
+ None
+ }
+@@ -94,10 +91,7 @@ trait PyIterNextProtocolImpl {
+ fn tp_iternext() -> Option<ffi::iternextfunc>;
+ }
+
+-impl<'p, T> PyIterNextProtocolImpl for T
+-where
+- T: PyIterProtocol<'p>,
+-{
++impl<'p, T> PyIterNextProtocolImpl for T where T: PyIterProtocol<'p> {
+ default fn tp_iternext() -> Option<ffi::iternextfunc> {
+ None
+ }
+diff --git a/src/class/mapping.rs b/src/class/mapping.rs
+index 32326ff46..64d7b57ce 100644
+--- a/src/class/mapping.rs
++++ b/src/class/mapping.rs
+@@ -160,10 +160,7 @@ trait PyMappingLenProtocolImpl {
+ fn mp_length() -> Option<ffi::lenfunc>;
+ }
+
+-impl<'p, T> PyMappingLenProtocolImpl for T
+-where
+- T: PyMappingProtocol<'p>,
+-{
++impl<'p, T> PyMappingLenProtocolImpl for T where T: PyMappingProtocol<'p> {
+ default fn mp_length() -> Option<ffi::lenfunc> {
+ None
+ }
+@@ -183,10 +180,7 @@ trait PyMappingGetItemProtocolImpl {
+ fn mp_subscript() -> Option<ffi::binaryfunc>;
+ }
+
+-impl<'p, T> PyMappingGetItemProtocolImpl for T
+-where
+- T: PyMappingProtocol<'p>,
+-{
++impl<'p, T> PyMappingGetItemProtocolImpl for T where T: PyMappingProtocol<'p> {
+ default fn mp_subscript() -> Option<ffi::binaryfunc> {
+ None
+ }
+@@ -211,10 +205,7 @@ trait PyMappingSetItemProtocolImpl {
+ fn mp_ass_subscript() -> Option<ffi::objobjargproc>;
+ }
+
+-impl<'p, T> PyMappingSetItemProtocolImpl for T
+-where
+- T: PyMappingProtocol<'p>,
+-{
++impl<'p, T> PyMappingSetItemProtocolImpl for T where T: PyMappingProtocol<'p> {
+ default fn mp_ass_subscript() -> Option<ffi::objobjargproc> {
+ None
+ }
+@@ -236,10 +227,7 @@ trait DeplItemDipatch {
+ fn mp_del_subscript() -> Option<ffi::objobjargproc>;
+ }
+
+-impl<'p, T> DeplItemDipatch for T
+-where
+- T: PyMappingProtocol<'p>,
+-{
++impl<'p, T> DeplItemDipatch for T where T: PyMappingProtocol<'p> {
+ default fn mp_del_subscript() -> Option<ffi::objobjargproc> {
+ None
+ }
+@@ -250,10 +238,7 @@ trait DelSetItemDispatch: Sized + for<'p> PyMappingDelItemProtocol<'p> {
+ fn det_set_dispatch() -> Option<ffi::objobjargproc>;
+ }
+
+-impl<T> DelSetItemDispatch for T
+-where
+- T: Sized + for<'p> PyMappingDelItemProtocol<'p>,
+-{
++impl<T> DelSetItemDispatch for T where T: Sized + for<'p> PyMappingDelItemProtocol<'p> {
+ default fn det_set_dispatch() -> Option<ffi::objobjargproc> {
+ py_func_del!(PyMappingDelItemProtocol, Self, __delitem__)
+ }
+@@ -288,10 +273,7 @@ pub trait PyMappingContainsProtocolImpl {
+ fn __contains__() -> Option<PyMethodDef>;
+ }
+
+-impl<'p, T> PyMappingContainsProtocolImpl for T
+-where
+- T: PyMappingProtocol<'p>,
+-{
++impl<'p, T> PyMappingContainsProtocolImpl for T where T: PyMappingProtocol<'p> {
+ default fn __contains__() -> Option<PyMethodDef> {
+ None
+ }
+@@ -302,10 +284,7 @@ pub trait PyMappingReversedProtocolImpl {
+ fn __reversed__() -> Option<PyMethodDef>;
+ }
+
+-impl<'p, T> PyMappingReversedProtocolImpl for T
+-where
+- T: PyMappingProtocol<'p>,
+-{
++impl<'p, T> PyMappingReversedProtocolImpl for T where T: PyMappingProtocol<'p> {
+ default fn __reversed__() -> Option<PyMethodDef> {
+ None
+ }
+@@ -316,10 +295,7 @@ pub trait PyMappingIterProtocolImpl {
+ fn __iter__() -> Option<PyMethodDef>;
+ }
+
+-impl<'p, T> PyMappingIterProtocolImpl for T
+-where
+- T: PyMappingProtocol<'p>,
+-{
++impl<'p, T> PyMappingIterProtocolImpl for T where T: PyMappingProtocol<'p> {
+ default fn __iter__() -> Option<PyMethodDef> {
+ None
+ }
+diff --git a/src/class/number.rs b/src/class/number.rs
+index 796b8bad9..0ab162e72 100644
+--- a/src/class/number.rs
++++ b/src/class/number.rs
+@@ -749,10 +749,7 @@ trait PyNumberAddProtocolImpl {
+ fn nb_add() -> Option<ffi::binaryfunc>;
+ }
+
+-impl<'p, T> PyNumberAddProtocolImpl for T
+-where
+- T: PyNumberProtocol<'p>,
+-{
++impl<'p, T> PyNumberAddProtocolImpl for T where T: PyNumberProtocol<'p> {
+ default fn nb_add() -> Option<ffi::binaryfunc> {
+ None
+ }
+@@ -776,10 +773,7 @@ trait PyNumberSubProtocolImpl {
+ fn nb_subtract() -> Option<ffi::binaryfunc>;
+ }
+
+-impl<'p, T> PyNumberSubProtocolImpl for T
+-where
+- T: PyNumberProtocol<'p>,
+-{
++impl<'p, T> PyNumberSubProtocolImpl for T where T: PyNumberProtocol<'p> {
+ default fn nb_subtract() -> Option<ffi::binaryfunc> {
+ None
+ }
+@@ -803,10 +797,7 @@ trait PyNumberMulProtocolImpl {
+ fn nb_multiply() -> Option<ffi::binaryfunc>;
+ }
+
+-impl<'p, T> PyNumberMulProtocolImpl for T
+-where
+- T: PyNumberProtocol<'p>,
+-{
++impl<'p, T> PyNumberMulProtocolImpl for T where T: PyNumberProtocol<'p> {
+ default fn nb_multiply() -> Option<ffi::binaryfunc> {
+ None
+ }
+@@ -830,10 +821,7 @@ trait PyNumberMatmulProtocolImpl {
+ fn nb_matrix_multiply() -> Option<ffi::binaryfunc>;
+ }
+
+-impl<'p, T> PyNumberMatmulProtocolImpl for T
+-where
+- T: PyNumberProtocol<'p>,
+-{
++impl<'p, T> PyNumberMatmulProtocolImpl for T where T: PyNumberProtocol<'p> {
+ default fn nb_matrix_multiply() -> Option<ffi::binaryfunc> {
+ None
+ }
+@@ -857,10 +845,7 @@ trait PyNumberTruedivProtocolImpl {
+ fn nb_true_divide() -> Option<ffi::binaryfunc>;
+ }
+
+-impl<'p, T> PyNumberTruedivProtocolImpl for T
+-where
+- T: PyNumberProtocol<'p>,
+-{
++impl<'p, T> PyNumberTruedivProtocolImpl for T where T: PyNumberProtocol<'p> {
+ default fn nb_true_divide() -> Option<ffi::binaryfunc> {
+ None
+ }
+@@ -884,10 +869,7 @@ trait PyNumberFloordivProtocolImpl {
+ fn nb_floor_divide() -> Option<ffi::binaryfunc>;
+ }
+
+-impl<'p, T> PyNumberFloordivProtocolImpl for T
+-where
+- T: PyNumberProtocol<'p>,
+-{
++impl<'p, T> PyNumberFloordivProtocolImpl for T where T: PyNumberProtocol<'p> {
+ default fn nb_floor_divide() -> Option<ffi::binaryfunc> {
+ None
+ }
+@@ -911,10 +893,7 @@ trait PyNumberModProtocolImpl {
+ fn nb_remainder() -> Option<ffi::binaryfunc>;
+ }
+
+-impl<'p, T> PyNumberModProtocolImpl for T
+-where
+- T: PyNumberProtocol<'p>,
+-{
++impl<'p, T> PyNumberModProtocolImpl for T where T: PyNumberProtocol<'p> {
+ default fn nb_remainder() -> Option<ffi::binaryfunc> {
+ None
+ }
+@@ -938,10 +917,7 @@ trait PyNumberDivmodProtocolImpl {
+ fn nb_divmod() -> Option<ffi::binaryfunc>;
+ }
+
+-impl<'p, T> PyNumberDivmodProtocolImpl for T
+-where
+- T: PyNumberProtocol<'p>,
+-{
++impl<'p, T> PyNumberDivmodProtocolImpl for T where T: PyNumberProtocol<'p> {
+ default fn nb_divmod() -> Option<ffi::binaryfunc> {
+ None
+ }
+@@ -965,10 +941,7 @@ trait PyNumberPowProtocolImpl {
+ fn nb_power() -> Option<ffi::ternaryfunc>;
+ }
+
+-impl<'p, T> PyNumberPowProtocolImpl for T
+-where
+- T: PyNumberProtocol<'p>,
+-{
++impl<'p, T> PyNumberPowProtocolImpl for T where T: PyNumberProtocol<'p> {
+ default fn nb_power() -> Option<ffi::ternaryfunc> {
+ None
+ }
+@@ -992,10 +965,7 @@ trait PyNumberLShiftProtocolImpl {
+ fn nb_lshift() -> Option<ffi::binaryfunc>;
+ }
+
+-impl<'p, T> PyNumberLShiftProtocolImpl for T
+-where
+- T: PyNumberProtocol<'p>,
+-{
++impl<'p, T> PyNumberLShiftProtocolImpl for T where T: PyNumberProtocol<'p> {
+ default fn nb_lshift() -> Option<ffi::binaryfunc> {
+ None
+ }
+@@ -1019,10 +989,7 @@ trait PyNumberRShiftProtocolImpl {
+ fn nb_rshift() -> Option<ffi::binaryfunc>;
+ }
+
+-impl<'p, T> PyNumberRShiftProtocolImpl for T
+-where
+- T: PyNumberProtocol<'p>,
+-{
++impl<'p, T> PyNumberRShiftProtocolImpl for T where T: PyNumberProtocol<'p> {
+ default fn nb_rshift() -> Option<ffi::binaryfunc> {
+ None
+ }
+@@ -1046,10 +1013,7 @@ trait PyNumberAndProtocolImpl {
+ fn nb_and() -> Option<ffi::binaryfunc>;
+ }
+
+-impl<'p, T> PyNumberAndProtocolImpl for T
+-where
+- T: PyNumberProtocol<'p>,
+-{
++impl<'p, T> PyNumberAndProtocolImpl for T where T: PyNumberProtocol<'p> {
+ default fn nb_and() -> Option<ffi::binaryfunc> {
+ None
+ }
+@@ -1073,10 +1037,7 @@ trait PyNumberXorProtocolImpl {
+ fn nb_xor() -> Option<ffi::binaryfunc>;
+ }
+
+-impl<'p, T> PyNumberXorProtocolImpl for T
+-where
+- T: PyNumberProtocol<'p>,
+-{
++impl<'p, T> PyNumberXorProtocolImpl for T where T: PyNumberProtocol<'p> {
+ default fn nb_xor() -> Option<ffi::binaryfunc> {
+ None
+ }
+@@ -1100,10 +1061,7 @@ trait PyNumberOrProtocolImpl {
+ fn nb_or() -> Option<ffi::binaryfunc>;
+ }
+
+-impl<'p, T> PyNumberOrProtocolImpl for T
+-where
+- T: PyNumberProtocol<'p>,
+-{
++impl<'p, T> PyNumberOrProtocolImpl for T where T: PyNumberProtocol<'p> {
+ default fn nb_or() -> Option<ffi::binaryfunc> {
+ None
+ }
+@@ -1127,10 +1085,7 @@ trait PyNumberIAddProtocolImpl {
+ fn nb_inplace_add() -> Option<ffi::binaryfunc>;
+ }
+
+-impl<'p, T> PyNumberIAddProtocolImpl for T
+-where
+- T: PyNumberProtocol<'p>,
+-{
++impl<'p, T> PyNumberIAddProtocolImpl for T where T: PyNumberProtocol<'p> {
+ default fn nb_inplace_add() -> Option<ffi::binaryfunc> {
+ None
+ }
+@@ -1149,10 +1104,7 @@ trait PyNumberISubProtocolImpl {
+ fn nb_inplace_subtract() -> Option<ffi::binaryfunc>;
+ }
+
+-impl<'p, T> PyNumberISubProtocolImpl for T
+-where
+- T: PyNumberProtocol<'p>,
+-{
++impl<'p, T> PyNumberISubProtocolImpl for T where T: PyNumberProtocol<'p> {
+ default fn nb_inplace_subtract() -> Option<ffi::binaryfunc> {
+ None
+ }
+@@ -1171,10 +1123,7 @@ trait PyNumberIMulProtocolImpl {
+ fn nb_inplace_multiply() -> Option<ffi::binaryfunc>;
+ }
+
+-impl<'p, T> PyNumberIMulProtocolImpl for T
+-where
+- T: PyNumberProtocol<'p>,
+-{
++impl<'p, T> PyNumberIMulProtocolImpl for T where T: PyNumberProtocol<'p> {
+ default fn nb_inplace_multiply() -> Option<ffi::binaryfunc> {
+ None
+ }
+@@ -1193,10 +1142,7 @@ trait PyNumberIMatmulProtocolImpl {
+ fn nb_inplace_matrix_multiply() -> Option<ffi::binaryfunc>;
+ }
+
+-impl<'p, T> PyNumberIMatmulProtocolImpl for T
+-where
+- T: PyNumberProtocol<'p>,
+-{
++impl<'p, T> PyNumberIMatmulProtocolImpl for T where T: PyNumberProtocol<'p> {
+ default fn nb_inplace_matrix_multiply() -> Option<ffi::binaryfunc> {
+ None
+ }
+@@ -1215,10 +1161,7 @@ trait PyNumberITruedivProtocolImpl {
+ fn nb_inplace_true_divide() -> Option<ffi::binaryfunc>;
+ }
+
+-impl<'p, T> PyNumberITruedivProtocolImpl for T
+-where
+- T: PyNumberProtocol<'p>,
+-{
++impl<'p, T> PyNumberITruedivProtocolImpl for T where T: PyNumberProtocol<'p> {
+ default fn nb_inplace_true_divide() -> Option<ffi::binaryfunc> {
+ None
+ }
+@@ -1237,10 +1180,7 @@ trait PyNumberIFloordivProtocolImpl {
+ fn nb_inplace_floor_divide() -> Option<ffi::binaryfunc>;
+ }
+
+-impl<'p, T> PyNumberIFloordivProtocolImpl for T
+-where
+- T: PyNumberProtocol<'p>,
+-{
++impl<'p, T> PyNumberIFloordivProtocolImpl for T where T: PyNumberProtocol<'p> {
+ default fn nb_inplace_floor_divide() -> Option<ffi::binaryfunc> {
+ None
+ }
+@@ -1259,10 +1199,7 @@ trait PyNumberIModProtocolImpl {
+ fn nb_inplace_remainder() -> Option<ffi::binaryfunc>;
+ }
+
+-impl<'p, T> PyNumberIModProtocolImpl for T
+-where
+- T: PyNumberProtocol<'p>,
+-{
++impl<'p, T> PyNumberIModProtocolImpl for T where T: PyNumberProtocol<'p> {
+ default fn nb_inplace_remainder() -> Option<ffi::binaryfunc> {
+ None
+ }
+@@ -1281,10 +1218,7 @@ trait PyNumberIPowProtocolImpl {
+ fn nb_inplace_power() -> Option<ffi::ternaryfunc>;
+ }
+
+-impl<'p, T> PyNumberIPowProtocolImpl for T
+-where
+- T: PyNumberProtocol<'p>,
+-{
++impl<'p, T> PyNumberIPowProtocolImpl for T where T: PyNumberProtocol<'p> {
+ default fn nb_inplace_power() -> Option<ffi::ternaryfunc> {
+ None
+ }
+@@ -1303,10 +1237,7 @@ trait PyNumberILShiftProtocolImpl {
+ fn nb_inplace_lshift() -> Option<ffi::binaryfunc>;
+ }
+
+-impl<'p, T> PyNumberILShiftProtocolImpl for T
+-where
+- T: PyNumberProtocol<'p>,
+-{
++impl<'p, T> PyNumberILShiftProtocolImpl for T where T: PyNumberProtocol<'p> {
+ default fn nb_inplace_lshift() -> Option<ffi::binaryfunc> {
+ None
+ }
+@@ -1325,10 +1256,7 @@ trait PyNumberIRShiftProtocolImpl {
+ fn nb_inplace_rshift() -> Option<ffi::binaryfunc>;
+ }
+
+-impl<'p, T> PyNumberIRShiftProtocolImpl for T
+-where
+- T: PyNumberProtocol<'p>,
+-{
++impl<'p, T> PyNumberIRShiftProtocolImpl for T where T: PyNumberProtocol<'p> {
+ default fn nb_inplace_rshift() -> Option<ffi::binaryfunc> {
+ None
+ }
+@@ -1347,10 +1275,7 @@ trait PyNumberIAndProtocolImpl {
+ fn nb_inplace_and() -> Option<ffi::binaryfunc>;
+ }
+
+-impl<'p, T> PyNumberIAndProtocolImpl for T
+-where
+- T: PyNumberProtocol<'p>,
+-{
++impl<'p, T> PyNumberIAndProtocolImpl for T where T: PyNumberProtocol<'p> {
+ default fn nb_inplace_and() -> Option<ffi::binaryfunc> {
+ None
+ }
+@@ -1369,10 +1294,7 @@ trait PyNumberIXorProtocolImpl {
+ fn nb_inplace_xor() -> Option<ffi::binaryfunc>;
+ }
+
+-impl<'p, T> PyNumberIXorProtocolImpl for T
+-where
+- T: PyNumberProtocol<'p>,
+-{
++impl<'p, T> PyNumberIXorProtocolImpl for T where T: PyNumberProtocol<'p> {
+ default fn nb_inplace_xor() -> Option<ffi::binaryfunc> {
+ None
+ }
+@@ -1391,10 +1313,7 @@ trait PyNumberIOrProtocolImpl {
+ fn nb_inplace_or() -> Option<ffi::binaryfunc>;
+ }
+
+-impl<'p, T> PyNumberIOrProtocolImpl for T
+-where
+- T: PyNumberProtocol<'p>,
+-{
++impl<'p, T> PyNumberIOrProtocolImpl for T where T: PyNumberProtocol<'p> {
+ default fn nb_inplace_or() -> Option<ffi::binaryfunc> {
+ None
+ }
+@@ -1414,10 +1333,7 @@ pub trait PyNumberRAddProtocolImpl {
+ fn __radd__() -> Option<PyMethodDef>;
+ }
+
+-impl<'p, T> PyNumberRAddProtocolImpl for T
+-where
+- T: PyNumberProtocol<'p>,
+-{
++impl<'p, T> PyNumberRAddProtocolImpl for T where T: PyNumberProtocol<'p> {
+ default fn __radd__() -> Option<PyMethodDef> {
+ None
+ }
+@@ -1437,10 +1353,7 @@ pub trait PyNumberRMulProtocolImpl {
+ fn __rmul__() -> Option<PyMethodDef>;
+ }
+
+-impl<'p, T> PyNumberRMulProtocolImpl for T
+-where
+- T: PyNumberProtocol<'p>,
+-{
++impl<'p, T> PyNumberRMulProtocolImpl for T where T: PyNumberProtocol<'p> {
+ default fn __rmul__() -> Option<PyMethodDef> {
+ None
+ }
+@@ -1451,10 +1364,7 @@ pub trait PyNumberRMatmulProtocolImpl {
+ fn __rmatmul__() -> Option<PyMethodDef>;
+ }
+
+-impl<'p, T> PyNumberRMatmulProtocolImpl for T
+-where
+- T: PyNumberProtocol<'p>,
+-{
++impl<'p, T> PyNumberRMatmulProtocolImpl for T where T: PyNumberProtocol<'p> {
+ default fn __rmatmul__() -> Option<PyMethodDef> {
+ None
+ }
+@@ -1465,10 +1375,7 @@ pub trait PyNumberRTruedivProtocolImpl {
+ fn __rtruediv__() -> Option<PyMethodDef>;
+ }
+
+-impl<'p, T> PyNumberRTruedivProtocolImpl for T
+-where
+- T: PyNumberProtocol<'p>,
+-{
++impl<'p, T> PyNumberRTruedivProtocolImpl for T where T: PyNumberProtocol<'p> {
+ default fn __rtruediv__() -> Option<PyMethodDef> {
+ None
+ }
+@@ -1479,10 +1386,7 @@ pub trait PyNumberRFloordivProtocolImpl {
+ fn __rfloordiv__() -> Option<PyMethodDef>;
+ }
+
+-impl<'p, T> PyNumberRFloordivProtocolImpl for T
+-where
+- T: PyNumberProtocol<'p>,
+-{
++impl<'p, T> PyNumberRFloordivProtocolImpl for T where T: PyNumberProtocol<'p> {
+ default fn __rfloordiv__() -> Option<PyMethodDef> {
+ None
+ }
+@@ -1493,10 +1397,7 @@ pub trait PyNumberRModProtocolImpl {
+ fn __rmod__() -> Option<PyMethodDef>;
+ }
+
+-impl<'p, T> PyNumberRModProtocolImpl for T
+-where
+- T: PyNumberProtocol<'p>,
+-{
++impl<'p, T> PyNumberRModProtocolImpl for T where T: PyNumberProtocol<'p> {
+ default fn __rmod__() -> Option<PyMethodDef> {
+ None
+ }
+@@ -1507,10 +1408,7 @@ pub trait PyNumberRDivmodProtocolImpl {
+ fn __rdivmod__() -> Option<PyMethodDef>;
+ }
+
+-impl<'p, T> PyNumberRDivmodProtocolImpl for T
+-where
+- T: PyNumberProtocol<'p>,
+-{
++impl<'p, T> PyNumberRDivmodProtocolImpl for T where T: PyNumberProtocol<'p> {
+ default fn __rdivmod__() -> Option<PyMethodDef> {
+ None
+ }
+@@ -1521,10 +1419,7 @@ pub trait PyNumberRPowProtocolImpl {
+ fn __rpow__() -> Option<PyMethodDef>;
+ }
+
+-impl<'p, T> PyNumberRPowProtocolImpl for T
+-where
+- T: PyNumberProtocol<'p>,
+-{
++impl<'p, T> PyNumberRPowProtocolImpl for T where T: PyNumberProtocol<'p> {
+ default fn __rpow__() -> Option<PyMethodDef> {
+ None
+ }
+@@ -1535,10 +1430,7 @@ pub trait PyNumberRLShiftProtocolImpl {
+ fn __rlshift__() -> Option<PyMethodDef>;
+ }
+
+-impl<'p, T> PyNumberRLShiftProtocolImpl for T
+-where
+- T: PyNumberProtocol<'p>,
+-{
++impl<'p, T> PyNumberRLShiftProtocolImpl for T where T: PyNumberProtocol<'p> {
+ default fn __rlshift__() -> Option<PyMethodDef> {
+ None
+ }
+@@ -1549,10 +1441,7 @@ pub trait PyNumberRRShiftProtocolImpl {
+ fn __rrshift__() -> Option<PyMethodDef>;
+ }
+
+-impl<'p, T> PyNumberRRShiftProtocolImpl for T
+-where
+- T: PyNumberProtocol<'p>,
+-{
++impl<'p, T> PyNumberRRShiftProtocolImpl for T where T: PyNumberProtocol<'p> {
+ default fn __rrshift__() -> Option<PyMethodDef> {
+ None
+ }
+@@ -1563,10 +1452,7 @@ pub trait PyNumberRAndProtocolImpl {
+ fn __rand__() -> Option<PyMethodDef>;
+ }
+
+-impl<'p, T> PyNumberRAndProtocolImpl for T
+-where
+- T: PyNumberProtocol<'p>,
+-{
++impl<'p, T> PyNumberRAndProtocolImpl for T where T: PyNumberProtocol<'p> {
+ default fn __rand__() -> Option<PyMethodDef> {
+ None
+ }
+@@ -1577,10 +1463,7 @@ pub trait PyNumberRXorProtocolImpl {
+ fn __rxor__() -> Option<PyMethodDef>;
+ }
+
+-impl<'p, T> PyNumberRXorProtocolImpl for T
+-where
+- T: PyNumberProtocol<'p>,
+-{
++impl<'p, T> PyNumberRXorProtocolImpl for T where T: PyNumberProtocol<'p> {
+ default fn __rxor__() -> Option<PyMethodDef> {
+ None
+ }
+@@ -1591,10 +1474,7 @@ pub trait PyNumberROrProtocolImpl {
+ fn __ror__() -> Option<PyMethodDef>;
+ }
+
+-impl<'p, T> PyNumberROrProtocolImpl for T
+-where
+- T: PyNumberProtocol<'p>,
+-{
++impl<'p, T> PyNumberROrProtocolImpl for T where T: PyNumberProtocol<'p> {
+ default fn __ror__() -> Option<PyMethodDef> {
+ None
+ }
+@@ -1604,10 +1484,7 @@ trait PyNumberNegProtocolImpl {
+ fn nb_negative() -> Option<ffi::unaryfunc>;
+ }
+
+-impl<'p, T> PyNumberNegProtocolImpl for T
+-where
+- T: PyNumberProtocol<'p>,
+-{
++impl<'p, T> PyNumberNegProtocolImpl for T where T: PyNumberProtocol<'p> {
+ default fn nb_negative() -> Option<ffi::unaryfunc> {
+ None
+ }
+@@ -1632,10 +1509,7 @@ trait PyNumberPosProtocolImpl {
+ fn nb_positive() -> Option<ffi::unaryfunc>;
+ }
+
+-impl<'p, T> PyNumberPosProtocolImpl for T
+-where
+- T: PyNumberProtocol<'p>,
+-{
++impl<'p, T> PyNumberPosProtocolImpl for T where T: PyNumberProtocol<'p> {
+ default fn nb_positive() -> Option<ffi::unaryfunc> {
+ None
+ }
+@@ -1659,10 +1533,7 @@ trait PyNumberAbsProtocolImpl {
+ fn nb_absolute() -> Option<ffi::unaryfunc>;
+ }
+
+-impl<'p, T> PyNumberAbsProtocolImpl for T
+-where
+- T: PyNumberProtocol<'p>,
+-{
++impl<'p, T> PyNumberAbsProtocolImpl for T where T: PyNumberProtocol<'p> {
+ default fn nb_absolute() -> Option<ffi::unaryfunc> {
+ None
+ }
+@@ -1686,10 +1557,7 @@ trait PyNumberInvertProtocolImpl {
+ fn nb_invert() -> Option<ffi::unaryfunc>;
+ }
+
+-impl<'p, T> PyNumberInvertProtocolImpl for T
+-where
+- T: PyNumberProtocol<'p>,
+-{
++impl<'p, T> PyNumberInvertProtocolImpl for T where T: PyNumberProtocol<'p> {
+ default fn nb_invert() -> Option<ffi::unaryfunc> {
+ None
+ }
+@@ -1713,10 +1581,7 @@ trait PyNumberIntProtocolImpl {
+ fn nb_int() -> Option<ffi::unaryfunc>;
+ }
+
+-impl<'p, T> PyNumberIntProtocolImpl for T
+-where
+- T: PyNumberProtocol<'p>,
+-{
++impl<'p, T> PyNumberIntProtocolImpl for T where T: PyNumberProtocol<'p> {
+ default fn nb_int() -> Option<ffi::unaryfunc> {
+ None
+ }
+@@ -1740,10 +1605,7 @@ trait PyNumberFloatProtocolImpl {
+ fn nb_float() -> Option<ffi::unaryfunc>;
+ }
+
+-impl<'p, T> PyNumberFloatProtocolImpl for T
+-where
+- T: PyNumberProtocol<'p>,
+-{
++impl<'p, T> PyNumberFloatProtocolImpl for T where T: PyNumberProtocol<'p> {
+ default fn nb_float() -> Option<ffi::unaryfunc> {
+ None
+ }
+@@ -1767,10 +1629,7 @@ trait PyNumberIndexProtocolImpl {
+ fn nb_index() -> Option<ffi::unaryfunc>;
+ }
+
+-impl<'p, T> PyNumberIndexProtocolImpl for T
+-where
+- T: PyNumberProtocol<'p>,
+-{
++impl<'p, T> PyNumberIndexProtocolImpl for T where T: PyNumberProtocol<'p> {
+ default fn nb_index() -> Option<ffi::unaryfunc> {
+ None
+ }
+@@ -1794,10 +1653,7 @@ trait PyNumberComplexProtocolImpl {
+ fn __complex__() -> Option<PyMethodDef>;
+ }
+
+-impl<'p, T> PyNumberComplexProtocolImpl for T
+-where
+- T: PyNumberProtocol<'p>,
+-{
++impl<'p, T> PyNumberComplexProtocolImpl for T where T: PyNumberProtocol<'p> {
+ default fn __complex__() -> Option<PyMethodDef> {
+ None
+ }
+@@ -1807,10 +1663,7 @@ trait PyNumberRoundProtocolImpl {
+ fn __round__() -> Option<PyMethodDef>;
+ }
+
+-impl<'p, T> PyNumberRoundProtocolImpl for T
+-where
+- T: PyNumberProtocol<'p>,
+-{
++impl<'p, T> PyNumberRoundProtocolImpl for T where T: PyNumberProtocol<'p> {
+ default fn __round__() -> Option<PyMethodDef> {
+ None
+ }
+diff --git a/src/class/pyasync.rs b/src/class/pyasync.rs
+index 2536d4ce2..f977fadfa 100644
+--- a/src/class/pyasync.rs
++++ b/src/class/pyasync.rs
+@@ -137,10 +137,7 @@ trait PyAsyncAwaitProtocolImpl {
+ fn am_await() -> Option<ffi::unaryfunc>;
+ }
+
+-impl<'p, T> PyAsyncAwaitProtocolImpl for T
+-where
+- T: PyAsyncProtocol<'p>,
+-{
++impl<'p, T> PyAsyncAwaitProtocolImpl for T where T: PyAsyncProtocol<'p> {
+ default fn am_await() -> Option<ffi::unaryfunc> {
+ None
+ }
+@@ -165,10 +162,7 @@ trait PyAsyncAiterProtocolImpl {
+ fn am_aiter() -> Option<ffi::unaryfunc>;
+ }
+
+-impl<'p, T> PyAsyncAiterProtocolImpl for T
+-where
+- T: PyAsyncProtocol<'p>,
+-{
++impl<'p, T> PyAsyncAiterProtocolImpl for T where T: PyAsyncProtocol<'p> {
+ default fn am_aiter() -> Option<ffi::unaryfunc> {
+ None
+ }
+@@ -193,10 +187,7 @@ trait PyAsyncAnextProtocolImpl {
+ fn am_anext() -> Option<ffi::unaryfunc>;
+ }
+
+-impl<'p, T> PyAsyncAnextProtocolImpl for T
+-where
+- T: PyAsyncProtocol<'p>,
+-{
++impl<'p, T> PyAsyncAnextProtocolImpl for T where T: PyAsyncProtocol<'p> {
+ default fn am_anext() -> Option<ffi::unaryfunc> {
+ None
+ }
+@@ -254,10 +245,7 @@ trait PyAsyncAenterProtocolImpl {
+ fn __aenter__() -> Option<PyMethodDef>;
+ }
+
+-impl<'p, T> PyAsyncAenterProtocolImpl for T
+-where
+- T: PyAsyncProtocol<'p>,
+-{
++impl<'p, T> PyAsyncAenterProtocolImpl for T where T: PyAsyncProtocol<'p> {
+ default fn __aenter__() -> Option<PyMethodDef> {
+ None
+ }
+@@ -267,10 +255,7 @@ trait PyAsyncAexitProtocolImpl {
+ fn __aexit__() -> Option<PyMethodDef>;
+ }
+
+-impl<'p, T> PyAsyncAexitProtocolImpl for T
+-where
+- T: PyAsyncProtocol<'p>,
+-{
++impl<'p, T> PyAsyncAexitProtocolImpl for T where T: PyAsyncProtocol<'p> {
+ default fn __aexit__() -> Option<PyMethodDef> {
+ None
+ }
+diff --git a/src/class/sequence.rs b/src/class/sequence.rs
+index 5414704a1..ce65508fd 100644
+--- a/src/class/sequence.rs
++++ b/src/class/sequence.rs
+@@ -167,10 +167,7 @@ trait PySequenceLenProtocolImpl {
+ fn sq_length() -> Option<ffi::lenfunc>;
+ }
+
+-impl<'p, T> PySequenceLenProtocolImpl for T
+-where
+- T: PySequenceProtocol<'p>,
+-{
++impl<'p, T> PySequenceLenProtocolImpl for T where T: PySequenceProtocol<'p> {
+ default fn sq_length() -> Option<ffi::lenfunc> {
+ None
+ }
+@@ -189,10 +186,7 @@ trait PySequenceGetItemProtocolImpl {
+ fn sq_item() -> Option<ffi::ssizeargfunc>;
+ }
+
+-impl<'p, T> PySequenceGetItemProtocolImpl for T
+-where
+- T: PySequenceProtocol<'p>,
+-{
++impl<'p, T> PySequenceGetItemProtocolImpl for T where T: PySequenceProtocol<'p> {
+ default fn sq_item() -> Option<ffi::ssizeargfunc> {
+ None
+ }
+@@ -298,10 +292,7 @@ mod sq_ass_item_impl {
+ fn del_item() -> Option<ffi::ssizeobjargproc>;
+ }
+
+- impl<'p, T> DelItem for T
+- where
+- T: PySequenceProtocol<'p>,
+- {
++ impl<'p, T> DelItem for T where T: PySequenceProtocol<'p> {
+ default fn del_item() -> Option<ffi::ssizeobjargproc> {
+ None
+ }
+@@ -349,10 +340,7 @@ mod sq_ass_item_impl {
+ fn del_set_item() -> Option<ffi::ssizeobjargproc>;
+ }
+
+- impl<'p, T> DelSetItem for T
+- where
+- T: PySequenceProtocol<'p>,
+- {
++ impl<'p, T> DelSetItem for T where T: PySequenceProtocol<'p> {
+ default fn del_set_item() -> Option<ffi::ssizeobjargproc> {
+ None
+ }
+@@ -401,10 +389,7 @@ trait PySequenceContainsProtocolImpl {
+ fn sq_contains() -> Option<ffi::objobjproc>;
+ }
+
+-impl<'p, T> PySequenceContainsProtocolImpl for T
+-where
+- T: PySequenceProtocol<'p>,
+-{
++impl<'p, T> PySequenceContainsProtocolImpl for T where T: PySequenceProtocol<'p> {
+ default fn sq_contains() -> Option<ffi::objobjproc> {
+ None
+ }
+@@ -429,10 +414,7 @@ trait PySequenceConcatProtocolImpl {
+ fn sq_concat() -> Option<ffi::binaryfunc>;
+ }
+
+-impl<'p, T> PySequenceConcatProtocolImpl for T
+-where
+- T: PySequenceProtocol<'p>,
+-{
++impl<'p, T> PySequenceConcatProtocolImpl for T where T: PySequenceProtocol<'p> {
+ default fn sq_concat() -> Option<ffi::binaryfunc> {
+ None
+ }
+@@ -456,10 +438,7 @@ trait PySequenceRepeatProtocolImpl {
+ fn sq_repeat() -> Option<ffi::ssizeargfunc>;
+ }
+
+-impl<'p, T> PySequenceRepeatProtocolImpl for T
+-where
+- T: PySequenceProtocol<'p>,
+-{
++impl<'p, T> PySequenceRepeatProtocolImpl for T where T: PySequenceProtocol<'p> {
+ default fn sq_repeat() -> Option<ffi::ssizeargfunc> {
+ None
+ }
+@@ -483,10 +462,7 @@ trait PySequenceInplaceConcatProtocolImpl {
+ fn sq_inplace_concat() -> Option<ffi::binaryfunc>;
+ }
+
+-impl<'p, T> PySequenceInplaceConcatProtocolImpl for T
+-where
+- T: PySequenceProtocol<'p>,
+-{
++impl<'p, T> PySequenceInplaceConcatProtocolImpl for T where T: PySequenceProtocol<'p> {
+ default fn sq_inplace_concat() -> Option<ffi::binaryfunc> {
+ None
+ }
+@@ -510,10 +486,7 @@ trait PySequenceInplaceRepeatProtocolImpl {
+ fn sq_inplace_repeat() -> Option<ffi::ssizeargfunc>;
+ }
+
+-impl<'p, T> PySequenceInplaceRepeatProtocolImpl for T
+-where
+- T: PySequenceProtocol<'p>,
+-{
++impl<'p, T> PySequenceInplaceRepeatProtocolImpl for T where T: PySequenceProtocol<'p> {
+ default fn sq_inplace_repeat() -> Option<ffi::ssizeargfunc> {
+ None
+ }
+diff --git a/src/conversion.rs b/src/conversion.rs
+index 38f436de4..15ccdabde 100644
+--- a/src/conversion.rs
++++ b/src/conversion.rs
+@@ -100,10 +100,7 @@ pub trait ToBorrowedObject: ToPyObject {
+ F: FnOnce(*mut ffi::PyObject) -> R;
+ }
+
+-impl<T> ToBorrowedObject for T
+-where
+- T: ToPyObject,
+-{
++impl<T> ToBorrowedObject for T where T: ToPyObject {
+ default fn with_borrowed_ptr<F, R>(&self, py: Python, f: F) -> R
+ where
+ F: FnOnce(*mut ffi::PyObject) -> R,
diff --git a/srcpkgs/anki/files/pyo3-patches/0011-specialization-89c028e23ab3dab4eaa2277734019f1b8e0210c1.patch b/srcpkgs/anki/files/pyo3-patches/0011-specialization-89c028e23ab3dab4eaa2277734019f1b8e0210c1.patch
new file mode 100644
index 00000000000..ff6e46229e8
--- /dev/null
+++ b/srcpkgs/anki/files/pyo3-patches/0011-specialization-89c028e23ab3dab4eaa2277734019f1b8e0210c1.patch
@@ -0,0 +1,1978 @@
+From 89c028e23ab3dab4eaa2277734019f1b8e0210c1 Mon Sep 17 00:00:00 2001
+From: Martin Donlon <github-martin@donlons.com>
+Date: Fri, 25 Oct 2019 20:52:10 -0700
+Subject: [PATCH] Revert "Fix broken specialized implementations with Rust
+ 1.40"
+
+This reverts commit 5397a62f486a25b2f99aac7aa758161b993af6ae.
+---
+ src/class/basic.rs | 94 ++++------
+ src/class/buffer.rs | 16 +-
+ src/class/context.rs | 24 +--
+ src/class/descr.rs | 23 +--
+ src/class/gc.rs | 22 +--
+ src/class/iter.rs | 22 +--
+ src/class/mapping.rs | 75 +++-----
+ src/class/number.rs | 403 ++++++++++++++++--------------------------
+ src/class/pyasync.rs | 51 ++----
+ src/class/sequence.rs | 80 ++++-----
+ src/conversion.rs | 8 +-
+ src/instance.rs | 39 ++--
+ 12 files changed, 319 insertions(+), 538 deletions(-)
+
+diff --git a/src/class/basic.rs b/src/class/basic.rs
+index 29e19871f..c3153dfa3 100644
+--- a/src/class/basic.rs
++++ b/src/class/basic.rs
+@@ -152,21 +152,17 @@ pub trait PyObjectRichcmpProtocol<'p>: PyObjectProtocol<'p> {
+
+ #[doc(hidden)]
+ pub trait PyObjectProtocolImpl {
+- fn methods() -> Vec<PyMethodDef>;
+- fn tp_as_object(_type_object: &mut ffi::PyTypeObject);
+- fn nb_bool_fn() -> Option<ffi::inquiry>;
+-}
+-
+-impl<T> PyObjectProtocolImpl for T {
+- default fn methods() -> Vec<PyMethodDef> {
++ fn methods() -> Vec<PyMethodDef> {
+ Vec::new()
+ }
+- default fn tp_as_object(_type_object: &mut ffi::PyTypeObject) {}
+- default fn nb_bool_fn() -> Option<ffi::inquiry> {
++ fn tp_as_object(_type_object: &mut ffi::PyTypeObject) {}
++ fn nb_bool_fn() -> Option<ffi::inquiry> {
+ None
+ }
+ }
+
++impl<T> PyObjectProtocolImpl for T {}
++
+ impl<'p, T> PyObjectProtocolImpl for T
+ where
+ T: PyObjectProtocol<'p>,
+@@ -199,15 +195,13 @@ where
+ }
+
+ trait GetAttrProtocolImpl {
+- fn tp_getattro() -> Option<ffi::binaryfunc>;
+-}
+-
+-impl<'p, T> GetAttrProtocolImpl for T where T: PyObjectProtocol<'p> {
+- default fn tp_getattro() -> Option<ffi::binaryfunc> {
++ fn tp_getattro() -> Option<ffi::binaryfunc> {
+ None
+ }
+ }
+
++impl<'p, T> GetAttrProtocolImpl for T where T: PyObjectProtocol<'p> {}
++
+ impl<T> GetAttrProtocolImpl for T
+ where
+ T: for<'p> PyObjectGetAttrProtocol<'p>,
+@@ -274,15 +268,13 @@ mod tp_setattro_impl {
+ }
+
+ trait SetAttr {
+- fn set_attr() -> Option<ffi::setattrofunc>;
+- }
+-
+- impl<'p, T: PyObjectProtocol<'p>> SetAttr for T {
+- default fn set_attr() -> Option<ffi::setattrofunc> {
++ fn set_attr() -> Option<ffi::setattrofunc> {
+ None
+ }
+ }
+
++ impl<'p, T: PyObjectProtocol<'p>> SetAttr for T {}
++
+ impl<T> SetAttr for T
+ where
+ T: for<'p> PyObjectSetAttrProtocol<'p>,
+@@ -293,15 +285,13 @@ mod tp_setattro_impl {
+ }
+
+ trait DelAttr {
+- fn del_attr() -> Option<ffi::setattrofunc>;
+- }
+-
+- impl<'p, T> DelAttr for T where T: PyObjectProtocol<'p> {
+- default fn del_attr() -> Option<ffi::setattrofunc> {
++ fn del_attr() -> Option<ffi::setattrofunc> {
+ None
+ }
+ }
+
++ impl<'p, T> DelAttr for T where T: PyObjectProtocol<'p> {}
++
+ impl<T> DelAttr for T
+ where
+ T: for<'p> PyObjectDelAttrProtocol<'p>,
+@@ -312,15 +302,13 @@ mod tp_setattro_impl {
+ }
+
+ trait SetDelAttr {
+- fn set_del_attr() -> Option<ffi::setattrofunc>;
+- }
+-
+- impl<'p, T> SetDelAttr for T where T: PyObjectProtocol<'p> {
+- default fn set_del_attr() -> Option<ffi::setattrofunc> {
++ fn set_del_attr() -> Option<ffi::setattrofunc> {
+ None
+ }
+ }
+
++ impl<'p, T> SetDelAttr for T where T: PyObjectProtocol<'p> {}
++
+ impl<T> SetDelAttr for T
+ where
+ T: for<'p> PyObjectSetAttrProtocol<'p> + for<'p> PyObjectDelAttrProtocol<'p>,
+@@ -338,13 +326,11 @@ mod tp_setattro_impl {
+ }
+
+ trait StrProtocolImpl {
+- fn tp_str() -> Option<ffi::unaryfunc>;
+-}
+-impl<'p, T> StrProtocolImpl for T where T: PyObjectProtocol<'p> {
+- default fn tp_str() -> Option<ffi::unaryfunc> {
++ fn tp_str() -> Option<ffi::unaryfunc> {
+ None
+ }
+ }
++impl<'p, T> StrProtocolImpl for T where T: PyObjectProtocol<'p> {}
+ impl<T> StrProtocolImpl for T
+ where
+ T: for<'p> PyObjectStrProtocol<'p>,
+@@ -360,13 +346,11 @@ where
+ }
+
+ trait ReprProtocolImpl {
+- fn tp_repr() -> Option<ffi::unaryfunc>;
+-}
+-impl<'p, T> ReprProtocolImpl for T where T: PyObjectProtocol<'p> {
+- default fn tp_repr() -> Option<ffi::unaryfunc> {
++ fn tp_repr() -> Option<ffi::unaryfunc> {
+ None
+ }
+ }
++impl<'p, T> ReprProtocolImpl for T where T: PyObjectProtocol<'p> {}
+ impl<T> ReprProtocolImpl for T
+ where
+ T: for<'p> PyObjectReprProtocol<'p>,
+@@ -383,42 +367,34 @@ where
+
+ #[doc(hidden)]
+ pub trait FormatProtocolImpl {
+- fn __format__() -> Option<PyMethodDef>;
+-}
+-impl<'p, T> FormatProtocolImpl for T where T: PyObjectProtocol<'p> {
+- default fn __format__() -> Option<PyMethodDef> {
++ fn __format__() -> Option<PyMethodDef> {
+ None
+ }
+ }
++impl<'p, T> FormatProtocolImpl for T where T: PyObjectProtocol<'p> {}
+
+ #[doc(hidden)]
+ pub trait BytesProtocolImpl {
+- fn __bytes__() -> Option<PyMethodDef>;
+-}
+-impl<'p, T> BytesProtocolImpl for T where T: PyObjectProtocol<'p> {
+- default fn __bytes__() -> Option<PyMethodDef> {
++ fn __bytes__() -> Option<PyMethodDef> {
+ None
+ }
+ }
++impl<'p, T> BytesProtocolImpl for T where T: PyObjectProtocol<'p> {}
+
+ #[doc(hidden)]
+ pub trait UnicodeProtocolImpl {
+- fn __unicode__() -> Option<PyMethodDef>;
+-}
+-impl<'p, T> UnicodeProtocolImpl for T where T: PyObjectProtocol<'p> {
+- default fn __unicode__() -> Option<PyMethodDef> {
++ fn __unicode__() -> Option<PyMethodDef> {
+ None
+ }
+ }
++impl<'p, T> UnicodeProtocolImpl for T where T: PyObjectProtocol<'p> {}
+
+ trait HashProtocolImpl {
+- fn tp_hash() -> Option<ffi::hashfunc>;
+-}
+-impl<'p, T> HashProtocolImpl for T where T: PyObjectProtocol<'p> {
+- default fn tp_hash() -> Option<ffi::hashfunc> {
++ fn tp_hash() -> Option<ffi::hashfunc> {
+ None
+ }
+ }
++impl<'p, T> HashProtocolImpl for T where T: PyObjectProtocol<'p> {}
+ impl<T> HashProtocolImpl for T
+ where
+ T: for<'p> PyObjectHashProtocol<'p>,
+@@ -435,13 +411,11 @@ where
+ }
+
+ trait BoolProtocolImpl {
+- fn nb_bool() -> Option<ffi::inquiry>;
+-}
+-impl<'p, T> BoolProtocolImpl for T where T: PyObjectProtocol<'p> {
+- default fn nb_bool() -> Option<ffi::inquiry> {
++ fn nb_bool() -> Option<ffi::inquiry> {
+ None
+ }
+ }
++impl<'p, T> BoolProtocolImpl for T where T: PyObjectProtocol<'p> {}
+ impl<T> BoolProtocolImpl for T
+ where
+ T: for<'p> PyObjectBoolProtocol<'p>,
+@@ -458,13 +432,11 @@ where
+ }
+
+ trait RichcmpProtocolImpl {
+- fn tp_richcompare() -> Option<ffi::richcmpfunc>;
+-}
+-impl<'p, T> RichcmpProtocolImpl for T where T: PyObjectProtocol<'p> {
+- default fn tp_richcompare() -> Option<ffi::richcmpfunc> {
++ fn tp_richcompare() -> Option<ffi::richcmpfunc> {
+ None
+ }
+ }
++impl<'p, T> RichcmpProtocolImpl for T where T: PyObjectProtocol<'p> {}
+ impl<T> RichcmpProtocolImpl for T
+ where
+ T: for<'p> PyObjectRichcmpProtocol<'p>,
+diff --git a/src/class/buffer.rs b/src/class/buffer.rs
+index c30f078cc..d36524e7c 100644
+--- a/src/class/buffer.rs
++++ b/src/class/buffer.rs
+@@ -41,15 +41,13 @@ pub trait PyBufferReleaseBufferProtocol<'p>: PyBufferProtocol<'p> {
+
+ #[doc(hidden)]
+ pub trait PyBufferProtocolImpl {
+- fn tp_as_buffer() -> Option<ffi::PyBufferProcs>;
+-}
+-
+-impl<T> PyBufferProtocolImpl for T {
+- default fn tp_as_buffer() -> Option<ffi::PyBufferProcs> {
++ fn tp_as_buffer() -> Option<ffi::PyBufferProcs> {
+ None
+ }
+ }
+
++impl<T> PyBufferProtocolImpl for T {}
++
+ impl<'p, T> PyBufferProtocolImpl for T
+ where
+ T: PyBufferProtocol<'p>,
+@@ -66,15 +64,13 @@ where
+ }
+
+ trait PyBufferGetBufferProtocolImpl {
+- fn cb_bf_getbuffer() -> Option<ffi::getbufferproc>;
+-}
+-
+-impl<'p, T> PyBufferGetBufferProtocolImpl for T where T: PyBufferProtocol<'p> {
+- default fn cb_bf_getbuffer() -> Option<ffi::getbufferproc> {
++ fn cb_bf_getbuffer() -> Option<ffi::getbufferproc> {
+ None
+ }
+ }
+
++impl<'p, T> PyBufferGetBufferProtocolImpl for T where T: PyBufferProtocol<'p> {}
++
+ impl<T> PyBufferGetBufferProtocolImpl for T
+ where
+ T: for<'p> PyBufferGetBufferProtocol<'p>,
+diff --git a/src/class/context.rs b/src/class/context.rs
+index 2ad59768d..092527ba0 100644
+--- a/src/class/context.rs
++++ b/src/class/context.rs
+@@ -47,15 +47,13 @@ pub trait PyContextExitProtocol<'p>: PyContextProtocol<'p> {
+
+ #[doc(hidden)]
+ pub trait PyContextProtocolImpl {
+- fn methods() -> Vec<PyMethodDef>;
+-}
+-
+-impl<T> PyContextProtocolImpl for T {
+- default fn methods() -> Vec<PyMethodDef> {
++ fn methods() -> Vec<PyMethodDef> {
+ Vec::new()
+ }
+ }
+
++impl<T> PyContextProtocolImpl for T {}
++
+ impl<'p, T> PyContextProtocolImpl for T
+ where
+ T: PyContextProtocol<'p>,
+@@ -77,22 +75,18 @@ where
+
+ #[doc(hidden)]
+ pub trait PyContextEnterProtocolImpl {
+- fn __enter__() -> Option<PyMethodDef>;
+-}
+-
+-impl<'p, T> PyContextEnterProtocolImpl for T where T: PyContextProtocol<'p> {
+- default fn __enter__() -> Option<PyMethodDef> {
++ fn __enter__() -> Option<PyMethodDef> {
+ None
+ }
+ }
+
++impl<'p, T> PyContextEnterProtocolImpl for T where T: PyContextProtocol<'p> {}
++
+ #[doc(hidden)]
+ pub trait PyContextExitProtocolImpl {
+- fn __exit__() -> Option<PyMethodDef>;
+-}
+-
+-impl<'p, T> PyContextExitProtocolImpl for T where T: PyContextProtocol<'p> {
+- default fn __exit__() -> Option<PyMethodDef> {
++ fn __exit__() -> Option<PyMethodDef> {
+ None
+ }
+ }
++
++impl<'p, T> PyContextExitProtocolImpl for T where T: PyContextProtocol<'p> {}
+diff --git a/src/class/descr.rs b/src/class/descr.rs
+index c7b5b9660..5f7e68306 100644
+--- a/src/class/descr.rs
++++ b/src/class/descr.rs
+@@ -70,13 +70,11 @@ pub trait PyDescrSetNameProtocol<'p>: PyDescrProtocol<'p> {
+ }
+
+ trait PyDescrGetProtocolImpl {
+- fn tp_descr_get() -> Option<ffi::descrgetfunc>;
+-}
+-impl<'p, T> PyDescrGetProtocolImpl for T where T: PyDescrProtocol<'p> {
+- default fn tp_descr_get() -> Option<ffi::descrgetfunc> {
++ fn tp_descr_get() -> Option<ffi::descrgetfunc> {
+ None
+ }
+ }
++impl<'p, T> PyDescrGetProtocolImpl for T where T: PyDescrProtocol<'p> {}
+
+ impl<T> PyDescrGetProtocolImpl for T
+ where
+@@ -93,13 +91,11 @@ where
+ }
+
+ trait PyDescrSetProtocolImpl {
+- fn tp_descr_set() -> Option<ffi::descrsetfunc>;
+-}
+-impl<'p, T> PyDescrSetProtocolImpl for T where T: PyDescrProtocol<'p> {
+- default fn tp_descr_set() -> Option<ffi::descrsetfunc> {
++ fn tp_descr_set() -> Option<ffi::descrsetfunc> {
+ None
+ }
+ }
++impl<'p, T> PyDescrSetProtocolImpl for T where T: PyDescrProtocol<'p> {}
+ impl<T> PyDescrSetProtocolImpl for T
+ where
+ T: for<'p> PyDescrSetProtocol<'p>,
+@@ -131,17 +127,14 @@ impl<'p, T> PyDescrSetNameProtocolImpl for T where T: PyDescrProtocol<'p> {}
+
+ #[doc(hidden)]
+ pub trait PyDescrProtocolImpl {
+- fn methods() -> Vec<PyMethodDef>;
+- fn tp_as_descr(_type_object: &mut ffi::PyTypeObject);
+-}
+-
+-impl<T> PyDescrProtocolImpl for T {
+- default fn methods() -> Vec<PyMethodDef> {
++ fn methods() -> Vec<PyMethodDef> {
+ Vec::new()
+ }
+- default fn tp_as_descr(_type_object: &mut ffi::PyTypeObject) {}
++ fn tp_as_descr(_type_object: &mut ffi::PyTypeObject) {}
+ }
+
++impl<T> PyDescrProtocolImpl for T {}
++
+ impl<'p, T> PyDescrProtocolImpl for T
+ where
+ T: PyDescrProtocol<'p>,
+diff --git a/src/class/gc.rs b/src/class/gc.rs
+index 4b69c9643..eaa4d9015 100644
+--- a/src/class/gc.rs
++++ b/src/class/gc.rs
+@@ -23,12 +23,10 @@ pub trait PyGCClearProtocol<'p>: PyGCProtocol<'p> {}
+
+ #[doc(hidden)]
+ pub trait PyGCProtocolImpl {
+- fn update_type_object(_type_object: &mut ffi::PyTypeObject);
++ fn update_type_object(_type_object: &mut ffi::PyTypeObject) {}
+ }
+
+-impl<'p, T> PyGCProtocolImpl for T {
+- default fn update_type_object(_type_object: &mut ffi::PyTypeObject) {}
+-}
++impl<'p, T> PyGCProtocolImpl for T {}
+
+ impl<'p, T> PyGCProtocolImpl for T
+ where
+@@ -65,15 +63,13 @@ impl<'p> PyVisit<'p> {
+ }
+
+ trait PyGCTraverseProtocolImpl {
+- fn tp_traverse() -> Option<ffi::traverseproc>;
+-}
+-
+-impl<'p, T> PyGCTraverseProtocolImpl for T where T: PyGCProtocol<'p> {
+- default fn tp_traverse() -> Option<ffi::traverseproc> {
++ fn tp_traverse() -> Option<ffi::traverseproc> {
+ None
+ }
+ }
+
++impl<'p, T> PyGCTraverseProtocolImpl for T where T: PyGCProtocol<'p> {}
++
+ #[doc(hidden)]
+ impl<T> PyGCTraverseProtocolImpl for T
+ where
+@@ -109,15 +105,13 @@ where
+ }
+
+ trait PyGCClearProtocolImpl {
+- fn tp_clear() -> Option<ffi::inquiry>;
+-}
+-
+-impl<'p, T> PyGCClearProtocolImpl for T where T: PyGCProtocol<'p> {
+- default fn tp_clear() -> Option<ffi::inquiry> {
++ fn tp_clear() -> Option<ffi::inquiry> {
+ None
+ }
+ }
+
++impl<'p, T> PyGCClearProtocolImpl for T where T: PyGCProtocol<'p> {}
++
+ impl<T> PyGCClearProtocolImpl for T
+ where
+ T: for<'p> PyGCClearProtocol<'p>,
+diff --git a/src/class/iter.rs b/src/class/iter.rs
+index fcf76f2e5..9001d53ce 100644
+--- a/src/class/iter.rs
++++ b/src/class/iter.rs
+@@ -44,12 +44,10 @@ pub trait PyIterNextProtocol<'p>: PyIterProtocol<'p> {
+
+ #[doc(hidden)]
+ pub trait PyIterProtocolImpl {
+- fn tp_as_iter(_typeob: &mut ffi::PyTypeObject);
++ fn tp_as_iter(_typeob: &mut ffi::PyTypeObject) {}
+ }
+
+-impl<T> PyIterProtocolImpl for T {
+- default fn tp_as_iter(_typeob: &mut ffi::PyTypeObject) {}
+-}
++impl<T> PyIterProtocolImpl for T {}
+
+ impl<'p, T> PyIterProtocolImpl for T
+ where
+@@ -63,15 +61,13 @@ where
+ }
+
+ trait PyIterIterProtocolImpl {
+- fn tp_iter() -> Option<ffi::getiterfunc>;
+-}
+-
+-impl<'p, T> PyIterIterProtocolImpl for T where T: PyIterProtocol<'p> {
+- default fn tp_iter() -> Option<ffi::getiterfunc> {
++ fn tp_iter() -> Option<ffi::getiterfunc> {
+ None
+ }
+ }
+
++impl<'p, T> PyIterIterProtocolImpl for T where T: PyIterProtocol<'p> {}
++
+ impl<T> PyIterIterProtocolImpl for T
+ where
+ T: for<'p> PyIterIterProtocol<'p>,
+@@ -88,15 +84,13 @@ where
+ }
+
+ trait PyIterNextProtocolImpl {
+- fn tp_iternext() -> Option<ffi::iternextfunc>;
+-}
+-
+-impl<'p, T> PyIterNextProtocolImpl for T where T: PyIterProtocol<'p> {
+- default fn tp_iternext() -> Option<ffi::iternextfunc> {
++ fn tp_iternext() -> Option<ffi::iternextfunc> {
+ None
+ }
+ }
+
++impl<'p, T> PyIterNextProtocolImpl for T where T: PyIterProtocol<'p> {}
++
+ impl<T> PyIterNextProtocolImpl for T
+ where
+ T: for<'p> PyIterNextProtocol<'p>,
+diff --git a/src/class/mapping.rs b/src/class/mapping.rs
+index 64d7b57ce..616763502 100644
+--- a/src/class/mapping.rs
++++ b/src/class/mapping.rs
+@@ -106,19 +106,16 @@ pub trait PyMappingReversedProtocol<'p>: PyMappingProtocol<'p> {
+
+ #[doc(hidden)]
+ pub trait PyMappingProtocolImpl {
+- fn tp_as_mapping() -> Option<ffi::PyMappingMethods>;
+- fn methods() -> Vec<PyMethodDef>;
+-}
+-
+-impl<T> PyMappingProtocolImpl for T {
+- default fn tp_as_mapping() -> Option<ffi::PyMappingMethods> {
++ fn tp_as_mapping() -> Option<ffi::PyMappingMethods> {
+ None
+ }
+- default fn methods() -> Vec<PyMethodDef> {
++ fn methods() -> Vec<PyMethodDef> {
+ Vec::new()
+ }
+ }
+
++impl<T> PyMappingProtocolImpl for T {}
++
+ impl<'p, T> PyMappingProtocolImpl for T
+ where
+ T: PyMappingProtocol<'p>,
+@@ -157,15 +154,13 @@ where
+ }
+
+ trait PyMappingLenProtocolImpl {
+- fn mp_length() -> Option<ffi::lenfunc>;
+-}
+-
+-impl<'p, T> PyMappingLenProtocolImpl for T where T: PyMappingProtocol<'p> {
+- default fn mp_length() -> Option<ffi::lenfunc> {
++ fn mp_length() -> Option<ffi::lenfunc> {
+ None
+ }
+ }
+
++impl<'p, T> PyMappingLenProtocolImpl for T where T: PyMappingProtocol<'p> {}
++
+ impl<T> PyMappingLenProtocolImpl for T
+ where
+ T: for<'p> PyMappingLenProtocol<'p>,
+@@ -177,15 +172,13 @@ where
+ }
+
+ trait PyMappingGetItemProtocolImpl {
+- fn mp_subscript() -> Option<ffi::binaryfunc>;
+-}
+-
+-impl<'p, T> PyMappingGetItemProtocolImpl for T where T: PyMappingProtocol<'p> {
+- default fn mp_subscript() -> Option<ffi::binaryfunc> {
++ fn mp_subscript() -> Option<ffi::binaryfunc> {
+ None
+ }
+ }
+
++impl<'p, T> PyMappingGetItemProtocolImpl for T where T: PyMappingProtocol<'p> {}
++
+ impl<T> PyMappingGetItemProtocolImpl for T
+ where
+ T: for<'p> PyMappingGetItemProtocol<'p>,
+@@ -202,15 +195,13 @@ where
+ }
+
+ trait PyMappingSetItemProtocolImpl {
+- fn mp_ass_subscript() -> Option<ffi::objobjargproc>;
+-}
+-
+-impl<'p, T> PyMappingSetItemProtocolImpl for T where T: PyMappingProtocol<'p> {
+- default fn mp_ass_subscript() -> Option<ffi::objobjargproc> {
++ fn mp_ass_subscript() -> Option<ffi::objobjargproc> {
+ None
+ }
+ }
+
++impl<'p, T> PyMappingSetItemProtocolImpl for T where T: PyMappingProtocol<'p> {}
++
+ impl<T> PyMappingSetItemProtocolImpl for T
+ where
+ T: for<'p> PyMappingSetItemProtocol<'p>,
+@@ -224,26 +215,22 @@ where
+ /// Returns `None` if PyMappingDelItemProtocol isn't implemented, otherwise dispatches to
+ /// `DelSetItemDispatch`
+ trait DeplItemDipatch {
+- fn mp_del_subscript() -> Option<ffi::objobjargproc>;
+-}
+-
+-impl<'p, T> DeplItemDipatch for T where T: PyMappingProtocol<'p> {
+- default fn mp_del_subscript() -> Option<ffi::objobjargproc> {
++ fn mp_del_subscript() -> Option<ffi::objobjargproc> {
+ None
+ }
+ }
+
++impl<'p, T> DeplItemDipatch for T where T: PyMappingProtocol<'p> {}
++
+ /// Returns `py_func_set_del` if PyMappingSetItemProtocol is implemented, otherwise `py_func_del`
+ trait DelSetItemDispatch: Sized + for<'p> PyMappingDelItemProtocol<'p> {
+- fn det_set_dispatch() -> Option<ffi::objobjargproc>;
+-}
+-
+-impl<T> DelSetItemDispatch for T where T: Sized + for<'p> PyMappingDelItemProtocol<'p> {
+- default fn det_set_dispatch() -> Option<ffi::objobjargproc> {
++ fn det_set_dispatch() -> Option<ffi::objobjargproc> {
+ py_func_del!(PyMappingDelItemProtocol, Self, __delitem__)
+ }
+ }
+
++impl<T> DelSetItemDispatch for T where T: Sized + for<'p> PyMappingDelItemProtocol<'p> {}
++
+ impl<T> DelSetItemDispatch for T
+ where
+ T: for<'p> PyMappingSetItemProtocol<'p> + for<'p> PyMappingDelItemProtocol<'p>,
+@@ -270,33 +257,27 @@ where
+
+ #[doc(hidden)]
+ pub trait PyMappingContainsProtocolImpl {
+- fn __contains__() -> Option<PyMethodDef>;
+-}
+-
+-impl<'p, T> PyMappingContainsProtocolImpl for T where T: PyMappingProtocol<'p> {
+- default fn __contains__() -> Option<PyMethodDef> {
++ fn __contains__() -> Option<PyMethodDef> {
+ None
+ }
+ }
+
++impl<'p, T> PyMappingContainsProtocolImpl for T where T: PyMappingProtocol<'p> {}
++
+ #[doc(hidden)]
+ pub trait PyMappingReversedProtocolImpl {
+- fn __reversed__() -> Option<PyMethodDef>;
+-}
+-
+-impl<'p, T> PyMappingReversedProtocolImpl for T where T: PyMappingProtocol<'p> {
+- default fn __reversed__() -> Option<PyMethodDef> {
++ fn __reversed__() -> Option<PyMethodDef> {
+ None
+ }
+ }
+
++impl<'p, T> PyMappingReversedProtocolImpl for T where T: PyMappingProtocol<'p> {}
++
+ #[doc(hidden)]
+ pub trait PyMappingIterProtocolImpl {
+- fn __iter__() -> Option<PyMethodDef>;
+-}
+-
+-impl<'p, T> PyMappingIterProtocolImpl for T where T: PyMappingProtocol<'p> {
+- default fn __iter__() -> Option<PyMethodDef> {
++ fn __iter__() -> Option<PyMethodDef> {
+ None
+ }
+ }
++
++impl<'p, T> PyMappingIterProtocolImpl for T where T: PyMappingProtocol<'p> {}
+diff --git a/src/class/number.rs b/src/class/number.rs
+index 0ab162e72..2ee3a57d5 100644
+--- a/src/class/number.rs
++++ b/src/class/number.rs
+@@ -622,15 +622,10 @@ pub trait PyNumberIndexProtocol<'p>: PyNumberProtocol<'p> {
+
+ #[doc(hidden)]
+ pub trait PyNumberProtocolImpl: PyObjectProtocolImpl {
+- fn methods() -> Vec<PyMethodDef>;
+- fn tp_as_number() -> Option<ffi::PyNumberMethods>;
+-}
+-
+-impl<'p, T> PyNumberProtocolImpl for T {
+- default fn methods() -> Vec<PyMethodDef> {
++ fn methods() -> Vec<PyMethodDef> {
+ Vec::new()
+ }
+- default fn tp_as_number() -> Option<ffi::PyNumberMethods> {
++ fn tp_as_number() -> Option<ffi::PyNumberMethods> {
+ if let Some(nb_bool) = <Self as PyObjectProtocolImpl>::nb_bool_fn() {
+ let meth = ffi::PyNumberMethods {
+ nb_bool: Some(nb_bool),
+@@ -643,6 +638,8 @@ impl<'p, T> PyNumberProtocolImpl for T {
+ }
+ }
+
++impl<'p, T> PyNumberProtocolImpl for T {}
++
+ impl<'p, T> PyNumberProtocolImpl for T
+ where
+ T: PyNumberProtocol<'p>,
+@@ -746,15 +743,13 @@ where
+ }
+
+ trait PyNumberAddProtocolImpl {
+- fn nb_add() -> Option<ffi::binaryfunc>;
+-}
+-
+-impl<'p, T> PyNumberAddProtocolImpl for T where T: PyNumberProtocol<'p> {
+- default fn nb_add() -> Option<ffi::binaryfunc> {
++ fn nb_add() -> Option<ffi::binaryfunc> {
+ None
+ }
+ }
+
++impl<'p, T> PyNumberAddProtocolImpl for T where T: PyNumberProtocol<'p> {}
++
+ impl<T> PyNumberAddProtocolImpl for T
+ where
+ T: for<'p> PyNumberAddProtocol<'p>,
+@@ -770,15 +765,13 @@ where
+ }
+
+ trait PyNumberSubProtocolImpl {
+- fn nb_subtract() -> Option<ffi::binaryfunc>;
+-}
+-
+-impl<'p, T> PyNumberSubProtocolImpl for T where T: PyNumberProtocol<'p> {
+- default fn nb_subtract() -> Option<ffi::binaryfunc> {
++ fn nb_subtract() -> Option<ffi::binaryfunc> {
+ None
+ }
+ }
+
++impl<'p, T> PyNumberSubProtocolImpl for T where T: PyNumberProtocol<'p> {}
++
+ impl<T> PyNumberSubProtocolImpl for T
+ where
+ T: for<'p> PyNumberSubProtocol<'p>,
+@@ -794,15 +787,13 @@ where
+ }
+
+ trait PyNumberMulProtocolImpl {
+- fn nb_multiply() -> Option<ffi::binaryfunc>;
+-}
+-
+-impl<'p, T> PyNumberMulProtocolImpl for T where T: PyNumberProtocol<'p> {
+- default fn nb_multiply() -> Option<ffi::binaryfunc> {
++ fn nb_multiply() -> Option<ffi::binaryfunc> {
+ None
+ }
+ }
+
++impl<'p, T> PyNumberMulProtocolImpl for T where T: PyNumberProtocol<'p> {}
++
+ impl<T> PyNumberMulProtocolImpl for T
+ where
+ T: for<'p> PyNumberMulProtocol<'p>,
+@@ -818,15 +809,13 @@ where
+ }
+
+ trait PyNumberMatmulProtocolImpl {
+- fn nb_matrix_multiply() -> Option<ffi::binaryfunc>;
+-}
+-
+-impl<'p, T> PyNumberMatmulProtocolImpl for T where T: PyNumberProtocol<'p> {
+- default fn nb_matrix_multiply() -> Option<ffi::binaryfunc> {
++ fn nb_matrix_multiply() -> Option<ffi::binaryfunc> {
+ None
+ }
+ }
+
++impl<'p, T> PyNumberMatmulProtocolImpl for T where T: PyNumberProtocol<'p> {}
++
+ impl<T> PyNumberMatmulProtocolImpl for T
+ where
+ T: for<'p> PyNumberMatmulProtocol<'p>,
+@@ -842,15 +831,13 @@ where
+ }
+
+ trait PyNumberTruedivProtocolImpl {
+- fn nb_true_divide() -> Option<ffi::binaryfunc>;
+-}
+-
+-impl<'p, T> PyNumberTruedivProtocolImpl for T where T: PyNumberProtocol<'p> {
+- default fn nb_true_divide() -> Option<ffi::binaryfunc> {
++ fn nb_true_divide() -> Option<ffi::binaryfunc> {
+ None
+ }
+ }
+
++impl<'p, T> PyNumberTruedivProtocolImpl for T where T: PyNumberProtocol<'p> {}
++
+ impl<T> PyNumberTruedivProtocolImpl for T
+ where
+ T: for<'p> PyNumberTruedivProtocol<'p>,
+@@ -866,15 +853,13 @@ where
+ }
+
+ trait PyNumberFloordivProtocolImpl {
+- fn nb_floor_divide() -> Option<ffi::binaryfunc>;
+-}
+-
+-impl<'p, T> PyNumberFloordivProtocolImpl for T where T: PyNumberProtocol<'p> {
+- default fn nb_floor_divide() -> Option<ffi::binaryfunc> {
++ fn nb_floor_divide() -> Option<ffi::binaryfunc> {
+ None
+ }
+ }
+
++impl<'p, T> PyNumberFloordivProtocolImpl for T where T: PyNumberProtocol<'p> {}
++
+ impl<T> PyNumberFloordivProtocolImpl for T
+ where
+ T: for<'p> PyNumberFloordivProtocol<'p>,
+@@ -890,15 +875,13 @@ where
+ }
+
+ trait PyNumberModProtocolImpl {
+- fn nb_remainder() -> Option<ffi::binaryfunc>;
+-}
+-
+-impl<'p, T> PyNumberModProtocolImpl for T where T: PyNumberProtocol<'p> {
+- default fn nb_remainder() -> Option<ffi::binaryfunc> {
++ fn nb_remainder() -> Option<ffi::binaryfunc> {
+ None
+ }
+ }
+
++impl<'p, T> PyNumberModProtocolImpl for T where T: PyNumberProtocol<'p> {}
++
+ impl<T> PyNumberModProtocolImpl for T
+ where
+ T: for<'p> PyNumberModProtocol<'p>,
+@@ -914,15 +897,13 @@ where
+ }
+
+ trait PyNumberDivmodProtocolImpl {
+- fn nb_divmod() -> Option<ffi::binaryfunc>;
+-}
+-
+-impl<'p, T> PyNumberDivmodProtocolImpl for T where T: PyNumberProtocol<'p> {
+- default fn nb_divmod() -> Option<ffi::binaryfunc> {
++ fn nb_divmod() -> Option<ffi::binaryfunc> {
+ None
+ }
+ }
+
++impl<'p, T> PyNumberDivmodProtocolImpl for T where T: PyNumberProtocol<'p> {}
++
+ impl<T> PyNumberDivmodProtocolImpl for T
+ where
+ T: for<'p> PyNumberDivmodProtocol<'p>,
+@@ -938,15 +919,13 @@ where
+ }
+
+ trait PyNumberPowProtocolImpl {
+- fn nb_power() -> Option<ffi::ternaryfunc>;
+-}
+-
+-impl<'p, T> PyNumberPowProtocolImpl for T where T: PyNumberProtocol<'p> {
+- default fn nb_power() -> Option<ffi::ternaryfunc> {
++ fn nb_power() -> Option<ffi::ternaryfunc> {
+ None
+ }
+ }
+
++impl<'p, T> PyNumberPowProtocolImpl for T where T: PyNumberProtocol<'p> {}
++
+ impl<T> PyNumberPowProtocolImpl for T
+ where
+ T: for<'p> PyNumberPowProtocol<'p>,
+@@ -962,15 +941,13 @@ where
+ }
+
+ trait PyNumberLShiftProtocolImpl {
+- fn nb_lshift() -> Option<ffi::binaryfunc>;
+-}
+-
+-impl<'p, T> PyNumberLShiftProtocolImpl for T where T: PyNumberProtocol<'p> {
+- default fn nb_lshift() -> Option<ffi::binaryfunc> {
++ fn nb_lshift() -> Option<ffi::binaryfunc> {
+ None
+ }
+ }
+
++impl<'p, T> PyNumberLShiftProtocolImpl for T where T: PyNumberProtocol<'p> {}
++
+ impl<T> PyNumberLShiftProtocolImpl for T
+ where
+ T: for<'p> PyNumberLShiftProtocol<'p>,
+@@ -986,15 +963,13 @@ where
+ }
+
+ trait PyNumberRShiftProtocolImpl {
+- fn nb_rshift() -> Option<ffi::binaryfunc>;
+-}
+-
+-impl<'p, T> PyNumberRShiftProtocolImpl for T where T: PyNumberProtocol<'p> {
+- default fn nb_rshift() -> Option<ffi::binaryfunc> {
++ fn nb_rshift() -> Option<ffi::binaryfunc> {
+ None
+ }
+ }
+
++impl<'p, T> PyNumberRShiftProtocolImpl for T where T: PyNumberProtocol<'p> {}
++
+ impl<T> PyNumberRShiftProtocolImpl for T
+ where
+ T: for<'p> PyNumberRShiftProtocol<'p>,
+@@ -1010,15 +985,13 @@ where
+ }
+
+ trait PyNumberAndProtocolImpl {
+- fn nb_and() -> Option<ffi::binaryfunc>;
+-}
+-
+-impl<'p, T> PyNumberAndProtocolImpl for T where T: PyNumberProtocol<'p> {
+- default fn nb_and() -> Option<ffi::binaryfunc> {
++ fn nb_and() -> Option<ffi::binaryfunc> {
+ None
+ }
+ }
+
++impl<'p, T> PyNumberAndProtocolImpl for T where T: PyNumberProtocol<'p> {}
++
+ impl<T> PyNumberAndProtocolImpl for T
+ where
+ T: for<'p> PyNumberAndProtocol<'p>,
+@@ -1034,15 +1007,13 @@ where
+ }
+
+ trait PyNumberXorProtocolImpl {
+- fn nb_xor() -> Option<ffi::binaryfunc>;
+-}
+-
+-impl<'p, T> PyNumberXorProtocolImpl for T where T: PyNumberProtocol<'p> {
+- default fn nb_xor() -> Option<ffi::binaryfunc> {
++ fn nb_xor() -> Option<ffi::binaryfunc> {
+ None
+ }
+ }
+
++impl<'p, T> PyNumberXorProtocolImpl for T where T: PyNumberProtocol<'p> {}
++
+ impl<T> PyNumberXorProtocolImpl for T
+ where
+ T: for<'p> PyNumberXorProtocol<'p>,
+@@ -1058,15 +1029,13 @@ where
+ }
+
+ trait PyNumberOrProtocolImpl {
+- fn nb_or() -> Option<ffi::binaryfunc>;
+-}
+-
+-impl<'p, T> PyNumberOrProtocolImpl for T where T: PyNumberProtocol<'p> {
+- default fn nb_or() -> Option<ffi::binaryfunc> {
++ fn nb_or() -> Option<ffi::binaryfunc> {
+ None
+ }
+ }
+
++impl<'p, T> PyNumberOrProtocolImpl for T where T: PyNumberProtocol<'p> {}
++
+ impl<T> PyNumberOrProtocolImpl for T
+ where
+ T: for<'p> PyNumberOrProtocol<'p>,
+@@ -1082,15 +1051,13 @@ where
+ }
+
+ trait PyNumberIAddProtocolImpl {
+- fn nb_inplace_add() -> Option<ffi::binaryfunc>;
+-}
+-
+-impl<'p, T> PyNumberIAddProtocolImpl for T where T: PyNumberProtocol<'p> {
+- default fn nb_inplace_add() -> Option<ffi::binaryfunc> {
++ fn nb_inplace_add() -> Option<ffi::binaryfunc> {
+ None
+ }
+ }
+
++impl<'p, T> PyNumberIAddProtocolImpl for T where T: PyNumberProtocol<'p> {}
++
+ impl<T> PyNumberIAddProtocolImpl for T
+ where
+ T: for<'p> PyNumberIAddProtocol<'p>,
+@@ -1101,15 +1068,13 @@ where
+ }
+
+ trait PyNumberISubProtocolImpl {
+- fn nb_inplace_subtract() -> Option<ffi::binaryfunc>;
+-}
+-
+-impl<'p, T> PyNumberISubProtocolImpl for T where T: PyNumberProtocol<'p> {
+- default fn nb_inplace_subtract() -> Option<ffi::binaryfunc> {
++ fn nb_inplace_subtract() -> Option<ffi::binaryfunc> {
+ None
+ }
+ }
+
++impl<'p, T> PyNumberISubProtocolImpl for T where T: PyNumberProtocol<'p> {}
++
+ impl<T> PyNumberISubProtocolImpl for T
+ where
+ T: for<'p> PyNumberISubProtocol<'p>,
+@@ -1120,15 +1085,13 @@ where
+ }
+
+ trait PyNumberIMulProtocolImpl {
+- fn nb_inplace_multiply() -> Option<ffi::binaryfunc>;
+-}
+-
+-impl<'p, T> PyNumberIMulProtocolImpl for T where T: PyNumberProtocol<'p> {
+- default fn nb_inplace_multiply() -> Option<ffi::binaryfunc> {
++ fn nb_inplace_multiply() -> Option<ffi::binaryfunc> {
+ None
+ }
+ }
+
++impl<'p, T> PyNumberIMulProtocolImpl for T where T: PyNumberProtocol<'p> {}
++
+ impl<T> PyNumberIMulProtocolImpl for T
+ where
+ T: for<'p> PyNumberIMulProtocol<'p>,
+@@ -1139,15 +1102,13 @@ where
+ }
+
+ trait PyNumberIMatmulProtocolImpl {
+- fn nb_inplace_matrix_multiply() -> Option<ffi::binaryfunc>;
+-}
+-
+-impl<'p, T> PyNumberIMatmulProtocolImpl for T where T: PyNumberProtocol<'p> {
+- default fn nb_inplace_matrix_multiply() -> Option<ffi::binaryfunc> {
++ fn nb_inplace_matrix_multiply() -> Option<ffi::binaryfunc> {
+ None
+ }
+ }
+
++impl<'p, T> PyNumberIMatmulProtocolImpl for T where T: PyNumberProtocol<'p> {}
++
+ impl<T> PyNumberIMatmulProtocolImpl for T
+ where
+ T: for<'p> PyNumberIMatmulProtocol<'p>,
+@@ -1158,15 +1119,13 @@ where
+ }
+
+ trait PyNumberITruedivProtocolImpl {
+- fn nb_inplace_true_divide() -> Option<ffi::binaryfunc>;
+-}
+-
+-impl<'p, T> PyNumberITruedivProtocolImpl for T where T: PyNumberProtocol<'p> {
+- default fn nb_inplace_true_divide() -> Option<ffi::binaryfunc> {
++ fn nb_inplace_true_divide() -> Option<ffi::binaryfunc> {
+ None
+ }
+ }
+
++impl<'p, T> PyNumberITruedivProtocolImpl for T where T: PyNumberProtocol<'p> {}
++
+ impl<T> PyNumberITruedivProtocolImpl for T
+ where
+ T: for<'p> PyNumberITruedivProtocol<'p>,
+@@ -1177,15 +1136,13 @@ where
+ }
+
+ trait PyNumberIFloordivProtocolImpl {
+- fn nb_inplace_floor_divide() -> Option<ffi::binaryfunc>;
+-}
+-
+-impl<'p, T> PyNumberIFloordivProtocolImpl for T where T: PyNumberProtocol<'p> {
+- default fn nb_inplace_floor_divide() -> Option<ffi::binaryfunc> {
++ fn nb_inplace_floor_divide() -> Option<ffi::binaryfunc> {
+ None
+ }
+ }
+
++impl<'p, T> PyNumberIFloordivProtocolImpl for T where T: PyNumberProtocol<'p> {}
++
+ impl<T> PyNumberIFloordivProtocolImpl for T
+ where
+ T: for<'p> PyNumberIFloordivProtocol<'p>,
+@@ -1196,15 +1153,13 @@ where
+ }
+
+ trait PyNumberIModProtocolImpl {
+- fn nb_inplace_remainder() -> Option<ffi::binaryfunc>;
+-}
+-
+-impl<'p, T> PyNumberIModProtocolImpl for T where T: PyNumberProtocol<'p> {
+- default fn nb_inplace_remainder() -> Option<ffi::binaryfunc> {
++ fn nb_inplace_remainder() -> Option<ffi::binaryfunc> {
+ None
+ }
+ }
+
++impl<'p, T> PyNumberIModProtocolImpl for T where T: PyNumberProtocol<'p> {}
++
+ impl<T> PyNumberIModProtocolImpl for T
+ where
+ T: for<'p> PyNumberIModProtocol<'p>,
+@@ -1215,15 +1170,13 @@ where
+ }
+
+ trait PyNumberIPowProtocolImpl {
+- fn nb_inplace_power() -> Option<ffi::ternaryfunc>;
+-}
+-
+-impl<'p, T> PyNumberIPowProtocolImpl for T where T: PyNumberProtocol<'p> {
+- default fn nb_inplace_power() -> Option<ffi::ternaryfunc> {
++ fn nb_inplace_power() -> Option<ffi::ternaryfunc> {
+ None
+ }
+ }
+
++impl<'p, T> PyNumberIPowProtocolImpl for T where T: PyNumberProtocol<'p> {}
++
+ impl<T> PyNumberIPowProtocolImpl for T
+ where
+ T: for<'p> PyNumberIPowProtocol<'p>,
+@@ -1234,15 +1187,13 @@ where
+ }
+
+ trait PyNumberILShiftProtocolImpl {
+- fn nb_inplace_lshift() -> Option<ffi::binaryfunc>;
+-}
+-
+-impl<'p, T> PyNumberILShiftProtocolImpl for T where T: PyNumberProtocol<'p> {
+- default fn nb_inplace_lshift() -> Option<ffi::binaryfunc> {
++ fn nb_inplace_lshift() -> Option<ffi::binaryfunc> {
+ None
+ }
+ }
+
++impl<'p, T> PyNumberILShiftProtocolImpl for T where T: PyNumberProtocol<'p> {}
++
+ impl<T> PyNumberILShiftProtocolImpl for T
+ where
+ T: for<'p> PyNumberILShiftProtocol<'p>,
+@@ -1253,15 +1204,13 @@ where
+ }
+
+ trait PyNumberIRShiftProtocolImpl {
+- fn nb_inplace_rshift() -> Option<ffi::binaryfunc>;
+-}
+-
+-impl<'p, T> PyNumberIRShiftProtocolImpl for T where T: PyNumberProtocol<'p> {
+- default fn nb_inplace_rshift() -> Option<ffi::binaryfunc> {
++ fn nb_inplace_rshift() -> Option<ffi::binaryfunc> {
+ None
+ }
+ }
+
++impl<'p, T> PyNumberIRShiftProtocolImpl for T where T: PyNumberProtocol<'p> {}
++
+ impl<T> PyNumberIRShiftProtocolImpl for T
+ where
+ T: for<'p> PyNumberIRShiftProtocol<'p>,
+@@ -1272,15 +1221,13 @@ where
+ }
+
+ trait PyNumberIAndProtocolImpl {
+- fn nb_inplace_and() -> Option<ffi::binaryfunc>;
+-}
+-
+-impl<'p, T> PyNumberIAndProtocolImpl for T where T: PyNumberProtocol<'p> {
+- default fn nb_inplace_and() -> Option<ffi::binaryfunc> {
++ fn nb_inplace_and() -> Option<ffi::binaryfunc> {
+ None
+ }
+ }
+
++impl<'p, T> PyNumberIAndProtocolImpl for T where T: PyNumberProtocol<'p> {}
++
+ impl<T> PyNumberIAndProtocolImpl for T
+ where
+ T: for<'p> PyNumberIAndProtocol<'p>,
+@@ -1291,15 +1238,13 @@ where
+ }
+
+ trait PyNumberIXorProtocolImpl {
+- fn nb_inplace_xor() -> Option<ffi::binaryfunc>;
+-}
+-
+-impl<'p, T> PyNumberIXorProtocolImpl for T where T: PyNumberProtocol<'p> {
+- default fn nb_inplace_xor() -> Option<ffi::binaryfunc> {
++ fn nb_inplace_xor() -> Option<ffi::binaryfunc> {
+ None
+ }
+ }
+
++impl<'p, T> PyNumberIXorProtocolImpl for T where T: PyNumberProtocol<'p> {}
++
+ impl<T> PyNumberIXorProtocolImpl for T
+ where
+ T: for<'p> PyNumberIXorProtocol<'p>,
+@@ -1310,15 +1255,13 @@ where
+ }
+
+ trait PyNumberIOrProtocolImpl {
+- fn nb_inplace_or() -> Option<ffi::binaryfunc>;
+-}
+-
+-impl<'p, T> PyNumberIOrProtocolImpl for T where T: PyNumberProtocol<'p> {
+- default fn nb_inplace_or() -> Option<ffi::binaryfunc> {
++ fn nb_inplace_or() -> Option<ffi::binaryfunc> {
+ None
+ }
+ }
+
++impl<'p, T> PyNumberIOrProtocolImpl for T where T: PyNumberProtocol<'p> {}
++
+ impl<T> PyNumberIOrProtocolImpl for T
+ where
+ T: for<'p> PyNumberIOrProtocol<'p>,
+@@ -1330,15 +1273,13 @@ where
+
+ #[doc(hidden)]
+ pub trait PyNumberRAddProtocolImpl {
+- fn __radd__() -> Option<PyMethodDef>;
+-}
+-
+-impl<'p, T> PyNumberRAddProtocolImpl for T where T: PyNumberProtocol<'p> {
+- default fn __radd__() -> Option<PyMethodDef> {
++ fn __radd__() -> Option<PyMethodDef> {
+ None
+ }
+ }
+
++impl<'p, T> PyNumberRAddProtocolImpl for T where T: PyNumberProtocol<'p> {}
++
+ #[doc(hidden)]
+ pub trait PyNumberRSubProtocolImpl {
+ fn __rsub__() -> Option<PyMethodDef> {
+@@ -1350,146 +1291,120 @@ impl<'p, T> PyNumberRSubProtocolImpl for T where T: PyNumberProtocol<'p> {}
+
+ #[doc(hidden)]
+ pub trait PyNumberRMulProtocolImpl {
+- fn __rmul__() -> Option<PyMethodDef>;
+-}
+-
+-impl<'p, T> PyNumberRMulProtocolImpl for T where T: PyNumberProtocol<'p> {
+- default fn __rmul__() -> Option<PyMethodDef> {
++ fn __rmul__() -> Option<PyMethodDef> {
+ None
+ }
+ }
+
++impl<'p, T> PyNumberRMulProtocolImpl for T where T: PyNumberProtocol<'p> {}
++
+ #[doc(hidden)]
+ pub trait PyNumberRMatmulProtocolImpl {
+- fn __rmatmul__() -> Option<PyMethodDef>;
+-}
+-
+-impl<'p, T> PyNumberRMatmulProtocolImpl for T where T: PyNumberProtocol<'p> {
+- default fn __rmatmul__() -> Option<PyMethodDef> {
++ fn __rmatmul__() -> Option<PyMethodDef> {
+ None
+ }
+ }
+
++impl<'p, T> PyNumberRMatmulProtocolImpl for T where T: PyNumberProtocol<'p> {}
++
+ #[doc(hidden)]
+ pub trait PyNumberRTruedivProtocolImpl {
+- fn __rtruediv__() -> Option<PyMethodDef>;
+-}
+-
+-impl<'p, T> PyNumberRTruedivProtocolImpl for T where T: PyNumberProtocol<'p> {
+- default fn __rtruediv__() -> Option<PyMethodDef> {
++ fn __rtruediv__() -> Option<PyMethodDef> {
+ None
+ }
+ }
+
++impl<'p, T> PyNumberRTruedivProtocolImpl for T where T: PyNumberProtocol<'p> {}
++
+ #[doc(hidden)]
+ pub trait PyNumberRFloordivProtocolImpl {
+- fn __rfloordiv__() -> Option<PyMethodDef>;
+-}
+-
+-impl<'p, T> PyNumberRFloordivProtocolImpl for T where T: PyNumberProtocol<'p> {
+- default fn __rfloordiv__() -> Option<PyMethodDef> {
++ fn __rfloordiv__() -> Option<PyMethodDef> {
+ None
+ }
+ }
+
++impl<'p, T> PyNumberRFloordivProtocolImpl for T where T: PyNumberProtocol<'p> {}
++
+ #[doc(hidden)]
+ pub trait PyNumberRModProtocolImpl {
+- fn __rmod__() -> Option<PyMethodDef>;
+-}
+-
+-impl<'p, T> PyNumberRModProtocolImpl for T where T: PyNumberProtocol<'p> {
+- default fn __rmod__() -> Option<PyMethodDef> {
++ fn __rmod__() -> Option<PyMethodDef> {
+ None
+ }
+ }
+
++impl<'p, T> PyNumberRModProtocolImpl for T where T: PyNumberProtocol<'p> {}
++
+ #[doc(hidden)]
+ pub trait PyNumberRDivmodProtocolImpl {
+- fn __rdivmod__() -> Option<PyMethodDef>;
+-}
+-
+-impl<'p, T> PyNumberRDivmodProtocolImpl for T where T: PyNumberProtocol<'p> {
+- default fn __rdivmod__() -> Option<PyMethodDef> {
++ fn __rdivmod__() -> Option<PyMethodDef> {
+ None
+ }
+ }
+
++impl<'p, T> PyNumberRDivmodProtocolImpl for T where T: PyNumberProtocol<'p> {}
++
+ #[doc(hidden)]
+ pub trait PyNumberRPowProtocolImpl {
+- fn __rpow__() -> Option<PyMethodDef>;
+-}
+-
+-impl<'p, T> PyNumberRPowProtocolImpl for T where T: PyNumberProtocol<'p> {
+- default fn __rpow__() -> Option<PyMethodDef> {
++ fn __rpow__() -> Option<PyMethodDef> {
+ None
+ }
+ }
+
++impl<'p, T> PyNumberRPowProtocolImpl for T where T: PyNumberProtocol<'p> {}
++
+ #[doc(hidden)]
+ pub trait PyNumberRLShiftProtocolImpl {
+- fn __rlshift__() -> Option<PyMethodDef>;
+-}
+-
+-impl<'p, T> PyNumberRLShiftProtocolImpl for T where T: PyNumberProtocol<'p> {
+- default fn __rlshift__() -> Option<PyMethodDef> {
++ fn __rlshift__() -> Option<PyMethodDef> {
+ None
+ }
+ }
+
++impl<'p, T> PyNumberRLShiftProtocolImpl for T where T: PyNumberProtocol<'p> {}
++
+ #[doc(hidden)]
+ pub trait PyNumberRRShiftProtocolImpl {
+- fn __rrshift__() -> Option<PyMethodDef>;
+-}
+-
+-impl<'p, T> PyNumberRRShiftProtocolImpl for T where T: PyNumberProtocol<'p> {
+- default fn __rrshift__() -> Option<PyMethodDef> {
++ fn __rrshift__() -> Option<PyMethodDef> {
+ None
+ }
+ }
+
++impl<'p, T> PyNumberRRShiftProtocolImpl for T where T: PyNumberProtocol<'p> {}
++
+ #[doc(hidden)]
+ pub trait PyNumberRAndProtocolImpl {
+- fn __rand__() -> Option<PyMethodDef>;
+-}
+-
+-impl<'p, T> PyNumberRAndProtocolImpl for T where T: PyNumberProtocol<'p> {
+- default fn __rand__() -> Option<PyMethodDef> {
++ fn __rand__() -> Option<PyMethodDef> {
+ None
+ }
+ }
+
++impl<'p, T> PyNumberRAndProtocolImpl for T where T: PyNumberProtocol<'p> {}
++
+ #[doc(hidden)]
+ pub trait PyNumberRXorProtocolImpl {
+- fn __rxor__() -> Option<PyMethodDef>;
+-}
+-
+-impl<'p, T> PyNumberRXorProtocolImpl for T where T: PyNumberProtocol<'p> {
+- default fn __rxor__() -> Option<PyMethodDef> {
++ fn __rxor__() -> Option<PyMethodDef> {
+ None
+ }
+ }
+
++impl<'p, T> PyNumberRXorProtocolImpl for T where T: PyNumberProtocol<'p> {}
++
+ #[doc(hidden)]
+ pub trait PyNumberROrProtocolImpl {
+- fn __ror__() -> Option<PyMethodDef>;
+-}
+-
+-impl<'p, T> PyNumberROrProtocolImpl for T where T: PyNumberProtocol<'p> {
+- default fn __ror__() -> Option<PyMethodDef> {
++ fn __ror__() -> Option<PyMethodDef> {
+ None
+ }
+ }
+
+-trait PyNumberNegProtocolImpl {
+- fn nb_negative() -> Option<ffi::unaryfunc>;
+-}
++impl<'p, T> PyNumberROrProtocolImpl for T where T: PyNumberProtocol<'p> {}
+
+-impl<'p, T> PyNumberNegProtocolImpl for T where T: PyNumberProtocol<'p> {
+- default fn nb_negative() -> Option<ffi::unaryfunc> {
++trait PyNumberNegProtocolImpl {
++ fn nb_negative() -> Option<ffi::unaryfunc> {
+ None
+ }
+ }
+
++impl<'p, T> PyNumberNegProtocolImpl for T where T: PyNumberProtocol<'p> {}
++
+ impl<T> PyNumberNegProtocolImpl for T
+ where
+ T: for<'p> PyNumberNegProtocol<'p>,
+@@ -1506,15 +1421,13 @@ where
+ }
+
+ trait PyNumberPosProtocolImpl {
+- fn nb_positive() -> Option<ffi::unaryfunc>;
+-}
+-
+-impl<'p, T> PyNumberPosProtocolImpl for T where T: PyNumberProtocol<'p> {
+- default fn nb_positive() -> Option<ffi::unaryfunc> {
++ fn nb_positive() -> Option<ffi::unaryfunc> {
+ None
+ }
+ }
+
++impl<'p, T> PyNumberPosProtocolImpl for T where T: PyNumberProtocol<'p> {}
++
+ impl<T> PyNumberPosProtocolImpl for T
+ where
+ T: for<'p> PyNumberPosProtocol<'p>,
+@@ -1530,15 +1443,13 @@ where
+ }
+
+ trait PyNumberAbsProtocolImpl {
+- fn nb_absolute() -> Option<ffi::unaryfunc>;
+-}
+-
+-impl<'p, T> PyNumberAbsProtocolImpl for T where T: PyNumberProtocol<'p> {
+- default fn nb_absolute() -> Option<ffi::unaryfunc> {
++ fn nb_absolute() -> Option<ffi::unaryfunc> {
+ None
+ }
+ }
+
++impl<'p, T> PyNumberAbsProtocolImpl for T where T: PyNumberProtocol<'p> {}
++
+ impl<T> PyNumberAbsProtocolImpl for T
+ where
+ T: for<'p> PyNumberAbsProtocol<'p>,
+@@ -1554,15 +1465,13 @@ where
+ }
+
+ trait PyNumberInvertProtocolImpl {
+- fn nb_invert() -> Option<ffi::unaryfunc>;
+-}
+-
+-impl<'p, T> PyNumberInvertProtocolImpl for T where T: PyNumberProtocol<'p> {
+- default fn nb_invert() -> Option<ffi::unaryfunc> {
++ fn nb_invert() -> Option<ffi::unaryfunc> {
+ None
+ }
+ }
+
++impl<'p, T> PyNumberInvertProtocolImpl for T where T: PyNumberProtocol<'p> {}
++
+ impl<T> PyNumberInvertProtocolImpl for T
+ where
+ T: for<'p> PyNumberInvertProtocol<'p>,
+@@ -1578,15 +1487,13 @@ where
+ }
+
+ trait PyNumberIntProtocolImpl {
+- fn nb_int() -> Option<ffi::unaryfunc>;
+-}
+-
+-impl<'p, T> PyNumberIntProtocolImpl for T where T: PyNumberProtocol<'p> {
+- default fn nb_int() -> Option<ffi::unaryfunc> {
++ fn nb_int() -> Option<ffi::unaryfunc> {
+ None
+ }
+ }
+
++impl<'p, T> PyNumberIntProtocolImpl for T where T: PyNumberProtocol<'p> {}
++
+ impl<T> PyNumberIntProtocolImpl for T
+ where
+ T: for<'p> PyNumberIntProtocol<'p>,
+@@ -1602,15 +1509,13 @@ where
+ }
+
+ trait PyNumberFloatProtocolImpl {
+- fn nb_float() -> Option<ffi::unaryfunc>;
+-}
+-
+-impl<'p, T> PyNumberFloatProtocolImpl for T where T: PyNumberProtocol<'p> {
+- default fn nb_float() -> Option<ffi::unaryfunc> {
++ fn nb_float() -> Option<ffi::unaryfunc> {
+ None
+ }
+ }
+
++impl<'p, T> PyNumberFloatProtocolImpl for T where T: PyNumberProtocol<'p> {}
++
+ impl<T> PyNumberFloatProtocolImpl for T
+ where
+ T: for<'p> PyNumberFloatProtocol<'p>,
+@@ -1626,15 +1531,13 @@ where
+ }
+
+ trait PyNumberIndexProtocolImpl {
+- fn nb_index() -> Option<ffi::unaryfunc>;
+-}
+-
+-impl<'p, T> PyNumberIndexProtocolImpl for T where T: PyNumberProtocol<'p> {
+- default fn nb_index() -> Option<ffi::unaryfunc> {
++ fn nb_index() -> Option<ffi::unaryfunc> {
+ None
+ }
+ }
+
++impl<'p, T> PyNumberIndexProtocolImpl for T where T: PyNumberProtocol<'p> {}
++
+ impl<T> PyNumberIndexProtocolImpl for T
+ where
+ T: for<'p> PyNumberIndexProtocol<'p>,
+@@ -1650,21 +1553,17 @@ where
+ }
+
+ trait PyNumberComplexProtocolImpl {
+- fn __complex__() -> Option<PyMethodDef>;
+-}
+-
+-impl<'p, T> PyNumberComplexProtocolImpl for T where T: PyNumberProtocol<'p> {
+- default fn __complex__() -> Option<PyMethodDef> {
++ fn __complex__() -> Option<PyMethodDef> {
+ None
+ }
+ }
+
+-trait PyNumberRoundProtocolImpl {
+- fn __round__() -> Option<PyMethodDef>;
+-}
++impl<'p, T> PyNumberComplexProtocolImpl for T where T: PyNumberProtocol<'p> {}
+
+-impl<'p, T> PyNumberRoundProtocolImpl for T where T: PyNumberProtocol<'p> {
+- default fn __round__() -> Option<PyMethodDef> {
++trait PyNumberRoundProtocolImpl {
++ fn __round__() -> Option<PyMethodDef> {
+ None
+ }
+ }
++
++impl<'p, T> PyNumberRoundProtocolImpl for T where T: PyNumberProtocol<'p> {}
+diff --git a/src/class/pyasync.rs b/src/class/pyasync.rs
+index f977fadfa..9afb72c17 100644
+--- a/src/class/pyasync.rs
++++ b/src/class/pyasync.rs
+@@ -91,20 +91,17 @@ pub trait PyAsyncAexitProtocol<'p>: PyAsyncProtocol<'p> {
+
+ #[doc(hidden)]
+ pub trait PyAsyncProtocolImpl {
+- fn tp_as_async() -> Option<ffi::PyAsyncMethods>;
+- fn methods() -> Vec<PyMethodDef>;
+-}
+-
+-impl<T> PyAsyncProtocolImpl for T {
+- default fn tp_as_async() -> Option<ffi::PyAsyncMethods> {
++ fn tp_as_async() -> Option<ffi::PyAsyncMethods> {
+ None
+ }
+
+- default fn methods() -> Vec<PyMethodDef> {
++ fn methods() -> Vec<PyMethodDef> {
+ Vec::new()
+ }
+ }
+
++impl<T> PyAsyncProtocolImpl for T {}
++
+ impl<'p, T> PyAsyncProtocolImpl for T
+ where
+ T: PyAsyncProtocol<'p>,
+@@ -134,15 +131,13 @@ where
+ }
+
+ trait PyAsyncAwaitProtocolImpl {
+- fn am_await() -> Option<ffi::unaryfunc>;
+-}
+-
+-impl<'p, T> PyAsyncAwaitProtocolImpl for T where T: PyAsyncProtocol<'p> {
+- default fn am_await() -> Option<ffi::unaryfunc> {
++ fn am_await() -> Option<ffi::unaryfunc> {
+ None
+ }
+ }
+
++impl<'p, T> PyAsyncAwaitProtocolImpl for T where T: PyAsyncProtocol<'p> {}
++
+ impl<T> PyAsyncAwaitProtocolImpl for T
+ where
+ T: for<'p> PyAsyncAwaitProtocol<'p>,
+@@ -159,15 +154,13 @@ where
+ }
+
+ trait PyAsyncAiterProtocolImpl {
+- fn am_aiter() -> Option<ffi::unaryfunc>;
+-}
+-
+-impl<'p, T> PyAsyncAiterProtocolImpl for T where T: PyAsyncProtocol<'p> {
+- default fn am_aiter() -> Option<ffi::unaryfunc> {
++ fn am_aiter() -> Option<ffi::unaryfunc> {
+ None
+ }
+ }
+
++impl<'p, T> PyAsyncAiterProtocolImpl for T where T: PyAsyncProtocol<'p> {}
++
+ impl<T> PyAsyncAiterProtocolImpl for T
+ where
+ T: for<'p> PyAsyncAiterProtocol<'p>,
+@@ -184,15 +177,13 @@ where
+ }
+
+ trait PyAsyncAnextProtocolImpl {
+- fn am_anext() -> Option<ffi::unaryfunc>;
+-}
+-
+-impl<'p, T> PyAsyncAnextProtocolImpl for T where T: PyAsyncProtocol<'p> {
+- default fn am_anext() -> Option<ffi::unaryfunc> {
++ fn am_anext() -> Option<ffi::unaryfunc> {
+ None
+ }
+ }
+
++impl<'p, T> PyAsyncAnextProtocolImpl for T where T: PyAsyncProtocol<'p> {}
++
+ mod anext {
+ use super::{PyAsyncAnextProtocol, PyAsyncAnextProtocolImpl};
+ use crate::callback::CallbackConverter;
+@@ -242,21 +233,17 @@ mod anext {
+ }
+
+ trait PyAsyncAenterProtocolImpl {
+- fn __aenter__() -> Option<PyMethodDef>;
+-}
+-
+-impl<'p, T> PyAsyncAenterProtocolImpl for T where T: PyAsyncProtocol<'p> {
+- default fn __aenter__() -> Option<PyMethodDef> {
++ fn __aenter__() -> Option<PyMethodDef> {
+ None
+ }
+ }
+
+-trait PyAsyncAexitProtocolImpl {
+- fn __aexit__() -> Option<PyMethodDef>;
+-}
++impl<'p, T> PyAsyncAenterProtocolImpl for T where T: PyAsyncProtocol<'p> {}
+
+-impl<'p, T> PyAsyncAexitProtocolImpl for T where T: PyAsyncProtocol<'p> {
+- default fn __aexit__() -> Option<PyMethodDef> {
++trait PyAsyncAexitProtocolImpl {
++ fn __aexit__() -> Option<PyMethodDef> {
+ None
+ }
+ }
++
++impl<'p, T> PyAsyncAexitProtocolImpl for T where T: PyAsyncProtocol<'p> {}
+diff --git a/src/class/sequence.rs b/src/class/sequence.rs
+index ce65508fd..23771ba0b 100644
+--- a/src/class/sequence.rs
++++ b/src/class/sequence.rs
+@@ -134,15 +134,13 @@ pub trait PySequenceInplaceRepeatProtocol<'p>: PySequenceProtocol<'p> + IntoPy<P
+
+ #[doc(hidden)]
+ pub trait PySequenceProtocolImpl {
+- fn tp_as_sequence() -> Option<ffi::PySequenceMethods>;
+-}
+-
+-impl<T> PySequenceProtocolImpl for T {
+- default fn tp_as_sequence() -> Option<ffi::PySequenceMethods> {
++ fn tp_as_sequence() -> Option<ffi::PySequenceMethods> {
+ None
+ }
+ }
+
++impl<T> PySequenceProtocolImpl for T {}
++
+ impl<'p, T> PySequenceProtocolImpl for T
+ where
+ T: PySequenceProtocol<'p>,
+@@ -164,15 +162,13 @@ where
+ }
+
+ trait PySequenceLenProtocolImpl {
+- fn sq_length() -> Option<ffi::lenfunc>;
+-}
+-
+-impl<'p, T> PySequenceLenProtocolImpl for T where T: PySequenceProtocol<'p> {
+- default fn sq_length() -> Option<ffi::lenfunc> {
++ fn sq_length() -> Option<ffi::lenfunc> {
+ None
+ }
+ }
+
++impl<'p, T> PySequenceLenProtocolImpl for T where T: PySequenceProtocol<'p> {}
++
+ impl<T> PySequenceLenProtocolImpl for T
+ where
+ T: for<'p> PySequenceLenProtocol<'p>,
+@@ -183,15 +179,13 @@ where
+ }
+
+ trait PySequenceGetItemProtocolImpl {
+- fn sq_item() -> Option<ffi::ssizeargfunc>;
+-}
+-
+-impl<'p, T> PySequenceGetItemProtocolImpl for T where T: PySequenceProtocol<'p> {
+- default fn sq_item() -> Option<ffi::ssizeargfunc> {
++ fn sq_item() -> Option<ffi::ssizeargfunc> {
+ None
+ }
+ }
+
++impl<'p, T> PySequenceGetItemProtocolImpl for T where T: PySequenceProtocol<'p> {}
++
+ impl<T> PySequenceGetItemProtocolImpl for T
+ where
+ T: for<'p> PySequenceGetItemProtocol<'p>,
+@@ -289,15 +283,13 @@ mod sq_ass_item_impl {
+ }
+
+ trait DelItem {
+- fn del_item() -> Option<ffi::ssizeobjargproc>;
+- }
+-
+- impl<'p, T> DelItem for T where T: PySequenceProtocol<'p> {
+- default fn del_item() -> Option<ffi::ssizeobjargproc> {
++ fn del_item() -> Option<ffi::ssizeobjargproc> {
+ None
+ }
+ }
+
++ impl<'p, T> DelItem for T where T: PySequenceProtocol<'p> {}
++
+ impl<T> DelItem for T
+ where
+ T: for<'p> PySequenceDelItemProtocol<'p>,
+@@ -337,15 +329,13 @@ mod sq_ass_item_impl {
+ }
+
+ trait DelSetItem {
+- fn del_set_item() -> Option<ffi::ssizeobjargproc>;
+- }
+-
+- impl<'p, T> DelSetItem for T where T: PySequenceProtocol<'p> {
+- default fn del_set_item() -> Option<ffi::ssizeobjargproc> {
++ fn del_set_item() -> Option<ffi::ssizeobjargproc> {
+ None
+ }
+ }
+
++ impl<'p, T> DelSetItem for T where T: PySequenceProtocol<'p> {}
++
+ impl<T> DelSetItem for T
+ where
+ T: for<'p> PySequenceSetItemProtocol<'p> + for<'p> PySequenceDelItemProtocol<'p>,
+@@ -386,15 +376,13 @@ mod sq_ass_item_impl {
+ }
+
+ trait PySequenceContainsProtocolImpl {
+- fn sq_contains() -> Option<ffi::objobjproc>;
+-}
+-
+-impl<'p, T> PySequenceContainsProtocolImpl for T where T: PySequenceProtocol<'p> {
+- default fn sq_contains() -> Option<ffi::objobjproc> {
++ fn sq_contains() -> Option<ffi::objobjproc> {
+ None
+ }
+ }
+
++impl<'p, T> PySequenceContainsProtocolImpl for T where T: PySequenceProtocol<'p> {}
++
+ impl<T> PySequenceContainsProtocolImpl for T
+ where
+ T: for<'p> PySequenceContainsProtocol<'p>,
+@@ -411,15 +399,13 @@ where
+ }
+
+ trait PySequenceConcatProtocolImpl {
+- fn sq_concat() -> Option<ffi::binaryfunc>;
+-}
+-
+-impl<'p, T> PySequenceConcatProtocolImpl for T where T: PySequenceProtocol<'p> {
+- default fn sq_concat() -> Option<ffi::binaryfunc> {
++ fn sq_concat() -> Option<ffi::binaryfunc> {
+ None
+ }
+ }
+
++impl<'p, T> PySequenceConcatProtocolImpl for T where T: PySequenceProtocol<'p> {}
++
+ impl<T> PySequenceConcatProtocolImpl for T
+ where
+ T: for<'p> PySequenceConcatProtocol<'p>,
+@@ -435,15 +421,13 @@ where
+ }
+
+ trait PySequenceRepeatProtocolImpl {
+- fn sq_repeat() -> Option<ffi::ssizeargfunc>;
+-}
+-
+-impl<'p, T> PySequenceRepeatProtocolImpl for T where T: PySequenceProtocol<'p> {
+- default fn sq_repeat() -> Option<ffi::ssizeargfunc> {
++ fn sq_repeat() -> Option<ffi::ssizeargfunc> {
+ None
+ }
+ }
+
++impl<'p, T> PySequenceRepeatProtocolImpl for T where T: PySequenceProtocol<'p> {}
++
+ impl<T> PySequenceRepeatProtocolImpl for T
+ where
+ T: for<'p> PySequenceRepeatProtocol<'p>,
+@@ -459,15 +443,13 @@ where
+ }
+
+ trait PySequenceInplaceConcatProtocolImpl {
+- fn sq_inplace_concat() -> Option<ffi::binaryfunc>;
+-}
+-
+-impl<'p, T> PySequenceInplaceConcatProtocolImpl for T where T: PySequenceProtocol<'p> {
+- default fn sq_inplace_concat() -> Option<ffi::binaryfunc> {
++ fn sq_inplace_concat() -> Option<ffi::binaryfunc> {
+ None
+ }
+ }
+
++impl<'p, T> PySequenceInplaceConcatProtocolImpl for T where T: PySequenceProtocol<'p> {}
++
+ impl<T> PySequenceInplaceConcatProtocolImpl for T
+ where
+ T: for<'p> PySequenceInplaceConcatProtocol<'p>,
+@@ -483,15 +465,13 @@ where
+ }
+
+ trait PySequenceInplaceRepeatProtocolImpl {
+- fn sq_inplace_repeat() -> Option<ffi::ssizeargfunc>;
+-}
+-
+-impl<'p, T> PySequenceInplaceRepeatProtocolImpl for T where T: PySequenceProtocol<'p> {
+- default fn sq_inplace_repeat() -> Option<ffi::ssizeargfunc> {
++ fn sq_inplace_repeat() -> Option<ffi::ssizeargfunc> {
+ None
+ }
+ }
+
++impl<'p, T> PySequenceInplaceRepeatProtocolImpl for T where T: PySequenceProtocol<'p> {}
++
+ impl<T> PySequenceInplaceRepeatProtocolImpl for T
+ where
+ T: for<'p> PySequenceInplaceRepeatProtocol<'p>,
+diff --git a/src/conversion.rs b/src/conversion.rs
+index 15ccdabde..a3bca1175 100644
+--- a/src/conversion.rs
++++ b/src/conversion.rs
+@@ -96,12 +96,6 @@ pub trait ToBorrowedObject: ToPyObject {
+ /// May be more efficient than `to_object` because it does not need
+ /// to touch any reference counts when the input object already is a Python object.
+ fn with_borrowed_ptr<F, R>(&self, py: Python, f: F) -> R
+- where
+- F: FnOnce(*mut ffi::PyObject) -> R;
+-}
+-
+-impl<T> ToBorrowedObject for T where T: ToPyObject {
+- default fn with_borrowed_ptr<F, R>(&self, py: Python, f: F) -> R
+ where
+ F: FnOnce(*mut ffi::PyObject) -> R,
+ {
+@@ -114,6 +108,8 @@ impl<T> ToBorrowedObject for T where T: ToPyObject {
+ }
+ }
+
++impl<T> ToBorrowedObject for T where T: ToPyObject {}
++
+ impl<T> ToBorrowedObject for T
+ where
+ T: ToPyObject + AsPyPointer,
+diff --git a/src/instance.rs b/src/instance.rs
+index 779d18617..68bd45ec3 100644
+--- a/src/instance.rs
++++ b/src/instance.rs
+@@ -359,18 +359,13 @@ impl<T> Py<T> {
+
+ /// Specialization workaround
+ trait AsPyRefDispatch<T: PyTypeInfo>: AsPyPointer {
+- fn as_ref_dispatch(&self, _py: Python) -> &T;
+- fn as_mut_dispatch(&mut self, _py: Python) -> &mut T;
+-}
+-
+-impl<T: PyTypeInfo> AsPyRefDispatch<T> for Py<T> {
+- default fn as_ref_dispatch(&self, _py: Python) -> &T {
++ fn as_ref_dispatch(&self, _py: Python) -> &T {
+ unsafe {
+ let ptr = (self.as_ptr() as *mut u8).offset(T::OFFSET) as *mut T;
+ ptr.as_ref().expect("Py has a null pointer")
+ }
+ }
+- default fn as_mut_dispatch(&mut self, _py: Python) -> &mut T {
++ fn as_mut_dispatch(&mut self, _py: Python) -> &mut T {
+ unsafe {
+ let ptr = (self.as_ptr() as *mut u8).offset(T::OFFSET) as *mut T;
+ ptr.as_mut().expect("Py has a null pointer")
+@@ -378,6 +373,8 @@ impl<T: PyTypeInfo> AsPyRefDispatch<T> for Py<T> {
+ }
+ }
+
++impl<T: PyTypeInfo> AsPyRefDispatch<T> for Py<T> {}
++
+ impl<T: PyTypeInfo + PyNativeType> AsPyRefDispatch<T> for Py<T> {
+ fn as_ref_dispatch(&self, _py: Python) -> &T {
+ unsafe { &*(self as *const instance::Py<T> as *const T) }
+@@ -556,21 +553,9 @@ impl<'p, T: ToPyObject> AsPyPointer for ManagedPyRef<'p, T> {
+ /// Helper trait to choose the right implementation for [ManagedPyRef]
+ pub trait ManagedPyRefDispatch: ToPyObject {
+ /// Optionally converts into a python object and stores the pointer to the python heap.
+- fn to_managed_py_ref<'p>(&self, py: Python<'p>) -> ManagedPyRef<'p, Self>;
+-
+- /// Dispatch over a xdecref and a noop drop impl
+- fn drop_impl(borrowed: &mut ManagedPyRef<Self>);
+-}
+-
+-/// Case 1: It's a rust object which still needs to be converted to a python object.
+-/// This means we're storing the owned pointer that into_ptr() has given us
+-/// and therefore need to xdecref when we're done.
+-///
+-/// Note that the actual implementations are part of the trait declaration to avoid
+-/// a specialization error
+-impl<T: ToPyObject + ?Sized> ManagedPyRefDispatch for T {
++ ///
+ /// Contains the case 1 impl (with to_object) to avoid a specialization error
+- default fn to_managed_py_ref<'p>(&self, py: Python<'p>) -> ManagedPyRef<'p, Self> {
++ fn to_managed_py_ref<'p>(&self, py: Python<'p>) -> ManagedPyRef<'p, Self> {
+ ManagedPyRef {
+ data: self.to_object(py).into_ptr(),
+ data_type: PhantomData,
+@@ -578,12 +563,22 @@ impl<T: ToPyObject + ?Sized> ManagedPyRefDispatch for T {
+ }
+ }
+
++ /// Dispatch over a xdecref and a noop drop impl
++ ///
+ /// Contains the case 1 impl (decref) to avoid a specialization error
+- default fn drop_impl(borrowed: &mut ManagedPyRef<Self>) {
++ fn drop_impl(borrowed: &mut ManagedPyRef<Self>) {
+ unsafe { ffi::Py_DECREF(borrowed.data) };
+ }
+ }
+
++/// Case 1: It's a rust object which still needs to be converted to a python object.
++/// This means we're storing the owned pointer that into_ptr() has given us
++/// and therefore need to xdecref when we're done.
++///
++/// Note that the actual implementations are part of the trait declaration to avoid
++/// a specialization error
++impl<T: ToPyObject + ?Sized> ManagedPyRefDispatch for T {}
++
+ /// Case 2: It's an object on the python heap, we're just storing a borrowed pointer.
+ /// The object we're getting is an owned pointer, it might have it's own drop impl.
+ impl<T: ToPyObject + AsPyPointer + ?Sized> ManagedPyRefDispatch for T {
diff --git a/srcpkgs/anki/files/pyo3-patches/0012-specialization-2f4dfec729e00355bbd067e5770a9e8e889280cf.patch b/srcpkgs/anki/files/pyo3-patches/0012-specialization-2f4dfec729e00355bbd067e5770a9e8e889280cf.patch
new file mode 100644
index 00000000000..c4315a09425
--- /dev/null
+++ b/srcpkgs/anki/files/pyo3-patches/0012-specialization-2f4dfec729e00355bbd067e5770a9e8e889280cf.patch
@@ -0,0 +1,1659 @@
+From 2f4dfec729e00355bbd067e5770a9e8e889280cf Mon Sep 17 00:00:00 2001
+From: Martin Donlon <github-martin@donlons.com>
+Date: Mon, 28 Oct 2019 14:44:26 -0700
+Subject: [PATCH] Removed specialization for all traits
+
+Crate compiles but tests all fail due to missing trait implementations
+---
+ build.rs | 5 --
+ src/class/basic.rs | 55 ++++++------
+ src/class/buffer.rs | 8 +-
+ src/class/context.rs | 2 -
+ src/class/descr.rs | 11 +--
+ src/class/gc.rs | 12 +--
+ src/class/iter.rs | 12 +--
+ src/class/mapping.rs | 24 ++---
+ src/class/number.rs | 199 +++++++++++++++++++-----------------------
+ src/class/pyasync.rs | 19 ++--
+ src/class/sequence.rs | 63 +++++--------
+ src/conversion.rs | 9 +-
+ src/instance.rs | 13 ++-
+ src/lib.rs | 2 -
+ src/object.rs | 2 +-
+ src/type_object.rs | 50 +++++++++--
+ src/types/sequence.rs | 5 +-
+ 17 files changed, 229 insertions(+), 262 deletions(-)
+
+diff --git a/build.rs b/build.rs
+index 7f1060acc..d6b38c489 100644
+--- a/build.rs
++++ b/build.rs
+@@ -537,11 +537,6 @@ fn configure(interpreter_config: &InterpreterConfig) -> Result<(String), String>
+ }
+
+ fn check_rustc_version() {
+- let channel = Channel::read().expect("Failed to determine rustc channel");
+- if !channel.supports_features() {
+- panic!("Error: pyo3 requires a nightly or dev version of Rust.");
+- }
+-
+ let actual_version = Version::read().expect("Failed to determine the rustc version");
+ if !actual_version.at_least(MIN_VERSION) {
+ panic!(
+diff --git a/src/class/basic.rs b/src/class/basic.rs
+index c3153dfa3..f87a0d029 100644
+--- a/src/class/basic.rs
++++ b/src/class/basic.rs
+@@ -161,11 +161,21 @@ pub trait PyObjectProtocolImpl {
+ }
+ }
+
+-impl<T> PyObjectProtocolImpl for T {}
++//impl<T> PyObjectProtocolImpl for T {}
+
+ impl<'p, T> PyObjectProtocolImpl for T
+ where
+- T: PyObjectProtocol<'p>,
++ T: PyObjectProtocol<'p>
++ + PyObjectSetAttrProtocol<'p>
++ + GetAttrProtocolImpl
++ + StrProtocolImpl
++ + ReprProtocolImpl
++ + HashProtocolImpl
++ + RichcmpProtocolImpl
++ + BoolProtocolImpl
++ + tp_setattro_impl::DelAttr
++ + tp_setattro_impl::SetAttr
++ + tp_setattro_impl::SetDelAttr,
+ {
+ fn methods() -> Vec<PyMethodDef> {
+ let mut methods = Vec::new();
+@@ -194,14 +204,12 @@ where
+ }
+ }
+
+-trait GetAttrProtocolImpl {
++pub trait GetAttrProtocolImpl {
+ fn tp_getattro() -> Option<ffi::binaryfunc> {
+ None
+ }
+ }
+
+-impl<'p, T> GetAttrProtocolImpl for T where T: PyObjectProtocol<'p> {}
+-
+ impl<T> GetAttrProtocolImpl for T
+ where
+ T: for<'p> PyObjectGetAttrProtocol<'p>,
+@@ -255,7 +263,10 @@ mod tp_setattro_impl {
+ /// The signature is the same as for PyObject_SetAttr(), but setting v to NULL to delete an
+ /// attribute must be supported. It is usually convenient to set this field to
+ /// PyObject_GenericSetAttr(), which implements the normal way of setting object attributes.
+- pub(super) fn tp_setattro<'p, T: PyObjectProtocol<'p>>() -> Option<ffi::setattrofunc> {
++ pub(super) fn tp_setattro<'p, T>() -> Option<ffi::setattrofunc>
++ where
++ T: PyObjectProtocol<'p> + SetDelAttr + SetAttr + DelAttr,
++ {
+ if let Some(set_del) = T::set_del_attr() {
+ Some(set_del)
+ } else if let Some(set) = T::set_attr() {
+@@ -267,14 +278,12 @@ mod tp_setattro_impl {
+ }
+ }
+
+- trait SetAttr {
++ pub trait SetAttr {
+ fn set_attr() -> Option<ffi::setattrofunc> {
+ None
+ }
+ }
+
+- impl<'p, T: PyObjectProtocol<'p>> SetAttr for T {}
+-
+ impl<T> SetAttr for T
+ where
+ T: for<'p> PyObjectSetAttrProtocol<'p>,
+@@ -284,14 +293,12 @@ mod tp_setattro_impl {
+ }
+ }
+
+- trait DelAttr {
++ pub trait DelAttr {
+ fn del_attr() -> Option<ffi::setattrofunc> {
+ None
+ }
+ }
+
+- impl<'p, T> DelAttr for T where T: PyObjectProtocol<'p> {}
+-
+ impl<T> DelAttr for T
+ where
+ T: for<'p> PyObjectDelAttrProtocol<'p>,
+@@ -301,14 +308,12 @@ mod tp_setattro_impl {
+ }
+ }
+
+- trait SetDelAttr {
++ pub trait SetDelAttr {
+ fn set_del_attr() -> Option<ffi::setattrofunc> {
+ None
+ }
+ }
+
+- impl<'p, T> SetDelAttr for T where T: PyObjectProtocol<'p> {}
+-
+ impl<T> SetDelAttr for T
+ where
+ T: for<'p> PyObjectSetAttrProtocol<'p> + for<'p> PyObjectDelAttrProtocol<'p>,
+@@ -325,12 +330,12 @@ mod tp_setattro_impl {
+ }
+ }
+
+-trait StrProtocolImpl {
++pub trait StrProtocolImpl {
+ fn tp_str() -> Option<ffi::unaryfunc> {
+ None
+ }
+ }
+-impl<'p, T> StrProtocolImpl for T where T: PyObjectProtocol<'p> {}
++
+ impl<T> StrProtocolImpl for T
+ where
+ T: for<'p> PyObjectStrProtocol<'p>,
+@@ -345,12 +350,12 @@ where
+ }
+ }
+
+-trait ReprProtocolImpl {
++pub trait ReprProtocolImpl {
+ fn tp_repr() -> Option<ffi::unaryfunc> {
+ None
+ }
+ }
+-impl<'p, T> ReprProtocolImpl for T where T: PyObjectProtocol<'p> {}
++
+ impl<T> ReprProtocolImpl for T
+ where
+ T: for<'p> PyObjectReprProtocol<'p>,
+@@ -389,12 +394,12 @@ pub trait UnicodeProtocolImpl {
+ }
+ impl<'p, T> UnicodeProtocolImpl for T where T: PyObjectProtocol<'p> {}
+
+-trait HashProtocolImpl {
++pub trait HashProtocolImpl {
+ fn tp_hash() -> Option<ffi::hashfunc> {
+ None
+ }
+ }
+-impl<'p, T> HashProtocolImpl for T where T: PyObjectProtocol<'p> {}
++
+ impl<T> HashProtocolImpl for T
+ where
+ T: for<'p> PyObjectHashProtocol<'p>,
+@@ -410,12 +415,12 @@ where
+ }
+ }
+
+-trait BoolProtocolImpl {
++pub trait BoolProtocolImpl {
+ fn nb_bool() -> Option<ffi::inquiry> {
+ None
+ }
+ }
+-impl<'p, T> BoolProtocolImpl for T where T: PyObjectProtocol<'p> {}
++
+ impl<T> BoolProtocolImpl for T
+ where
+ T: for<'p> PyObjectBoolProtocol<'p>,
+@@ -431,12 +436,12 @@ where
+ }
+ }
+
+-trait RichcmpProtocolImpl {
++pub trait RichcmpProtocolImpl {
+ fn tp_richcompare() -> Option<ffi::richcmpfunc> {
+ None
+ }
+ }
+-impl<'p, T> RichcmpProtocolImpl for T where T: PyObjectProtocol<'p> {}
++
+ impl<T> RichcmpProtocolImpl for T
+ where
+ T: for<'p> PyObjectRichcmpProtocol<'p>,
+diff --git a/src/class/buffer.rs b/src/class/buffer.rs
+index d36524e7c..32d1a25af 100644
+--- a/src/class/buffer.rs
++++ b/src/class/buffer.rs
+@@ -46,11 +46,9 @@ pub trait PyBufferProtocolImpl {
+ }
+ }
+
+-impl<T> PyBufferProtocolImpl for T {}
+-
+ impl<'p, T> PyBufferProtocolImpl for T
+ where
+- T: PyBufferProtocol<'p>,
++ T: PyBufferProtocol<'p> + PyBufferGetBufferProtocolImpl,
+ {
+ #[inline]
+ #[allow(clippy::needless_update)] // For python 2 it's not useless
+@@ -63,14 +61,12 @@ where
+ }
+ }
+
+-trait PyBufferGetBufferProtocolImpl {
++pub trait PyBufferGetBufferProtocolImpl {
+ fn cb_bf_getbuffer() -> Option<ffi::getbufferproc> {
+ None
+ }
+ }
+
+-impl<'p, T> PyBufferGetBufferProtocolImpl for T where T: PyBufferProtocol<'p> {}
+-
+ impl<T> PyBufferGetBufferProtocolImpl for T
+ where
+ T: for<'p> PyBufferGetBufferProtocol<'p>,
+diff --git a/src/class/context.rs b/src/class/context.rs
+index 092527ba0..e5dd56b90 100644
+--- a/src/class/context.rs
++++ b/src/class/context.rs
+@@ -52,8 +52,6 @@ pub trait PyContextProtocolImpl {
+ }
+ }
+
+-impl<T> PyContextProtocolImpl for T {}
+-
+ impl<'p, T> PyContextProtocolImpl for T
+ where
+ T: PyContextProtocol<'p>,
+diff --git a/src/class/descr.rs b/src/class/descr.rs
+index 5f7e68306..ea1dbf012 100644
+--- a/src/class/descr.rs
++++ b/src/class/descr.rs
+@@ -69,12 +69,11 @@ pub trait PyDescrSetNameProtocol<'p>: PyDescrProtocol<'p> {
+ type Result: Into<PyResult<()>>;
+ }
+
+-trait PyDescrGetProtocolImpl {
++pub trait PyDescrGetProtocolImpl {
+ fn tp_descr_get() -> Option<ffi::descrgetfunc> {
+ None
+ }
+ }
+-impl<'p, T> PyDescrGetProtocolImpl for T where T: PyDescrProtocol<'p> {}
+
+ impl<T> PyDescrGetProtocolImpl for T
+ where
+@@ -90,12 +89,12 @@ where
+ }
+ }
+
+-trait PyDescrSetProtocolImpl {
++pub trait PyDescrSetProtocolImpl {
+ fn tp_descr_set() -> Option<ffi::descrsetfunc> {
+ None
+ }
+ }
+-impl<'p, T> PyDescrSetProtocolImpl for T where T: PyDescrProtocol<'p> {}
++
+ impl<T> PyDescrSetProtocolImpl for T
+ where
+ T: for<'p> PyDescrSetProtocol<'p>,
+@@ -133,11 +132,9 @@ pub trait PyDescrProtocolImpl {
+ fn tp_as_descr(_type_object: &mut ffi::PyTypeObject) {}
+ }
+
+-impl<T> PyDescrProtocolImpl for T {}
+-
+ impl<'p, T> PyDescrProtocolImpl for T
+ where
+- T: PyDescrProtocol<'p>,
++ T: PyDescrProtocol<'p> + PyDescrGetProtocolImpl + PyDescrSetProtocolImpl,
+ {
+ fn methods() -> Vec<PyMethodDef> {
+ Vec::new()
+diff --git a/src/class/gc.rs b/src/class/gc.rs
+index eaa4d9015..7e6bc8b45 100644
+--- a/src/class/gc.rs
++++ b/src/class/gc.rs
+@@ -26,11 +26,9 @@ pub trait PyGCProtocolImpl {
+ fn update_type_object(_type_object: &mut ffi::PyTypeObject) {}
+ }
+
+-impl<'p, T> PyGCProtocolImpl for T {}
+-
+ impl<'p, T> PyGCProtocolImpl for T
+ where
+- T: PyGCProtocol<'p>,
++ T: PyGCProtocol<'p> + PyGCTraverseProtocolImpl + PyGCClearProtocolImpl,
+ {
+ fn update_type_object(type_object: &mut ffi::PyTypeObject) {
+ type_object.tp_traverse = Self::tp_traverse();
+@@ -62,14 +60,12 @@ impl<'p> PyVisit<'p> {
+ }
+ }
+
+-trait PyGCTraverseProtocolImpl {
++pub trait PyGCTraverseProtocolImpl {
+ fn tp_traverse() -> Option<ffi::traverseproc> {
+ None
+ }
+ }
+
+-impl<'p, T> PyGCTraverseProtocolImpl for T where T: PyGCProtocol<'p> {}
+-
+ #[doc(hidden)]
+ impl<T> PyGCTraverseProtocolImpl for T
+ where
+@@ -104,14 +100,12 @@ where
+ }
+ }
+
+-trait PyGCClearProtocolImpl {
++pub trait PyGCClearProtocolImpl {
+ fn tp_clear() -> Option<ffi::inquiry> {
+ None
+ }
+ }
+
+-impl<'p, T> PyGCClearProtocolImpl for T where T: PyGCProtocol<'p> {}
+-
+ impl<T> PyGCClearProtocolImpl for T
+ where
+ T: for<'p> PyGCClearProtocol<'p>,
+diff --git a/src/class/iter.rs b/src/class/iter.rs
+index 9001d53ce..b1e896420 100644
+--- a/src/class/iter.rs
++++ b/src/class/iter.rs
+@@ -47,11 +47,9 @@ pub trait PyIterProtocolImpl {
+ fn tp_as_iter(_typeob: &mut ffi::PyTypeObject) {}
+ }
+
+-impl<T> PyIterProtocolImpl for T {}
+-
+ impl<'p, T> PyIterProtocolImpl for T
+ where
+- T: PyIterProtocol<'p>,
++ T: PyIterProtocol<'p> + PyIterIterProtocolImpl + PyIterNextProtocolImpl,
+ {
+ #[inline]
+ fn tp_as_iter(typeob: &mut ffi::PyTypeObject) {
+@@ -60,14 +58,12 @@ where
+ }
+ }
+
+-trait PyIterIterProtocolImpl {
++pub trait PyIterIterProtocolImpl {
+ fn tp_iter() -> Option<ffi::getiterfunc> {
+ None
+ }
+ }
+
+-impl<'p, T> PyIterIterProtocolImpl for T where T: PyIterProtocol<'p> {}
+-
+ impl<T> PyIterIterProtocolImpl for T
+ where
+ T: for<'p> PyIterIterProtocol<'p>,
+@@ -83,14 +79,12 @@ where
+ }
+ }
+
+-trait PyIterNextProtocolImpl {
++pub trait PyIterNextProtocolImpl {
+ fn tp_iternext() -> Option<ffi::iternextfunc> {
+ None
+ }
+ }
+
+-impl<'p, T> PyIterNextProtocolImpl for T where T: PyIterProtocol<'p> {}
+-
+ impl<T> PyIterNextProtocolImpl for T
+ where
+ T: for<'p> PyIterNextProtocol<'p>,
+diff --git a/src/class/mapping.rs b/src/class/mapping.rs
+index 616763502..df2ede958 100644
+--- a/src/class/mapping.rs
++++ b/src/class/mapping.rs
+@@ -114,11 +114,12 @@ pub trait PyMappingProtocolImpl {
+ }
+ }
+
+-impl<T> PyMappingProtocolImpl for T {}
+-
+ impl<'p, T> PyMappingProtocolImpl for T
+ where
+- T: PyMappingProtocol<'p>,
++ T: PyMappingProtocol<'p>
++ + PyMappingSetItemProtocolImpl
++ + PyMappingGetItemProtocolImpl
++ + PyMappingLenProtocolImpl,
+ {
+ #[inline]
+ fn tp_as_mapping() -> Option<ffi::PyMappingMethods> {
+@@ -153,14 +154,12 @@ where
+ }
+ }
+
+-trait PyMappingLenProtocolImpl {
++pub trait PyMappingLenProtocolImpl {
+ fn mp_length() -> Option<ffi::lenfunc> {
+ None
+ }
+ }
+
+-impl<'p, T> PyMappingLenProtocolImpl for T where T: PyMappingProtocol<'p> {}
+-
+ impl<T> PyMappingLenProtocolImpl for T
+ where
+ T: for<'p> PyMappingLenProtocol<'p>,
+@@ -171,14 +170,12 @@ where
+ }
+ }
+
+-trait PyMappingGetItemProtocolImpl {
++pub trait PyMappingGetItemProtocolImpl {
+ fn mp_subscript() -> Option<ffi::binaryfunc> {
+ None
+ }
+ }
+
+-impl<'p, T> PyMappingGetItemProtocolImpl for T where T: PyMappingProtocol<'p> {}
+-
+ impl<T> PyMappingGetItemProtocolImpl for T
+ where
+ T: for<'p> PyMappingGetItemProtocol<'p>,
+@@ -194,14 +191,12 @@ where
+ }
+ }
+
+-trait PyMappingSetItemProtocolImpl {
++pub trait PyMappingSetItemProtocolImpl {
+ fn mp_ass_subscript() -> Option<ffi::objobjargproc> {
+ None
+ }
+ }
+
+-impl<'p, T> PyMappingSetItemProtocolImpl for T where T: PyMappingProtocol<'p> {}
+-
+ impl<T> PyMappingSetItemProtocolImpl for T
+ where
+ T: for<'p> PyMappingSetItemProtocol<'p>,
+@@ -229,8 +224,6 @@ trait DelSetItemDispatch: Sized + for<'p> PyMappingDelItemProtocol<'p> {
+ }
+ }
+
+-impl<T> DelSetItemDispatch for T where T: Sized + for<'p> PyMappingDelItemProtocol<'p> {}
+-
+ impl<T> DelSetItemDispatch for T
+ where
+ T: for<'p> PyMappingSetItemProtocol<'p> + for<'p> PyMappingDelItemProtocol<'p>,
+@@ -246,6 +239,7 @@ where
+ }
+ }
+
++/* MJDFIXME
+ impl<T> DeplItemDipatch for T
+ where
+ T: Sized + for<'p> PyMappingDelItemProtocol<'p>,
+@@ -253,7 +247,7 @@ where
+ fn mp_del_subscript() -> Option<ffi::objobjargproc> {
+ <T as DelSetItemDispatch>::det_set_dispatch()
+ }
+-}
++}*/
+
+ #[doc(hidden)]
+ pub trait PyMappingContainsProtocolImpl {
+diff --git a/src/class/number.rs b/src/class/number.rs
+index 2ee3a57d5..796a1c7ea 100644
+--- a/src/class/number.rs
++++ b/src/class/number.rs
+@@ -638,11 +638,60 @@ pub trait PyNumberProtocolImpl: PyObjectProtocolImpl {
+ }
+ }
+
+-impl<'p, T> PyNumberProtocolImpl for T {}
+-
+ impl<'p, T> PyNumberProtocolImpl for T
+ where
+- T: PyNumberProtocol<'p>,
++ T: PyNumberProtocol<'p>
++ + PyNumberAbsProtocolImpl
++ + PyNumberAddProtocolImpl
++ + PyNumberAndProtocolImpl
++ + PyNumberComplexProtocolImpl
++ + PyNumberDivmodProtocolImpl
++ + PyNumberFloatProtocolImpl
++ + PyNumberFloordivProtocolImpl
++ + PyNumberIAddProtocolImpl
++ + PyNumberIAndProtocolImpl
++ + PyNumberIFloordivProtocolImpl
++ + PyNumberILShiftProtocolImpl
++ + PyNumberIMatmulProtocolImpl
++ + PyNumberIModProtocolImpl
++ + PyNumberIMulProtocolImpl
++ + PyNumberIOrProtocolImpl
++ + PyNumberIPowProtocolImpl
++ + PyNumberIRShiftProtocolImpl
++ + PyNumberISubProtocolImpl
++ + PyNumberITruedivProtocolImpl
++ + PyNumberIXorProtocolImpl
++ + PyNumberIndexProtocolImpl
++ + PyNumberIntProtocolImpl
++ + PyNumberInvertProtocolImpl
++ + PyNumberLShiftProtocolImpl
++ + PyNumberMatmulProtocolImpl
++ + PyNumberModProtocolImpl
++ + PyNumberMulProtocolImpl
++ + PyNumberNegProtocolImpl
++ + PyNumberOrProtocolImpl
++ + PyNumberPosProtocolImpl
++ + PyNumberPowProtocolImpl
++ + PyNumberRAddProtocolImpl
++ + PyNumberRAndProtocolImpl
++ + PyNumberRDivmodProtocolImpl
++ + PyNumberRFloordivProtocolImpl
++ + PyNumberRLShiftProtocolImpl
++ + PyNumberRMatmulProtocolImpl
++ + PyNumberRModProtocolImpl
++ + PyNumberRMulProtocolImpl
++ + PyNumberROrProtocolImpl
++ + PyNumberRPowProtocolImpl
++ + PyNumberRRShiftProtocolImpl
++ + PyNumberRShiftProtocolImpl
++ + PyNumberRSubProtocolImpl
++ + PyNumberRTruedivProtocolImpl
++ + PyNumberRXorProtocolImpl
++ + PyNumberRoundProtocolImpl
++ + PyNumberSubProtocolImpl
++ + PyNumberTruedivProtocolImpl
++ + PyNumberXorProtocolImpl
++ + PyObjectProtocolImpl,
+ {
+ fn tp_as_number() -> Option<ffi::PyNumberMethods> {
+ Some(ffi::PyNumberMethods {
+@@ -742,14 +791,12 @@ where
+ }
+ }
+
+-trait PyNumberAddProtocolImpl {
++pub trait PyNumberAddProtocolImpl {
+ fn nb_add() -> Option<ffi::binaryfunc> {
+ None
+ }
+ }
+
+-impl<'p, T> PyNumberAddProtocolImpl for T where T: PyNumberProtocol<'p> {}
+-
+ impl<T> PyNumberAddProtocolImpl for T
+ where
+ T: for<'p> PyNumberAddProtocol<'p>,
+@@ -764,14 +811,12 @@ where
+ }
+ }
+
+-trait PyNumberSubProtocolImpl {
++pub trait PyNumberSubProtocolImpl {
+ fn nb_subtract() -> Option<ffi::binaryfunc> {
+ None
+ }
+ }
+
+-impl<'p, T> PyNumberSubProtocolImpl for T where T: PyNumberProtocol<'p> {}
+-
+ impl<T> PyNumberSubProtocolImpl for T
+ where
+ T: for<'p> PyNumberSubProtocol<'p>,
+@@ -786,14 +831,12 @@ where
+ }
+ }
+
+-trait PyNumberMulProtocolImpl {
++pub trait PyNumberMulProtocolImpl {
+ fn nb_multiply() -> Option<ffi::binaryfunc> {
+ None
+ }
+ }
+
+-impl<'p, T> PyNumberMulProtocolImpl for T where T: PyNumberProtocol<'p> {}
+-
+ impl<T> PyNumberMulProtocolImpl for T
+ where
+ T: for<'p> PyNumberMulProtocol<'p>,
+@@ -808,14 +851,12 @@ where
+ }
+ }
+
+-trait PyNumberMatmulProtocolImpl {
++pub trait PyNumberMatmulProtocolImpl {
+ fn nb_matrix_multiply() -> Option<ffi::binaryfunc> {
+ None
+ }
+ }
+
+-impl<'p, T> PyNumberMatmulProtocolImpl for T where T: PyNumberProtocol<'p> {}
+-
+ impl<T> PyNumberMatmulProtocolImpl for T
+ where
+ T: for<'p> PyNumberMatmulProtocol<'p>,
+@@ -830,14 +871,12 @@ where
+ }
+ }
+
+-trait PyNumberTruedivProtocolImpl {
++pub trait PyNumberTruedivProtocolImpl {
+ fn nb_true_divide() -> Option<ffi::binaryfunc> {
+ None
+ }
+ }
+
+-impl<'p, T> PyNumberTruedivProtocolImpl for T where T: PyNumberProtocol<'p> {}
+-
+ impl<T> PyNumberTruedivProtocolImpl for T
+ where
+ T: for<'p> PyNumberTruedivProtocol<'p>,
+@@ -852,14 +891,12 @@ where
+ }
+ }
+
+-trait PyNumberFloordivProtocolImpl {
++pub trait PyNumberFloordivProtocolImpl {
+ fn nb_floor_divide() -> Option<ffi::binaryfunc> {
+ None
+ }
+ }
+
+-impl<'p, T> PyNumberFloordivProtocolImpl for T where T: PyNumberProtocol<'p> {}
+-
+ impl<T> PyNumberFloordivProtocolImpl for T
+ where
+ T: for<'p> PyNumberFloordivProtocol<'p>,
+@@ -874,14 +911,12 @@ where
+ }
+ }
+
+-trait PyNumberModProtocolImpl {
++pub trait PyNumberModProtocolImpl {
+ fn nb_remainder() -> Option<ffi::binaryfunc> {
+ None
+ }
+ }
+
+-impl<'p, T> PyNumberModProtocolImpl for T where T: PyNumberProtocol<'p> {}
+-
+ impl<T> PyNumberModProtocolImpl for T
+ where
+ T: for<'p> PyNumberModProtocol<'p>,
+@@ -896,14 +931,12 @@ where
+ }
+ }
+
+-trait PyNumberDivmodProtocolImpl {
++pub trait PyNumberDivmodProtocolImpl {
+ fn nb_divmod() -> Option<ffi::binaryfunc> {
+ None
+ }
+ }
+
+-impl<'p, T> PyNumberDivmodProtocolImpl for T where T: PyNumberProtocol<'p> {}
+-
+ impl<T> PyNumberDivmodProtocolImpl for T
+ where
+ T: for<'p> PyNumberDivmodProtocol<'p>,
+@@ -918,14 +951,12 @@ where
+ }
+ }
+
+-trait PyNumberPowProtocolImpl {
++pub trait PyNumberPowProtocolImpl {
+ fn nb_power() -> Option<ffi::ternaryfunc> {
+ None
+ }
+ }
+
+-impl<'p, T> PyNumberPowProtocolImpl for T where T: PyNumberProtocol<'p> {}
+-
+ impl<T> PyNumberPowProtocolImpl for T
+ where
+ T: for<'p> PyNumberPowProtocol<'p>,
+@@ -940,14 +971,12 @@ where
+ }
+ }
+
+-trait PyNumberLShiftProtocolImpl {
++pub trait PyNumberLShiftProtocolImpl {
+ fn nb_lshift() -> Option<ffi::binaryfunc> {
+ None
+ }
+ }
+
+-impl<'p, T> PyNumberLShiftProtocolImpl for T where T: PyNumberProtocol<'p> {}
+-
+ impl<T> PyNumberLShiftProtocolImpl for T
+ where
+ T: for<'p> PyNumberLShiftProtocol<'p>,
+@@ -962,14 +991,12 @@ where
+ }
+ }
+
+-trait PyNumberRShiftProtocolImpl {
++pub trait PyNumberRShiftProtocolImpl {
+ fn nb_rshift() -> Option<ffi::binaryfunc> {
+ None
+ }
+ }
+
+-impl<'p, T> PyNumberRShiftProtocolImpl for T where T: PyNumberProtocol<'p> {}
+-
+ impl<T> PyNumberRShiftProtocolImpl for T
+ where
+ T: for<'p> PyNumberRShiftProtocol<'p>,
+@@ -984,14 +1011,12 @@ where
+ }
+ }
+
+-trait PyNumberAndProtocolImpl {
++pub trait PyNumberAndProtocolImpl {
+ fn nb_and() -> Option<ffi::binaryfunc> {
+ None
+ }
+ }
+
+-impl<'p, T> PyNumberAndProtocolImpl for T where T: PyNumberProtocol<'p> {}
+-
+ impl<T> PyNumberAndProtocolImpl for T
+ where
+ T: for<'p> PyNumberAndProtocol<'p>,
+@@ -1006,14 +1031,12 @@ where
+ }
+ }
+
+-trait PyNumberXorProtocolImpl {
++pub trait PyNumberXorProtocolImpl {
+ fn nb_xor() -> Option<ffi::binaryfunc> {
+ None
+ }
+ }
+
+-impl<'p, T> PyNumberXorProtocolImpl for T where T: PyNumberProtocol<'p> {}
+-
+ impl<T> PyNumberXorProtocolImpl for T
+ where
+ T: for<'p> PyNumberXorProtocol<'p>,
+@@ -1028,14 +1051,12 @@ where
+ }
+ }
+
+-trait PyNumberOrProtocolImpl {
++pub trait PyNumberOrProtocolImpl {
+ fn nb_or() -> Option<ffi::binaryfunc> {
+ None
+ }
+ }
+
+-impl<'p, T> PyNumberOrProtocolImpl for T where T: PyNumberProtocol<'p> {}
+-
+ impl<T> PyNumberOrProtocolImpl for T
+ where
+ T: for<'p> PyNumberOrProtocol<'p>,
+@@ -1050,14 +1071,12 @@ where
+ }
+ }
+
+-trait PyNumberIAddProtocolImpl {
++pub trait PyNumberIAddProtocolImpl {
+ fn nb_inplace_add() -> Option<ffi::binaryfunc> {
+ None
+ }
+ }
+
+-impl<'p, T> PyNumberIAddProtocolImpl for T where T: PyNumberProtocol<'p> {}
+-
+ impl<T> PyNumberIAddProtocolImpl for T
+ where
+ T: for<'p> PyNumberIAddProtocol<'p>,
+@@ -1067,14 +1086,12 @@ where
+ }
+ }
+
+-trait PyNumberISubProtocolImpl {
++pub trait PyNumberISubProtocolImpl {
+ fn nb_inplace_subtract() -> Option<ffi::binaryfunc> {
+ None
+ }
+ }
+
+-impl<'p, T> PyNumberISubProtocolImpl for T where T: PyNumberProtocol<'p> {}
+-
+ impl<T> PyNumberISubProtocolImpl for T
+ where
+ T: for<'p> PyNumberISubProtocol<'p>,
+@@ -1084,14 +1101,12 @@ where
+ }
+ }
+
+-trait PyNumberIMulProtocolImpl {
++pub trait PyNumberIMulProtocolImpl {
+ fn nb_inplace_multiply() -> Option<ffi::binaryfunc> {
+ None
+ }
+ }
+
+-impl<'p, T> PyNumberIMulProtocolImpl for T where T: PyNumberProtocol<'p> {}
+-
+ impl<T> PyNumberIMulProtocolImpl for T
+ where
+ T: for<'p> PyNumberIMulProtocol<'p>,
+@@ -1101,14 +1116,12 @@ where
+ }
+ }
+
+-trait PyNumberIMatmulProtocolImpl {
++pub trait PyNumberIMatmulProtocolImpl {
+ fn nb_inplace_matrix_multiply() -> Option<ffi::binaryfunc> {
+ None
+ }
+ }
+
+-impl<'p, T> PyNumberIMatmulProtocolImpl for T where T: PyNumberProtocol<'p> {}
+-
+ impl<T> PyNumberIMatmulProtocolImpl for T
+ where
+ T: for<'p> PyNumberIMatmulProtocol<'p>,
+@@ -1118,14 +1131,12 @@ where
+ }
+ }
+
+-trait PyNumberITruedivProtocolImpl {
++pub trait PyNumberITruedivProtocolImpl {
+ fn nb_inplace_true_divide() -> Option<ffi::binaryfunc> {
+ None
+ }
+ }
+
+-impl<'p, T> PyNumberITruedivProtocolImpl for T where T: PyNumberProtocol<'p> {}
+-
+ impl<T> PyNumberITruedivProtocolImpl for T
+ where
+ T: for<'p> PyNumberITruedivProtocol<'p>,
+@@ -1135,14 +1146,12 @@ where
+ }
+ }
+
+-trait PyNumberIFloordivProtocolImpl {
++pub trait PyNumberIFloordivProtocolImpl {
+ fn nb_inplace_floor_divide() -> Option<ffi::binaryfunc> {
+ None
+ }
+ }
+
+-impl<'p, T> PyNumberIFloordivProtocolImpl for T where T: PyNumberProtocol<'p> {}
+-
+ impl<T> PyNumberIFloordivProtocolImpl for T
+ where
+ T: for<'p> PyNumberIFloordivProtocol<'p>,
+@@ -1152,14 +1161,12 @@ where
+ }
+ }
+
+-trait PyNumberIModProtocolImpl {
++pub trait PyNumberIModProtocolImpl {
+ fn nb_inplace_remainder() -> Option<ffi::binaryfunc> {
+ None
+ }
+ }
+
+-impl<'p, T> PyNumberIModProtocolImpl for T where T: PyNumberProtocol<'p> {}
+-
+ impl<T> PyNumberIModProtocolImpl for T
+ where
+ T: for<'p> PyNumberIModProtocol<'p>,
+@@ -1169,14 +1176,12 @@ where
+ }
+ }
+
+-trait PyNumberIPowProtocolImpl {
++pub trait PyNumberIPowProtocolImpl {
+ fn nb_inplace_power() -> Option<ffi::ternaryfunc> {
+ None
+ }
+ }
+
+-impl<'p, T> PyNumberIPowProtocolImpl for T where T: PyNumberProtocol<'p> {}
+-
+ impl<T> PyNumberIPowProtocolImpl for T
+ where
+ T: for<'p> PyNumberIPowProtocol<'p>,
+@@ -1186,14 +1191,12 @@ where
+ }
+ }
+
+-trait PyNumberILShiftProtocolImpl {
++pub trait PyNumberILShiftProtocolImpl {
+ fn nb_inplace_lshift() -> Option<ffi::binaryfunc> {
+ None
+ }
+ }
+
+-impl<'p, T> PyNumberILShiftProtocolImpl for T where T: PyNumberProtocol<'p> {}
+-
+ impl<T> PyNumberILShiftProtocolImpl for T
+ where
+ T: for<'p> PyNumberILShiftProtocol<'p>,
+@@ -1203,14 +1206,12 @@ where
+ }
+ }
+
+-trait PyNumberIRShiftProtocolImpl {
++pub trait PyNumberIRShiftProtocolImpl {
+ fn nb_inplace_rshift() -> Option<ffi::binaryfunc> {
+ None
+ }
+ }
+
+-impl<'p, T> PyNumberIRShiftProtocolImpl for T where T: PyNumberProtocol<'p> {}
+-
+ impl<T> PyNumberIRShiftProtocolImpl for T
+ where
+ T: for<'p> PyNumberIRShiftProtocol<'p>,
+@@ -1220,14 +1221,12 @@ where
+ }
+ }
+
+-trait PyNumberIAndProtocolImpl {
++pub trait PyNumberIAndProtocolImpl {
+ fn nb_inplace_and() -> Option<ffi::binaryfunc> {
+ None
+ }
+ }
+
+-impl<'p, T> PyNumberIAndProtocolImpl for T where T: PyNumberProtocol<'p> {}
+-
+ impl<T> PyNumberIAndProtocolImpl for T
+ where
+ T: for<'p> PyNumberIAndProtocol<'p>,
+@@ -1237,14 +1236,12 @@ where
+ }
+ }
+
+-trait PyNumberIXorProtocolImpl {
++pub trait PyNumberIXorProtocolImpl {
+ fn nb_inplace_xor() -> Option<ffi::binaryfunc> {
+ None
+ }
+ }
+
+-impl<'p, T> PyNumberIXorProtocolImpl for T where T: PyNumberProtocol<'p> {}
+-
+ impl<T> PyNumberIXorProtocolImpl for T
+ where
+ T: for<'p> PyNumberIXorProtocol<'p>,
+@@ -1254,14 +1251,12 @@ where
+ }
+ }
+
+-trait PyNumberIOrProtocolImpl {
++pub trait PyNumberIOrProtocolImpl {
+ fn nb_inplace_or() -> Option<ffi::binaryfunc> {
+ None
+ }
+ }
+
+-impl<'p, T> PyNumberIOrProtocolImpl for T where T: PyNumberProtocol<'p> {}
+-
+ impl<T> PyNumberIOrProtocolImpl for T
+ where
+ T: for<'p> PyNumberIOrProtocol<'p>,
+@@ -1397,14 +1392,12 @@ pub trait PyNumberROrProtocolImpl {
+
+ impl<'p, T> PyNumberROrProtocolImpl for T where T: PyNumberProtocol<'p> {}
+
+-trait PyNumberNegProtocolImpl {
++pub trait PyNumberNegProtocolImpl {
+ fn nb_negative() -> Option<ffi::unaryfunc> {
+ None
+ }
+ }
+
+-impl<'p, T> PyNumberNegProtocolImpl for T where T: PyNumberProtocol<'p> {}
+-
+ impl<T> PyNumberNegProtocolImpl for T
+ where
+ T: for<'p> PyNumberNegProtocol<'p>,
+@@ -1420,14 +1413,12 @@ where
+ }
+ }
+
+-trait PyNumberPosProtocolImpl {
++pub trait PyNumberPosProtocolImpl {
+ fn nb_positive() -> Option<ffi::unaryfunc> {
+ None
+ }
+ }
+
+-impl<'p, T> PyNumberPosProtocolImpl for T where T: PyNumberProtocol<'p> {}
+-
+ impl<T> PyNumberPosProtocolImpl for T
+ where
+ T: for<'p> PyNumberPosProtocol<'p>,
+@@ -1442,14 +1433,12 @@ where
+ }
+ }
+
+-trait PyNumberAbsProtocolImpl {
++pub trait PyNumberAbsProtocolImpl {
+ fn nb_absolute() -> Option<ffi::unaryfunc> {
+ None
+ }
+ }
+
+-impl<'p, T> PyNumberAbsProtocolImpl for T where T: PyNumberProtocol<'p> {}
+-
+ impl<T> PyNumberAbsProtocolImpl for T
+ where
+ T: for<'p> PyNumberAbsProtocol<'p>,
+@@ -1464,14 +1453,12 @@ where
+ }
+ }
+
+-trait PyNumberInvertProtocolImpl {
++pub trait PyNumberInvertProtocolImpl {
+ fn nb_invert() -> Option<ffi::unaryfunc> {
+ None
+ }
+ }
+
+-impl<'p, T> PyNumberInvertProtocolImpl for T where T: PyNumberProtocol<'p> {}
+-
+ impl<T> PyNumberInvertProtocolImpl for T
+ where
+ T: for<'p> PyNumberInvertProtocol<'p>,
+@@ -1486,14 +1473,12 @@ where
+ }
+ }
+
+-trait PyNumberIntProtocolImpl {
++pub trait PyNumberIntProtocolImpl {
+ fn nb_int() -> Option<ffi::unaryfunc> {
+ None
+ }
+ }
+
+-impl<'p, T> PyNumberIntProtocolImpl for T where T: PyNumberProtocol<'p> {}
+-
+ impl<T> PyNumberIntProtocolImpl for T
+ where
+ T: for<'p> PyNumberIntProtocol<'p>,
+@@ -1508,14 +1493,12 @@ where
+ }
+ }
+
+-trait PyNumberFloatProtocolImpl {
++pub trait PyNumberFloatProtocolImpl {
+ fn nb_float() -> Option<ffi::unaryfunc> {
+ None
+ }
+ }
+
+-impl<'p, T> PyNumberFloatProtocolImpl for T where T: PyNumberProtocol<'p> {}
+-
+ impl<T> PyNumberFloatProtocolImpl for T
+ where
+ T: for<'p> PyNumberFloatProtocol<'p>,
+@@ -1530,14 +1513,12 @@ where
+ }
+ }
+
+-trait PyNumberIndexProtocolImpl {
++pub trait PyNumberIndexProtocolImpl {
+ fn nb_index() -> Option<ffi::unaryfunc> {
+ None
+ }
+ }
+
+-impl<'p, T> PyNumberIndexProtocolImpl for T where T: PyNumberProtocol<'p> {}
+-
+ impl<T> PyNumberIndexProtocolImpl for T
+ where
+ T: for<'p> PyNumberIndexProtocol<'p>,
+@@ -1552,18 +1533,14 @@ where
+ }
+ }
+
+-trait PyNumberComplexProtocolImpl {
++pub trait PyNumberComplexProtocolImpl {
+ fn __complex__() -> Option<PyMethodDef> {
+ None
+ }
+ }
+
+-impl<'p, T> PyNumberComplexProtocolImpl for T where T: PyNumberProtocol<'p> {}
+-
+-trait PyNumberRoundProtocolImpl {
++pub trait PyNumberRoundProtocolImpl {
+ fn __round__() -> Option<PyMethodDef> {
+ None
+ }
+ }
+-
+-impl<'p, T> PyNumberRoundProtocolImpl for T where T: PyNumberProtocol<'p> {}
+diff --git a/src/class/pyasync.rs b/src/class/pyasync.rs
+index 9afb72c17..e04aea33b 100644
+--- a/src/class/pyasync.rs
++++ b/src/class/pyasync.rs
+@@ -100,11 +100,12 @@ pub trait PyAsyncProtocolImpl {
+ }
+ }
+
+-impl<T> PyAsyncProtocolImpl for T {}
+-
+ impl<'p, T> PyAsyncProtocolImpl for T
+ where
+- T: PyAsyncProtocol<'p>,
++ T: PyAsyncProtocol<'p>
++ + PyAsyncAwaitProtocolImpl
++ + PyAsyncAiterProtocolImpl
++ + PyAsyncAnextProtocolImpl,
+ {
+ #[inline]
+ fn tp_as_async() -> Option<ffi::PyAsyncMethods> {
+@@ -130,14 +131,12 @@ where
+ }
+ }
+
+-trait PyAsyncAwaitProtocolImpl {
++pub trait PyAsyncAwaitProtocolImpl {
+ fn am_await() -> Option<ffi::unaryfunc> {
+ None
+ }
+ }
+
+-impl<'p, T> PyAsyncAwaitProtocolImpl for T where T: PyAsyncProtocol<'p> {}
+-
+ impl<T> PyAsyncAwaitProtocolImpl for T
+ where
+ T: for<'p> PyAsyncAwaitProtocol<'p>,
+@@ -153,14 +152,12 @@ where
+ }
+ }
+
+-trait PyAsyncAiterProtocolImpl {
++pub trait PyAsyncAiterProtocolImpl {
+ fn am_aiter() -> Option<ffi::unaryfunc> {
+ None
+ }
+ }
+
+-impl<'p, T> PyAsyncAiterProtocolImpl for T where T: PyAsyncProtocol<'p> {}
+-
+ impl<T> PyAsyncAiterProtocolImpl for T
+ where
+ T: for<'p> PyAsyncAiterProtocol<'p>,
+@@ -176,14 +173,12 @@ where
+ }
+ }
+
+-trait PyAsyncAnextProtocolImpl {
++pub trait PyAsyncAnextProtocolImpl {
+ fn am_anext() -> Option<ffi::unaryfunc> {
+ None
+ }
+ }
+
+-impl<'p, T> PyAsyncAnextProtocolImpl for T where T: PyAsyncProtocol<'p> {}
+-
+ mod anext {
+ use super::{PyAsyncAnextProtocol, PyAsyncAnextProtocolImpl};
+ use crate::callback::CallbackConverter;
+diff --git a/src/class/sequence.rs b/src/class/sequence.rs
+index 23771ba0b..840c11b97 100644
+--- a/src/class/sequence.rs
++++ b/src/class/sequence.rs
+@@ -139,11 +139,19 @@ pub trait PySequenceProtocolImpl {
+ }
+ }
+
+-impl<T> PySequenceProtocolImpl for T {}
+-
+ impl<'p, T> PySequenceProtocolImpl for T
+ where
+- T: PySequenceProtocol<'p>,
++ T: PySequenceProtocol<'p>
++ + PySequenceConcatProtocolImpl
++ + PySequenceContainsProtocolImpl
++ + PySequenceGetItemProtocolImpl
++ + PySequenceInplaceConcatProtocolImpl
++ + PySequenceInplaceRepeatProtocolImpl
++ + PySequenceLenProtocolImpl
++ + PySequenceRepeatProtocolImpl
++ + sq_ass_item_impl::SetItem
++ + sq_ass_item_impl::DelItem
++ + sq_ass_item_impl::DelSetItem,
+ {
+ fn tp_as_sequence() -> Option<ffi::PySequenceMethods> {
+ Some(ffi::PySequenceMethods {
+@@ -161,14 +169,12 @@ where
+ }
+ }
+
+-trait PySequenceLenProtocolImpl {
++pub trait PySequenceLenProtocolImpl {
+ fn sq_length() -> Option<ffi::lenfunc> {
+ None
+ }
+ }
+
+-impl<'p, T> PySequenceLenProtocolImpl for T where T: PySequenceProtocol<'p> {}
+-
+ impl<T> PySequenceLenProtocolImpl for T
+ where
+ T: for<'p> PySequenceLenProtocol<'p>,
+@@ -178,14 +184,12 @@ where
+ }
+ }
+
+-trait PySequenceGetItemProtocolImpl {
++pub trait PySequenceGetItemProtocolImpl {
+ fn sq_item() -> Option<ffi::ssizeargfunc> {
+ None
+ }
+ }
+
+-impl<'p, T> PySequenceGetItemProtocolImpl for T where T: PySequenceProtocol<'p> {}
+-
+ impl<T> PySequenceGetItemProtocolImpl for T
+ where
+ T: for<'p> PySequenceGetItemProtocol<'p>,
+@@ -214,7 +218,7 @@ mod sq_ass_item_impl {
+ /// item assignment and deletion.
+ pub(super) fn sq_ass_item<'p, T>() -> Option<ffi::ssizeobjargproc>
+ where
+- T: PySequenceProtocol<'p>,
++ T: PySequenceProtocol<'p> + SetItem + DelItem + DelSetItem,
+ {
+ if let Some(del_set_item) = T::del_set_item() {
+ Some(del_set_item)
+@@ -227,15 +231,8 @@ mod sq_ass_item_impl {
+ }
+ }
+
+- trait SetItem {
+- fn set_item() -> Option<ffi::ssizeobjargproc>;
+- }
+-
+- impl<'p, T> SetItem for T
+- where
+- T: PySequenceProtocol<'p>,
+- {
+- default fn set_item() -> Option<ffi::ssizeobjargproc> {
++ pub trait SetItem {
++ fn set_item() -> Option<ffi::ssizeobjargproc> {
+ None
+ }
+ }
+@@ -282,14 +279,12 @@ mod sq_ass_item_impl {
+ }
+ }
+
+- trait DelItem {
++ pub trait DelItem {
+ fn del_item() -> Option<ffi::ssizeobjargproc> {
+ None
+ }
+ }
+
+- impl<'p, T> DelItem for T where T: PySequenceProtocol<'p> {}
+-
+ impl<T> DelItem for T
+ where
+ T: for<'p> PySequenceDelItemProtocol<'p>,
+@@ -328,14 +323,12 @@ mod sq_ass_item_impl {
+ }
+ }
+
+- trait DelSetItem {
++ pub trait DelSetItem {
+ fn del_set_item() -> Option<ffi::ssizeobjargproc> {
+ None
+ }
+ }
+
+- impl<'p, T> DelSetItem for T where T: PySequenceProtocol<'p> {}
+-
+ impl<T> DelSetItem for T
+ where
+ T: for<'p> PySequenceSetItemProtocol<'p> + for<'p> PySequenceDelItemProtocol<'p>,
+@@ -375,14 +368,12 @@ mod sq_ass_item_impl {
+ }
+ }
+
+-trait PySequenceContainsProtocolImpl {
++pub trait PySequenceContainsProtocolImpl {
+ fn sq_contains() -> Option<ffi::objobjproc> {
+ None
+ }
+ }
+
+-impl<'p, T> PySequenceContainsProtocolImpl for T where T: PySequenceProtocol<'p> {}
+-
+ impl<T> PySequenceContainsProtocolImpl for T
+ where
+ T: for<'p> PySequenceContainsProtocol<'p>,
+@@ -398,14 +389,12 @@ where
+ }
+ }
+
+-trait PySequenceConcatProtocolImpl {
++pub trait PySequenceConcatProtocolImpl {
+ fn sq_concat() -> Option<ffi::binaryfunc> {
+ None
+ }
+ }
+
+-impl<'p, T> PySequenceConcatProtocolImpl for T where T: PySequenceProtocol<'p> {}
+-
+ impl<T> PySequenceConcatProtocolImpl for T
+ where
+ T: for<'p> PySequenceConcatProtocol<'p>,
+@@ -420,14 +409,12 @@ where
+ }
+ }
+
+-trait PySequenceRepeatProtocolImpl {
++pub trait PySequenceRepeatProtocolImpl {
+ fn sq_repeat() -> Option<ffi::ssizeargfunc> {
+ None
+ }
+ }
+
+-impl<'p, T> PySequenceRepeatProtocolImpl for T where T: PySequenceProtocol<'p> {}
+-
+ impl<T> PySequenceRepeatProtocolImpl for T
+ where
+ T: for<'p> PySequenceRepeatProtocol<'p>,
+@@ -442,14 +429,12 @@ where
+ }
+ }
+
+-trait PySequenceInplaceConcatProtocolImpl {
++pub trait PySequenceInplaceConcatProtocolImpl {
+ fn sq_inplace_concat() -> Option<ffi::binaryfunc> {
+ None
+ }
+ }
+
+-impl<'p, T> PySequenceInplaceConcatProtocolImpl for T where T: PySequenceProtocol<'p> {}
+-
+ impl<T> PySequenceInplaceConcatProtocolImpl for T
+ where
+ T: for<'p> PySequenceInplaceConcatProtocol<'p>,
+@@ -464,14 +449,12 @@ where
+ }
+ }
+
+-trait PySequenceInplaceRepeatProtocolImpl {
++pub trait PySequenceInplaceRepeatProtocolImpl {
+ fn sq_inplace_repeat() -> Option<ffi::ssizeargfunc> {
+ None
+ }
+ }
+
+-impl<'p, T> PySequenceInplaceRepeatProtocolImpl for T where T: PySequenceProtocol<'p> {}
+-
+ impl<T> PySequenceInplaceRepeatProtocolImpl for T
+ where
+ T: for<'p> PySequenceInplaceRepeatProtocol<'p>,
+diff --git a/src/conversion.rs b/src/conversion.rs
+index a3bca1175..76094694d 100644
+--- a/src/conversion.rs
++++ b/src/conversion.rs
+@@ -110,6 +110,7 @@ pub trait ToBorrowedObject: ToPyObject {
+
+ impl<T> ToBorrowedObject for T where T: ToPyObject {}
+
++/*MJDFIXME
+ impl<T> ToBorrowedObject for T
+ where
+ T: ToPyObject + AsPyPointer,
+@@ -120,7 +121,7 @@ where
+ {
+ f(self.as_ptr())
+ }
+-}
++}*/
+
+ /// Similar to [std::convert::From], just that it requires a gil token.
+ pub trait FromPy<T>: Sized {
+@@ -139,7 +140,7 @@ impl<T, U> IntoPy<U> for T
+ where
+ U: FromPy<T>,
+ {
+- default fn into_py(self, py: Python) -> U {
++ fn into_py(self, py: Python) -> U {
+ U::from_py(self, py)
+ }
+ }
+@@ -243,7 +244,7 @@ where
+ T: PyTryFrom<'a>,
+ {
+ #[inline]
+- default fn extract(ob: &'a PyAny) -> PyResult<&'a T> {
++ fn extract(ob: &'a PyAny) -> PyResult<&'a T> {
+ Ok(T::try_from(ob)?)
+ }
+ }
+@@ -254,7 +255,7 @@ where
+ T: PyTryFrom<'a>,
+ {
+ #[inline]
+- default fn extract(ob: &'a PyAny) -> PyResult<&'a mut T> {
++ fn extract(ob: &'a PyAny) -> PyResult<&'a mut T> {
+ Ok(T::try_from_mut(ob)?)
+ }
+ }
+diff --git a/src/instance.rs b/src/instance.rs
+index 68bd45ec3..ccbd07c57 100644
+--- a/src/instance.rs
++++ b/src/instance.rs
+@@ -358,7 +358,7 @@ impl<T> Py<T> {
+ }
+
+ /// Specialization workaround
+-trait AsPyRefDispatch<T: PyTypeInfo>: AsPyPointer {
++pub trait AsPyRefDispatch<T: PyTypeInfo>: AsPyPointer {
+ fn as_ref_dispatch(&self, _py: Python) -> &T {
+ unsafe {
+ let ptr = (self.as_ptr() as *mut u8).offset(T::OFFSET) as *mut T;
+@@ -373,8 +373,6 @@ trait AsPyRefDispatch<T: PyTypeInfo>: AsPyPointer {
+ }
+ }
+
+-impl<T: PyTypeInfo> AsPyRefDispatch<T> for Py<T> {}
+-
+ impl<T: PyTypeInfo + PyNativeType> AsPyRefDispatch<T> for Py<T> {
+ fn as_ref_dispatch(&self, _py: Python) -> &T {
+ unsafe { &*(self as *const instance::Py<T> as *const T) }
+@@ -387,6 +385,7 @@ impl<T: PyTypeInfo + PyNativeType> AsPyRefDispatch<T> for Py<T> {
+ impl<T> AsPyRef<T> for Py<T>
+ where
+ T: PyTypeInfo,
++ Py<T>: AsPyRefDispatch<T>,
+ {
+ #[inline]
+ fn as_ref(&self, py: Python) -> PyRef<T> {
+@@ -538,7 +537,7 @@ pub struct ManagedPyRef<'p, T: ToPyObject + ?Sized> {
+
+ /// This should eventually be replaced with a generic `IntoPy` trait impl by figuring
+ /// out the correct lifetime annotation to make the compiler happy
+-impl<'p, T: ToPyObject> ManagedPyRef<'p, T> {
++impl<'p, T: ToPyObject + ManagedPyRefDispatch> ManagedPyRef<'p, T> {
+ pub fn from_to_pyobject(py: Python<'p>, to_pyobject: &T) -> Self {
+ to_pyobject.to_managed_py_ref(py)
+ }
+@@ -577,7 +576,6 @@ pub trait ManagedPyRefDispatch: ToPyObject {
+ ///
+ /// Note that the actual implementations are part of the trait declaration to avoid
+ /// a specialization error
+-impl<T: ToPyObject + ?Sized> ManagedPyRefDispatch for T {}
+
+ /// Case 2: It's an object on the python heap, we're just storing a borrowed pointer.
+ /// The object we're getting is an owned pointer, it might have it's own drop impl.
+@@ -595,13 +593,14 @@ impl<T: ToPyObject + AsPyPointer + ?Sized> ManagedPyRefDispatch for T {
+ fn drop_impl(_: &mut ManagedPyRef<T>) {}
+ }
+
+-impl<'p, T: ToPyObject + ?Sized> Drop for ManagedPyRef<'p, T> {
++/* MJDFIXME
++impl<'p, T: ToPyObject + ?Sized + AsPyPointer> Drop for ManagedPyRef<'p, T> {
+ /// Uses the internal [ManagedPyRefDispatch] trait to get the right drop impl without causing
+ /// a specialization error
+ fn drop(&mut self) {
+ ManagedPyRefDispatch::drop_impl(self);
+ }
+-}
++}*/
+
+ #[cfg(test)]
+ mod test {
+diff --git a/src/lib.rs b/src/lib.rs
+index b5cb5402a..65fb611db 100755
+--- a/src/lib.rs
++++ b/src/lib.rs
+@@ -1,5 +1,3 @@
+-#![feature(specialization)]
+-
+ //! Rust bindings to the Python interpreter.
+ //!
+ //! Look at [the guide](https://pyo3.rs/) for a detailed introduction.
+diff --git a/src/object.rs b/src/object.rs
+index 128ef8377..5d46bfc71 100644
+--- a/src/object.rs
++++ b/src/object.rs
+@@ -171,7 +171,7 @@ impl PyObject {
+ /// This is equivalent to the Python expression 'self.attr_name'.
+ pub fn getattr<N>(&self, py: Python, attr_name: N) -> PyResult<PyObject>
+ where
+- N: ToPyObject,
++ N: ToPyObject + ToBorrowedObject,
+ {
+ attr_name.with_borrowed_ptr(py, |attr_name| unsafe {
+ PyObject::from_owned_ptr_or_err(py, ffi::PyObject_GetAttr(self.as_ptr(), attr_name))
+diff --git a/src/type_object.rs b/src/type_object.rs
+index 4cdd2d8db..3038afb40 100644
+--- a/src/type_object.rs
++++ b/src/type_object.rs
+@@ -2,6 +2,7 @@
+
+ //! Python type object information
+
++use crate::class::gc::PyGCProtocolImpl;
+ use crate::class::methods::PyMethodDefType;
+ use crate::err::{PyErr, PyResult};
+ use crate::instance::{Py, PyNativeType};
+@@ -249,7 +250,19 @@ pub unsafe trait PyTypeObject {
+
+ unsafe impl<T> PyTypeObject for T
+ where
+- T: PyTypeInfo + PyMethodsProtocol + PyObjectAlloc,
++ T: PyTypeInfo
++ + PyMethodsProtocol
++ + PyObjectAlloc
++ + class::gc::PyGCProtocolImpl
++ + class::context::PyContextProtocolImpl
++ + class::descr::PyDescrProtocolImpl
++ + class::iter::PyIterProtocolImpl
++ + class::basic::PyObjectProtocolImpl
++ + class::number::PyNumberProtocolImpl
++ + class::mapping::PyMappingProtocolImpl
++ + class::sequence::PySequenceProtocolImpl
++ + class::pyasync::PyAsyncProtocolImpl
++ + class::buffer::PyBufferProtocolImpl,
+ {
+ fn init_type() -> NonNull<ffi::PyTypeObject> {
+ let type_object = unsafe { <Self as PyTypeInfo>::type_object() };
+@@ -297,7 +310,19 @@ impl<T> PyTypeCreate for T where T: PyObjectAlloc + PyTypeObject + Sized {}
+ #[cfg(not(Py_LIMITED_API))]
+ pub fn initialize_type<T>(py: Python, module_name: Option<&str>) -> PyResult<*mut ffi::PyTypeObject>
+ where
+- T: PyObjectAlloc + PyTypeInfo + PyMethodsProtocol,
++ T: PyObjectAlloc
++ + PyTypeInfo
++ + PyMethodsProtocol
++ + class::gc::PyGCProtocolImpl
++ + class::context::PyContextProtocolImpl
++ + class::descr::PyDescrProtocolImpl
++ + class::iter::PyIterProtocolImpl
++ + class::basic::PyObjectProtocolImpl
++ + class::number::PyNumberProtocolImpl
++ + class::mapping::PyMappingProtocolImpl
++ + class::sequence::PySequenceProtocolImpl
++ + class::pyasync::PyAsyncProtocolImpl
++ + class::buffer::PyBufferProtocolImpl,
+ {
+ let type_object: &mut ffi::PyTypeObject = unsafe { T::type_object() };
+ let base_type_object: &mut ffi::PyTypeObject =
+@@ -438,12 +463,25 @@ fn py_class_flags<T: PyTypeInfo>(type_object: &mut ffi::PyTypeObject) {
+ }
+ }
+
+-fn py_class_method_defs<T: PyMethodsProtocol>() -> (
++fn py_class_method_defs<T>() -> (
+ Option<ffi::newfunc>,
+ Option<ffi::initproc>,
+ Option<ffi::PyCFunctionWithKeywords>,
+ Vec<ffi::PyMethodDef>,
+-) {
++)
++where
++ T: PyMethodsProtocol
++ + class::gc::PyGCProtocolImpl
++ + class::context::PyContextProtocolImpl
++ + class::descr::PyDescrProtocolImpl
++ + class::iter::PyIterProtocolImpl
++ + class::basic::PyObjectProtocolImpl
++ + class::number::PyNumberProtocolImpl
++ + class::mapping::PyMappingProtocolImpl
++ + class::sequence::PySequenceProtocolImpl
++ + class::pyasync::PyAsyncProtocolImpl
++ + class::buffer::PyBufferProtocolImpl,
++{
+ let mut defs = Vec::new();
+ let mut call = None;
+ let mut new = None;
+@@ -500,7 +538,9 @@ fn py_class_method_defs<T: PyMethodsProtocol>() -> (
+ (new, init, call, defs)
+ }
+
+-fn py_class_async_methods<T>(defs: &mut Vec<ffi::PyMethodDef>) {
++fn py_class_async_methods<T: class::pyasync::PyAsyncProtocolImpl>(
++ defs: &mut Vec<ffi::PyMethodDef>,
++) {
+ for def in <T as class::pyasync::PyAsyncProtocolImpl>::methods() {
+ defs.push(def.as_method_def());
+ }
+diff --git a/src/types/sequence.rs b/src/types/sequence.rs
+index d81ffbdd9..08d38b072 100644
+--- a/src/types/sequence.rs
++++ b/src/types/sequence.rs
+@@ -244,11 +244,12 @@ impl<'a, T> FromPyObject<'a> for Vec<T>
+ where
+ T: FromPyObject<'a>,
+ {
+- default fn extract(obj: &'a PyAny) -> PyResult<Self> {
++ fn extract(obj: &'a PyAny) -> PyResult<Self> {
+ extract_sequence(obj)
+ }
+ }
+
++/* MJDFIXME
+ impl<'source, T> FromPyObject<'source> for Vec<T>
+ where
+ for<'a> T: FromPyObject<'a> + buffer::Element + Copy,
+@@ -267,7 +268,7 @@ where
+ // fall back to sequence protocol
+ extract_sequence(obj)
+ }
+-}
++}*/
+
+ fn extract_sequence<'s, T>(obj: &'s PyAny) -> PyResult<Vec<T>>
+ where
diff --git a/srcpkgs/anki/files/pyo3-patches/0013-specialization-b0561da60c6c00fc8cd930efa34113a602a830e2.patch b/srcpkgs/anki/files/pyo3-patches/0013-specialization-b0561da60c6c00fc8cd930efa34113a602a830e2.patch
new file mode 100644
index 00000000000..8e8e4e9cff7
--- /dev/null
+++ b/srcpkgs/anki/files/pyo3-patches/0013-specialization-b0561da60c6c00fc8cd930efa34113a602a830e2.patch
@@ -0,0 +1,69 @@
+From b0561da60c6c00fc8cd930efa34113a602a830e2 Mon Sep 17 00:00:00 2001
+From: Donlon <mdonlon@treyarch.com>
+Date: Wed, 30 Oct 2019 07:02:06 -0700
+Subject: [PATCH] Stubbed out a bunch of tests
+
+---
+ src/instance.rs | 3 ++-
+ tests/test_class_basics.rs | 16 ++++++++++++++--
+
+diff --git a/src/instance.rs b/src/instance.rs
+index ccbd07c57..af0cd4382 100644
+--- a/src/instance.rs
++++ b/src/instance.rs
+@@ -602,6 +602,7 @@ impl<'p, T: ToPyObject + ?Sized + AsPyPointer> Drop for ManagedPyRef<'p, T> {
+ }
+ }*/
+
++/* MJDFIXME
+ #[cfg(test)]
+ mod test {
+ use crate::ffi;
+@@ -640,4 +641,4 @@ mod test {
+ ffi::Py_DECREF(ptr);
+ }
+ }
+-}
++}*/
+diff --git a/tests/test_class_basics.rs b/tests/test_class_basics.rs
+index 00e2674e6..53e4df51e 100644
+--- a/tests/test_class_basics.rs
++++ b/tests/test_class_basics.rs
+@@ -1,3 +1,4 @@
++use pyo3::class;
+ use pyo3::prelude::*;
+ use pyo3::py_run;
+ use pyo3::type_object::initialize_type;
+@@ -7,6 +8,17 @@ mod common;
+ #[pyclass]
+ struct EmptyClass {}
+
++impl class::gc::PyGCProtocolImpl for EmptyClass {}
++impl class::buffer::PyBufferProtocolImpl for EmptyClass {}
++impl class::context::PyContextProtocolImpl for EmptyClass {}
++impl class::iter::PyIterProtocolImpl for EmptyClass {}
++impl class::descr::PyDescrProtocolImpl for EmptyClass {}
++impl class::basic::PyObjectProtocolImpl for EmptyClass {}
++impl class::number::PyNumberProtocolImpl for EmptyClass {}
++impl class::mapping::PyMappingProtocolImpl for EmptyClass {}
++impl class::sequence::PySequenceProtocolImpl for EmptyClass {}
++impl class::pyasync::PyAsyncProtocolImpl for EmptyClass {}
++
+ #[test]
+ fn empty_class() {
+ let gil = Python::acquire_gil();
+@@ -17,7 +29,7 @@ fn empty_class() {
+
+ py_assert!(py, typeobj, "typeobj.__name__ == 'EmptyClass'");
+ }
+-
++/*
+ /// Line1
+ ///Line2
+ /// Line3
+@@ -77,4 +89,4 @@ fn empty_class_in_module() {
+ initialize_type::<EmptyClassInModule>(py, Some("test_module.nested")).unwrap();
+ let module: String = ty.getattr("__module__").unwrap().extract().unwrap();
+ assert_eq!(module, "test_module.nested");
+-}
++}*/
diff --git a/srcpkgs/anki/files/pyo3-patches/0014-specialization-c7e52948d9147689701a24de2fcdffafc32ebe62.patch b/srcpkgs/anki/files/pyo3-patches/0014-specialization-c7e52948d9147689701a24de2fcdffafc32ebe62.patch
new file mode 100644
index 00000000000..1d00862ff05
--- /dev/null
+++ b/srcpkgs/anki/files/pyo3-patches/0014-specialization-c7e52948d9147689701a24de2fcdffafc32ebe62.patch
@@ -0,0 +1,93 @@
+From c7e52948d9147689701a24de2fcdffafc32ebe62 Mon Sep 17 00:00:00 2001
+From: Martin Donlon <github-martin@donlons.com>
+Date: Wed, 30 Oct 2019 22:12:49 -0700
+Subject: [PATCH] pyclass protocols attribute parsing
+
+---
+ .vscode/settings.json | 4 ++++
+ pyo3-derive-backend/src/pyclass.rs | 32 ++++++++++++++++++++++++++++++
+ tests/test_class_basics.rs | 2 +-
+ 3 files changed, 37 insertions(+), 1 deletion(-)
+ create mode 100644 .vscode/settings.json
+
+diff --git a/.vscode/settings.json b/.vscode/settings.json
+new file mode 100644
+index 000000000..2b5f84ecc
+--- /dev/null
++++ b/.vscode/settings.json
+@@ -0,0 +1,4 @@
++{
++ "rust.all_targets": false,
++ "editor.formatOnSave": true
++}
+\ No newline at end of file
+diff --git a/pyo3-derive-backend/src/pyclass.rs b/pyo3-derive-backend/src/pyclass.rs
+index 1f902a959..3ac5d4cde 100644
+--- a/pyo3-derive-backend/src/pyclass.rs
++++ b/pyo3-derive-backend/src/pyclass.rs
+@@ -16,6 +16,7 @@ pub struct PyClassArgs {
+ pub flags: Vec<syn::Expr>,
+ pub base: syn::TypePath,
+ pub module: Option<syn::LitStr>,
++ pub protocols: Vec<syn::Ident>,
+ }
+
+ impl Parse for PyClassArgs {
+@@ -40,6 +41,7 @@ impl Default for PyClassArgs {
+ // are no other flags
+ flags: vec![parse_quote! {0}],
+ base: parse_quote! {pyo3::types::PyAny},
++ protocols: Vec::new(),
+ }
+ }
+ }
+@@ -110,6 +112,36 @@ impl PyClassArgs {
+ ));
+ }
+ },
++ "protocols" => match *assign.right {
++ syn::Expr::Array(syn::ExprArray { ref elems, .. }) => {
++ for elem in elems.iter() {
++ match elem {
++ syn::Expr::Path(syn::ExprPath { ref path, .. }) => {
++ if path.segments.len() == 1 {
++ self.protocols.push(path.segments[0].ident.clone());
++ } else {
++ return Err(syn::Error::new_spanned(
++ path.clone(),
++ "Expected an unqualified name for protocol",
++ ));
++ }
++ }
++ _ => {
++ return Err(syn::Error::new_spanned(
++ elem.clone(),
++ "Wrong format for protocol entry",
++ ));
++ }
++ }
++ }
++ }
++ _ => {
++ return Err(syn::Error::new_spanned(
++ *assign.right.clone(),
++ "Wrong format for protocol",
++ ));
++ }
++ },
+ _ => {
+ return Err(syn::Error::new_spanned(
+ *assign.left.clone(),
+diff --git a/tests/test_class_basics.rs b/tests/test_class_basics.rs
+index 53e4df51e..c8e1a42df 100644
+--- a/tests/test_class_basics.rs
++++ b/tests/test_class_basics.rs
+@@ -5,7 +5,7 @@ use pyo3::type_object::initialize_type;
+
+ mod common;
+
+-#[pyclass]
++#[pyclass(protocols=[PySequenceProtocol])]
+ struct EmptyClass {}
+
+ impl class::gc::PyGCProtocolImpl for EmptyClass {}
diff --git a/srcpkgs/anki/files/pyo3-patches/0015-specialization-81f2c30b15f467c9f5ab139564be0099fba5b27f.patch b/srcpkgs/anki/files/pyo3-patches/0015-specialization-81f2c30b15f467c9f5ab139564be0099fba5b27f.patch
new file mode 100644
index 00000000000..b7436efdee9
--- /dev/null
+++ b/srcpkgs/anki/files/pyo3-patches/0015-specialization-81f2c30b15f467c9f5ab139564be0099fba5b27f.patch
@@ -0,0 +1,159 @@
+From 81f2c30b15f467c9f5ab139564be0099fba5b27f Mon Sep 17 00:00:00 2001
+From: Martin Donlon <github-martin@donlons.com>
+Date: Thu, 31 Oct 2019 22:40:33 -0700
+Subject: [PATCH] Add lookup function for protocol defs
+
+---
+ pyo3-derive-backend/src/defs.rs | 40 ++++++++++++++++++++++--------
+ pyo3-derive-backend/src/pyproto.rs | 15 +++--------
+ 2 files changed, 33 insertions(+), 22 deletions(-)
+
+diff --git a/pyo3-derive-backend/src/defs.rs b/pyo3-derive-backend/src/defs.rs
+index 04c1fa3b0..52024c12b 100644
+--- a/pyo3-derive-backend/src/defs.rs
++++ b/pyo3-derive-backend/src/defs.rs
+@@ -7,12 +7,22 @@ pub struct Proto {
+ pub py_methods: &'static [PyMethod],
+ }
+
++impl Proto {
++ pub fn protocol_trait(&self) -> String {
++ format!("Py{}Protocol", self.name)
++ }
++
++ pub fn _impl_trait(&self) -> String {
++ format!("Py{}ProtocolImpl", self.name)
++ }
++}
++
+ pub struct PyMethod {
+ pub name: &'static str,
+ pub proto: &'static str,
+ }
+
+-pub const OBJECT: Proto = Proto {
++const OBJECT: Proto = Proto {
+ name: "Object",
+ methods: &[
+ MethodProto::Binary {
+@@ -88,7 +98,7 @@ pub const OBJECT: Proto = Proto {
+ ],
+ };
+
+-pub const ASYNC: Proto = Proto {
++const ASYNC: Proto = Proto {
+ name: "Async",
+ methods: &[
+ MethodProto::Unary {
+@@ -131,7 +141,7 @@ pub const ASYNC: Proto = Proto {
+ ],
+ };
+
+-pub const BUFFER: Proto = Proto {
++const BUFFER: Proto = Proto {
+ name: "Buffer",
+ methods: &[
+ MethodProto::Unary {
+@@ -148,7 +158,7 @@ pub const BUFFER: Proto = Proto {
+ py_methods: &[],
+ };
+
+-pub const CONTEXT: Proto = Proto {
++const CONTEXT: Proto = Proto {
+ name: "Context",
+ methods: &[
+ MethodProto::Unary {
+@@ -176,7 +186,7 @@ pub const CONTEXT: Proto = Proto {
+ ],
+ };
+
+-pub const GC: Proto = Proto {
++const GC: Proto = Proto {
+ name: "GC",
+ methods: &[
+ MethodProto::Free {
+@@ -191,7 +201,7 @@ pub const GC: Proto = Proto {
+ py_methods: &[],
+ };
+
+-pub const DESCR: Proto = Proto {
++const DESCR: Proto = Proto {
+ name: "Descriptor",
+ methods: &[
+ MethodProto::Ternary {
+@@ -233,7 +243,7 @@ pub const DESCR: Proto = Proto {
+ ],
+ };
+
+-pub const ITER: Proto = Proto {
++const ITER: Proto = Proto {
+ name: "Iter",
+ py_methods: &[],
+ methods: &[
+@@ -250,7 +260,7 @@ pub const ITER: Proto = Proto {
+ ],
+ };
+
+-pub const MAPPING: Proto = Proto {
++const MAPPING: Proto = Proto {
+ name: "Mapping",
+ methods: &[
+ MethodProto::Unary {
+@@ -310,7 +320,7 @@ pub const MAPPING: Proto = Proto {
+ ],
+ };
+
+-pub const SEQ: Proto = Proto {
++const SEQ: Proto = Proto {
+ name: "Sequence",
+ methods: &[
+ MethodProto::Unary {
+@@ -371,7 +381,7 @@ pub const SEQ: Proto = Proto {
+ py_methods: &[],
+ };
+
+-pub const NUM: Proto = Proto {
++const NUM: Proto = Proto {
+ name: "Number",
+ methods: &[
+ MethodProto::BinaryS {
+@@ -750,3 +760,13 @@ pub const NUM: Proto = Proto {
+ },
+ ],
+ };
++
++const PROTOCOLS: &[Proto] = &[
++ OBJECT, ASYNC, MAPPING, ITER, CONTEXT, SEQ, NUM, DESCR, BUFFER, GC,
++];
++
++pub fn find_protocol(protocol_trait: &str) -> Option<&'static Proto> {
++ PROTOCOLS
++ .iter()
++ .find(|p| p.protocol_trait() == protocol_trait)
++}
+diff --git a/pyo3-derive-backend/src/pyproto.rs b/pyo3-derive-backend/src/pyproto.rs
+index c0921bcbb..41f1deaf9 100644
+--- a/pyo3-derive-backend/src/pyproto.rs
++++ b/pyo3-derive-backend/src/pyproto.rs
+@@ -12,18 +12,9 @@ use quote::ToTokens;
+ pub fn build_py_proto(ast: &mut syn::ItemImpl) -> syn::Result<TokenStream> {
+ if let Some((_, ref mut path, _)) = ast.trait_ {
+ let proto = if let Some(ref mut segment) = path.segments.last() {
+- match segment.ident.to_string().as_str() {
+- "PyObjectProtocol" => &defs::OBJECT,
+- "PyAsyncProtocol" => &defs::ASYNC,
+- "PyMappingProtocol" => &defs::MAPPING,
+- "PyIterProtocol" => &defs::ITER,
+- "PyContextProtocol" => &defs::CONTEXT,
+- "PySequenceProtocol" => &defs::SEQ,
+- "PyNumberProtocol" => &defs::NUM,
+- "PyDescrProtocol" => &defs::DESCR,
+- "PyBufferProtocol" => &defs::BUFFER,
+- "PyGCProtocol" => &defs::GC,
+- _ => {
++ match defs::find_protocol(segment.ident.to_string().as_str()) {
++ Some(p) => p,
++ None => {
+ return Err(syn::Error::new_spanned(
+ path,
+ "#[pyproto] can not be used with this block",
diff --git a/srcpkgs/anki/files/pyo3-patches/0016-specialization-eb617c2ad89dad6be5cf454fe0012d9aba9e60b2.patch b/srcpkgs/anki/files/pyo3-patches/0016-specialization-eb617c2ad89dad6be5cf454fe0012d9aba9e60b2.patch
new file mode 100644
index 00000000000..615bd92790b
--- /dev/null
+++ b/srcpkgs/anki/files/pyo3-patches/0016-specialization-eb617c2ad89dad6be5cf454fe0012d9aba9e60b2.patch
@@ -0,0 +1,1387 @@
+From eb617c2ad89dad6be5cf454fe0012d9aba9e60b2 Mon Sep 17 00:00:00 2001
+From: Martin Donlon <github-martin@donlons.com>
+Date: Sun, 3 Nov 2019 18:06:54 -0800
+Subject: [PATCH] Proc macros now add the necessary default implementations
+
+---
+ .vscode/settings.json | 3 +-
+ pyo3-derive-backend/src/defs.rs | 137 ++++++++++++++++--
+ pyo3-derive-backend/src/func.rs | 37 +++++
+ pyo3-derive-backend/src/pyclass.rs | 34 ++++-
+ pyo3-derive-backend/src/pyproto.rs | 91 +++++++-----
+ src/buffer.rs | 5 +-
+ src/class/buffer.rs | 6 +
+ src/lib.rs | 4 +-
+ tests/test_arithmetics.rp | 12 +-
+ ...er_protocol.rp => test_buffer_protocol.rs} | 2 +-
+ tests/{test_bytes.rp => test_bytes.rs} | 0
+ tests/test_class_basics.rs | 17 +--
+ .../{test_class_new.rp => test_class_new.rs} | 0
+ ...compile_error.rp => test_compile_error.rs} | 0
+ tests/test_datetime.rp | 2 -
+ tests/{test_gc.rp => test_gc.rs} | 4 +-
+ ...getter_setter.rp => test_getter_setter.rs} | 0
+ tests/{test_sequence.rp => test_sequence.rs} | 2 +-
+ tests/{test_string.rp => test_string.rs} | 0
+ ...rguments.rp => test_variable_arguments.rs} | 0
+ tests/{test_various.rp => test_various.rs} | 3 +-
+ 21 files changed, 280 insertions(+), 79 deletions(-)
+ rename tests/{test_buffer_protocol.rp => test_buffer_protocol.rs} (98%)
+ rename tests/{test_bytes.rp => test_bytes.rs} (100%)
+ rename tests/{test_class_new.rp => test_class_new.rs} (100%)
+ rename tests/{test_compile_error.rp => test_compile_error.rs} (100%)
+ rename tests/{test_gc.rp => test_gc.rs} (98%)
+ rename tests/{test_getter_setter.rp => test_getter_setter.rs} (100%)
+ rename tests/{test_sequence.rp => test_sequence.rs} (99%)
+ rename tests/{test_string.rp => test_string.rs} (100%)
+ rename tests/{test_variable_arguments.rp => test_variable_arguments.rs} (100%)
+ rename tests/{test_various.rp => test_various.rs} (98%)
+
+diff --git a/.vscode/settings.json b/.vscode/settings.json
+index 2b5f84ecc..38768fd72 100644
+--- a/.vscode/settings.json
++++ b/.vscode/settings.json
+@@ -1,4 +1,5 @@
+ {
+ "rust.all_targets": false,
+- "editor.formatOnSave": true
++ "editor.formatOnSave": true,
++ "rust-analyzer.enableEnhancedTyping": false
+ }
+\ No newline at end of file
+diff --git a/pyo3-derive-backend/src/defs.rs b/pyo3-derive-backend/src/defs.rs
+index 52024c12b..06c1c6754 100644
+--- a/pyo3-derive-backend/src/defs.rs
++++ b/pyo3-derive-backend/src/defs.rs
+@@ -3,20 +3,12 @@ use crate::func::MethodProto;
+
+ pub struct Proto {
+ pub name: &'static str,
++ pub protocol_trait: &'static str,
++ pub impl_trait: &'static str,
+ pub methods: &'static [MethodProto],
+ pub py_methods: &'static [PyMethod],
+ }
+
+-impl Proto {
+- pub fn protocol_trait(&self) -> String {
+- format!("Py{}Protocol", self.name)
+- }
+-
+- pub fn _impl_trait(&self) -> String {
+- format!("Py{}ProtocolImpl", self.name)
+- }
+-}
+-
+ pub struct PyMethod {
+ pub name: &'static str,
+ pub proto: &'static str,
+@@ -24,12 +16,15 @@ pub struct PyMethod {
+
+ const OBJECT: Proto = Proto {
+ name: "Object",
++ protocol_trait: "pyo3::class::basic::PyObjectProtocol",
++ impl_trait: "pyo3::class::basic::PyObjectProtocolImpl",
+ methods: &[
+ MethodProto::Binary {
+ name: "__getattr__",
+ arg: "Name",
+ pyres: true,
+ proto: "pyo3::class::basic::PyObjectGetAttrProtocol",
++ default: "pyo3::class::basic::PyObjectGetAttrProtocol",
+ },
+ MethodProto::Ternary {
+ name: "__setattr__",
+@@ -37,49 +32,58 @@ const OBJECT: Proto = Proto {
+ arg2: "Value",
+ pyres: false,
+ proto: "pyo3::class::basic::PyObjectSetAttrProtocol",
++ default: "pyo3::class::basic::PyObjectSetAttrProtocol",
+ },
+ MethodProto::Binary {
+ name: "__delattr__",
+ arg: "Name",
+ pyres: true,
+ proto: "pyo3::class::basic::PyObjectDelAttrProtocol",
++ default: "pyo3::class::basic::PyObjectDelAttrProtocol",
+ },
+ MethodProto::Unary {
+ name: "__str__",
+ pyres: true,
+ proto: "pyo3::class::basic::PyObjectStrProtocol",
++ default: "pyo3::class::basic::PyObjectStrProtocol",
+ },
+ MethodProto::Unary {
+ name: "__repr__",
+ pyres: true,
+ proto: "pyo3::class::basic::PyObjectReprProtocol",
++ default: "pyo3::class::basic::PyObjectReprProtocol",
+ },
+ MethodProto::Binary {
+ name: "__format__",
+ arg: "Format",
+ pyres: true,
+ proto: "pyo3::class::basic::PyObjectFormatProtocol",
++ default: "pyo3::class::basic::PyObjectFormatProtocol",
+ },
+ MethodProto::Unary {
+ name: "__hash__",
+ pyres: false,
+ proto: "pyo3::class::basic::PyObjectHashProtocol",
++ default: "pyo3::class::basic::PyObjectHashProtocol",
+ },
+ MethodProto::Unary {
+ name: "__bytes__",
+ pyres: true,
+ proto: "pyo3::class::basic::PyObjectBytesProtocol",
++ default: "pyo3::class::basic::PyObjectBytesProtocol",
+ },
+ MethodProto::Unary {
+ name: "__bool__",
+ pyres: false,
+ proto: "pyo3::class::basic::PyObjectBoolProtocol",
++ default: "pyo3::class::basic::PyObjectBoolProtocol",
+ },
+ MethodProto::Binary {
+ name: "__richcmp__",
+ arg: "Other",
+ pyres: true,
+ proto: "pyo3::class::basic::PyObjectRichcmpProtocol",
++ default: "pyo3::class::basic::PyObjectRichcmpProtocol",
+ },
+ ],
+ py_methods: &[
+@@ -100,26 +104,32 @@ const OBJECT: Proto = Proto {
+
+ const ASYNC: Proto = Proto {
+ name: "Async",
++ protocol_trait: "pyo3::class::pyasync::PyAsyncProtocol",
++ impl_trait: "pyo3::class::pyasync::PyAsyncProtocolImpl",
+ methods: &[
+ MethodProto::Unary {
+ name: "__await__",
+ pyres: true,
+ proto: "pyo3::class::pyasync::PyAsyncAwaitProtocol",
++ default: "pyo3::class::pyasync::PyAsyncAwaitProtocol",
+ },
+ MethodProto::Unary {
+ name: "__aiter__",
+ pyres: true,
+ proto: "pyo3::class::pyasync::PyAsyncAiterProtocol",
++ default: "pyo3::class::pyasync::PyAsyncAiterProtocol",
+ },
+ MethodProto::Unary {
+ name: "__anext__",
+ pyres: true,
+ proto: "pyo3::class::pyasync::PyAsyncAnextProtocol",
++ default: "pyo3::class::pyasync::PyAsyncAnextProtocol",
+ },
+ MethodProto::Unary {
+ name: "__aenter__",
+ pyres: true,
+ proto: "pyo3::class::pyasync::PyAsyncAenterProtocol",
++ default: "pyo3::class::pyasync::PyAsyncAenterProtocol",
+ },
+ MethodProto::Quaternary {
+ name: "__aexit__",
+@@ -127,6 +137,7 @@ const ASYNC: Proto = Proto {
+ arg2: "ExcValue",
+ arg3: "Traceback",
+ proto: "pyo3::class::pyasync::PyAsyncAexitProtocol",
++ default: "pyo3::class::pyasync::PyAsyncAexitProtocol",
+ },
+ ],
+ py_methods: &[
+@@ -143,16 +154,20 @@ const ASYNC: Proto = Proto {
+
+ const BUFFER: Proto = Proto {
+ name: "Buffer",
++ protocol_trait: "pyo3::class::buffer::PyBufferProtocol",
++ impl_trait: "pyo3::class::buffer::PyBufferProtocolImpl",
+ methods: &[
+ MethodProto::Unary {
+ name: "bf_getbuffer",
+ pyres: false,
+ proto: "pyo3::class::buffer::PyBufferGetBufferProtocol",
++ default: "pyo3::class::buffer::PyBufferGetBufferProtocolImpl",
+ },
+ MethodProto::Unary {
+ name: "bf_releasebuffer",
+ pyres: false,
+ proto: "pyo3::class::buffer::PyBufferReleaseBufferProtocol",
++ default: "pyo3::class::buffer::PyBufferReleaseBufferProtocolImpl",
+ },
+ ],
+ py_methods: &[],
+@@ -160,11 +175,14 @@ const BUFFER: Proto = Proto {
+
+ const CONTEXT: Proto = Proto {
+ name: "Context",
++ protocol_trait: "pyo3::class::context::PyContextProtocol",
++ impl_trait: "pyo3::class::context::PyContextProtocolImpl",
+ methods: &[
+ MethodProto::Unary {
+ name: "__enter__",
+ pyres: true,
+ proto: "pyo3::class::context::PyContextEnterProtocol",
++ default: "pyo3::class::context::PyContextEnterProtocol",
+ },
+ MethodProto::Quaternary {
+ name: "__exit__",
+@@ -172,6 +190,7 @@ const CONTEXT: Proto = Proto {
+ arg2: "ExcValue",
+ arg3: "Traceback",
+ proto: "pyo3::class::context::PyContextExitProtocol",
++ default: "pyo3::class::context::PyContextExitProtocol",
+ },
+ ],
+ py_methods: &[
+@@ -188,14 +207,19 @@ const CONTEXT: Proto = Proto {
+
+ const GC: Proto = Proto {
+ name: "GC",
++ protocol_trait: "pyo3::class::gc::PyGCProtocol",
++ impl_trait: "pyo3::class::gc::PyGCProtocolImpl",
++
+ methods: &[
+ MethodProto::Free {
+ name: "__traverse__",
+ proto: "pyo3::class::gc::PyGCTraverseProtocol",
++ default: "pyo3::class::gc::PyGCTraverseProtocolImpl",
+ },
+ MethodProto::Free {
+ name: "__clear__",
+ proto: "pyo3::class::gc::PyGCClearProtocol",
++ default: "pyo3::class::gc::PyGCClearProtocolImpl",
+ },
+ ],
+ py_methods: &[],
+@@ -203,6 +227,9 @@ const GC: Proto = Proto {
+
+ const DESCR: Proto = Proto {
+ name: "Descriptor",
++ protocol_trait: "pyo3::class::descr::PyDescrProtocol",
++ impl_trait: "pyo3::class::descr::PyDescrProtocolImpl",
++
+ methods: &[
+ MethodProto::Ternary {
+ name: "__get__",
+@@ -210,6 +237,7 @@ const DESCR: Proto = Proto {
+ arg2: "Owner",
+ pyres: true,
+ proto: "pyo3::class::descr::PyDescrGetProtocol",
++ default: "pyo3::class::descr::PyDescrGetProtocol",
+ },
+ MethodProto::Ternary {
+ name: "__set__",
+@@ -217,18 +245,21 @@ const DESCR: Proto = Proto {
+ arg2: "Value",
+ pyres: true,
+ proto: "pyo3::class::descr::PyDescrSetProtocol",
++ default: "pyo3::class::descr::PyDescrSetProtocol",
+ },
+ MethodProto::Binary {
+ name: "__det__",
+ arg: "Inst",
+ pyres: false,
+ proto: "pyo3::class::descr::PyDescrDelProtocol",
++ default: "pyo3::class::descr::PyDescrDelProtocol",
+ },
+ MethodProto::Binary {
+ name: "__set_name__",
+ arg: "Inst",
+ pyres: false,
+ proto: "pyo3::class::descr::PyDescrSetNameProtocol",
++ default: "pyo3::class::descr::PyDescrSetNameProtocol",
+ },
+ ],
+ py_methods: &[
+@@ -245,34 +276,44 @@ const DESCR: Proto = Proto {
+
+ const ITER: Proto = Proto {
+ name: "Iter",
++ protocol_trait: "pyo3::class::iter::PyIterProtocol",
++ impl_trait: "pyo3::class::iter::PyIterProtocolImpl",
++
+ py_methods: &[],
+ methods: &[
+ MethodProto::Unary {
+ name: "__iter__",
+ pyres: true,
+ proto: "pyo3::class::iter::PyIterIterProtocol",
++ default: "pyo3::class::iter::PyIterIterProtocol",
+ },
+ MethodProto::Unary {
+ name: "__next__",
+ pyres: true,
+ proto: "pyo3::class::iter::PyIterNextProtocol",
++ default: "pyo3::class::iter::PyIterNextProtocol",
+ },
+ ],
+ };
+
+ const MAPPING: Proto = Proto {
+ name: "Mapping",
++ protocol_trait: "pyo3::class::mapping::PyMappingProtocol",
++ impl_trait: "pyo3::class::mapping::PyMappingProtocolImpl",
++
+ methods: &[
+ MethodProto::Unary {
+ name: "__len__",
+ pyres: false,
+ proto: "pyo3::class::mapping::PyMappingLenProtocol",
++ default: "pyo3::class::mapping::PyMappingLenProtocol",
+ },
+ MethodProto::Binary {
+ name: "__getitem__",
+ arg: "Key",
+ pyres: true,
+ proto: "pyo3::class::mapping::PyMappingGetItemProtocol",
++ default: "pyo3::class::mapping::PyMappingGetItemProtocol",
+ },
+ MethodProto::Ternary {
+ name: "__setitem__",
+@@ -280,28 +321,33 @@ const MAPPING: Proto = Proto {
+ arg2: "Value",
+ pyres: false,
+ proto: "pyo3::class::mapping::PyMappingSetItemProtocol",
++ default: "pyo3::class::mapping::PyMappingSetItemProtocol",
+ },
+ MethodProto::Binary {
+ name: "__delitem__",
+ arg: "Key",
+ pyres: false,
+ proto: "pyo3::class::mapping::PyMappingDelItemProtocol",
++ default: "pyo3::class::mapping::PyMappingDelItemProtocol",
+ },
+ MethodProto::Binary {
+ name: "__contains__",
+ arg: "Value",
+ pyres: false,
+ proto: "pyo3::class::mapping::PyMappingContainsProtocol",
++ default: "pyo3::class::mapping::PyMappingContainsProtocol",
+ },
+ MethodProto::Unary {
+ name: "__reversed__",
+ pyres: true,
+ proto: "pyo3::class::mapping::PyMappingReversedProtocol",
++ default: "pyo3::class::mapping::PyMappingReversedProtocol",
+ },
+ MethodProto::Unary {
+ name: "__iter__",
+ pyres: true,
+ proto: "pyo3::class::mapping::PyMappingIterProtocol",
++ default: "pyo3::class::mapping::PyMappingIterProtocol",
+ },
+ ],
+ py_methods: &[
+@@ -322,17 +368,22 @@ const MAPPING: Proto = Proto {
+
+ const SEQ: Proto = Proto {
+ name: "Sequence",
++ protocol_trait: "pyo3::class::sequence::PySequenceProtocol",
++ impl_trait: "pyo3::class::sequence::PySequenceProtocolImpl",
++
+ methods: &[
+ MethodProto::Unary {
+ name: "__len__",
+ pyres: false,
+ proto: "pyo3::class::sequence::PySequenceLenProtocol",
++ default: "pyo3::class::sequence::PySequenceLenProtocolImpl",
+ },
+ MethodProto::Binary {
+ name: "__getitem__",
+ arg: "Index",
+ pyres: true,
+ proto: "pyo3::class::sequence::PySequenceGetItemProtocol",
++ default: "pyo3::class::sequence::PySequenceGetItemProtocolImpl",
+ },
+ MethodProto::Ternary {
+ name: "__setitem__",
+@@ -340,42 +391,49 @@ const SEQ: Proto = Proto {
+ arg2: "Value",
+ pyres: false,
+ proto: "pyo3::class::sequence::PySequenceSetItemProtocol",
++ default: "pyo3::class::sequence::PySequenceSetItemProtocolImpl",
+ },
+ MethodProto::Binary {
+ name: "__delitem__",
+ arg: "Index",
+ pyres: false,
+ proto: "pyo3::class::sequence::PySequenceDelItemProtocol",
++ default: "pyo3::class::sequence::PySequenceDelItemProtocolImpl",
+ },
+ MethodProto::Binary {
+ name: "__contains__",
+ arg: "Item",
+ pyres: false,
+ proto: "pyo3::class::sequence::PySequenceContainsProtocol",
++ default: "pyo3::class::sequence::PySequenceContainsProtocolImpl",
+ },
+ MethodProto::Binary {
+ name: "__concat__",
+ arg: "Other",
+ pyres: true,
+ proto: "pyo3::class::sequence::PySequenceConcatProtocol",
++ default: "pyo3::class::sequence::PySequenceConcatProtocolImpl",
+ },
+ MethodProto::Binary {
+ name: "__repeat__",
+ arg: "Index",
+ pyres: true,
+ proto: "pyo3::class::sequence::PySequenceRepeatProtocol",
++ default: "pyo3::class::sequence::PySequenceRepeatProtocolImpl",
+ },
+ MethodProto::Binary {
+ name: "__inplace_concat__",
+ arg: "Other",
+ pyres: true,
+ proto: "pyo3::class::sequence::PySequenceInplaceConcatProtocol",
++ default: "pyo3::class::sequence::PySequenceInplaceConcatProtocolImpl",
+ },
+ MethodProto::Binary {
+ name: "__inplace_repeat__",
+ arg: "Index",
+ pyres: true,
+ proto: "pyo3::class::sequence::PySequenceInplaceRepeatProtocol",
++ default: "pyo3::class::sequence::PySequenceInplaceRepeatProtocolImpl",
+ },
+ ],
+ py_methods: &[],
+@@ -383,6 +441,9 @@ const SEQ: Proto = Proto {
+
+ const NUM: Proto = Proto {
+ name: "Number",
++ protocol_trait: "pyo3::class::number::PyNumberProtocol",
++ impl_trait: "pyo3::class::number::PyNumberProtocolImpl",
++
+ methods: &[
+ MethodProto::BinaryS {
+ name: "__add__",
+@@ -390,6 +451,7 @@ const NUM: Proto = Proto {
+ arg2: "Right",
+ pyres: true,
+ proto: "pyo3::class::number::PyNumberAddProtocol",
++ default: "pyo3::class::number::PyNumberAddProtocol",
+ },
+ MethodProto::BinaryS {
+ name: "__sub__",
+@@ -397,6 +459,7 @@ const NUM: Proto = Proto {
+ arg2: "Right",
+ pyres: true,
+ proto: "pyo3::class::number::PyNumberSubProtocol",
++ default: "pyo3::class::number::PyNumberSubProtocol",
+ },
+ MethodProto::BinaryS {
+ name: "__mul__",
+@@ -404,6 +467,7 @@ const NUM: Proto = Proto {
+ arg2: "Right",
+ pyres: true,
+ proto: "pyo3::class::number::PyNumberMulProtocol",
++ default: "pyo3::class::number::PyNumberMulProtocol",
+ },
+ MethodProto::BinaryS {
+ name: "__matmul__",
+@@ -411,6 +475,7 @@ const NUM: Proto = Proto {
+ arg2: "Right",
+ pyres: true,
+ proto: "pyo3::class::number::PyNumberMatmulProtocol",
++ default: "pyo3::class::number::PyNumberMatmulProtocol",
+ },
+ MethodProto::BinaryS {
+ name: "__truediv__",
+@@ -418,6 +483,7 @@ const NUM: Proto = Proto {
+ arg2: "Right",
+ pyres: true,
+ proto: "pyo3::class::number::PyNumberTruedivProtocol",
++ default: "pyo3::class::number::PyNumberTruedivProtocol",
+ },
+ MethodProto::BinaryS {
+ name: "__floordiv__",
+@@ -425,6 +491,7 @@ const NUM: Proto = Proto {
+ arg2: "Right",
+ pyres: true,
+ proto: "pyo3::class::number::PyNumberFloordivProtocol",
++ default: "pyo3::class::number::PyNumberFloordivProtocol",
+ },
+ MethodProto::BinaryS {
+ name: "__mod__",
+@@ -432,6 +499,7 @@ const NUM: Proto = Proto {
+ arg2: "Right",
+ pyres: true,
+ proto: "pyo3::class::number::PyNumberModProtocol",
++ default: "pyo3::class::number::PyNumberModProtocol",
+ },
+ MethodProto::BinaryS {
+ name: "__divmod__",
+@@ -439,6 +507,7 @@ const NUM: Proto = Proto {
+ arg2: "Right",
+ pyres: true,
+ proto: "pyo3::class::number::PyNumberDivmodProtocol",
++ default: "pyo3::class::number::PyNumberDivmodProtocol",
+ },
+ MethodProto::TernaryS {
+ name: "__pow__",
+@@ -447,6 +516,7 @@ const NUM: Proto = Proto {
+ arg3: "Modulo",
+ pyres: true,
+ proto: "pyo3::class::number::PyNumberPowProtocol",
++ default: "pyo3::class::number::PyNumberPowProtocol",
+ },
+ MethodProto::BinaryS {
+ name: "__lshift__",
+@@ -454,6 +524,7 @@ const NUM: Proto = Proto {
+ arg2: "Right",
+ pyres: true,
+ proto: "pyo3::class::number::PyNumberLShiftProtocol",
++ default: "pyo3::class::number::PyNumberLShiftProtocol",
+ },
+ MethodProto::BinaryS {
+ name: "__rshift__",
+@@ -461,6 +532,7 @@ const NUM: Proto = Proto {
+ arg2: "Right",
+ pyres: true,
+ proto: "pyo3::class::number::PyNumberRShiftProtocol",
++ default: "pyo3::class::number::PyNumberRShiftProtocol",
+ },
+ MethodProto::BinaryS {
+ name: "__and__",
+@@ -468,6 +540,7 @@ const NUM: Proto = Proto {
+ arg2: "Right",
+ pyres: true,
+ proto: "pyo3::class::number::PyNumberAndProtocol",
++ default: "pyo3::class::number::PyNumberAndProtocol",
+ },
+ MethodProto::BinaryS {
+ name: "__xor__",
+@@ -475,6 +548,7 @@ const NUM: Proto = Proto {
+ arg2: "Right",
+ pyres: true,
+ proto: "pyo3::class::number::PyNumberXorProtocol",
++ default: "pyo3::class::number::PyNumberXorProtocol",
+ },
+ MethodProto::BinaryS {
+ name: "__or__",
+@@ -482,54 +556,63 @@ const NUM: Proto = Proto {
+ arg2: "Right",
+ pyres: true,
+ proto: "pyo3::class::number::PyNumberOrProtocol",
++ default: "pyo3::class::number::PyNumberOrProtocol",
+ },
+ MethodProto::Binary {
+ name: "__radd__",
+ arg: "Other",
+ pyres: true,
+ proto: "pyo3::class::number::PyNumberRAddProtocol",
++ default: "pyo3::class::number::PyNumberRAddProtocol",
+ },
+ MethodProto::Binary {
+ name: "__rsub__",
+ arg: "Other",
+ pyres: true,
+ proto: "pyo3::class::number::PyNumberRSubProtocol",
++ default: "pyo3::class::number::PyNumberRSubProtocol",
+ },
+ MethodProto::Binary {
+ name: "__rmul__",
+ arg: "Other",
+ pyres: true,
+ proto: "pyo3::class::number::PyNumberRMulProtocol",
++ default: "pyo3::class::number::PyNumberRMulProtocol",
+ },
+ MethodProto::Binary {
+ name: "__rmatmul__",
+ arg: "Other",
+ pyres: true,
+ proto: "pyo3::class::number::PyNumberRMatmulProtocol",
++ default: "pyo3::class::number::PyNumberRMatmulProtocol",
+ },
+ MethodProto::Binary {
+ name: "__rtruediv__",
+ arg: "Other",
+ pyres: true,
+ proto: "pyo3::class::number::PyNumberRTruedivProtocol",
++ default: "pyo3::class::number::PyNumberRTruedivProtocol",
+ },
+ MethodProto::Binary {
+ name: "__rfloordiv__",
+ arg: "Other",
+ pyres: true,
+ proto: "pyo3::class::number::PyNumberRFloordivProtocol",
++ default: "pyo3::class::number::PyNumberRFloordivProtocol",
+ },
+ MethodProto::Binary {
+ name: "__rmod__",
+ arg: "Other",
+ pyres: true,
+ proto: "pyo3::class::number::PyNumberRModProtocol",
++ default: "pyo3::class::number::PyNumberRModProtocol",
+ },
+ MethodProto::Binary {
+ name: "__rdivmod__",
+ arg: "Other",
+ pyres: true,
+ proto: "pyo3::class::number::PyNumberRDivmodProtocol",
++ default: "pyo3::class::number::PyNumberRDivmodProtocol",
+ },
+ MethodProto::Ternary {
+ name: "__rpow__",
+@@ -537,78 +620,91 @@ const NUM: Proto = Proto {
+ arg2: "Modulo",
+ pyres: true,
+ proto: "pyo3::class::number::PyNumberRPowProtocol",
++ default: "pyo3::class::number::PyNumberRPowProtocol",
+ },
+ MethodProto::Binary {
+ name: "__rlshift__",
+ arg: "Other",
+ pyres: true,
+ proto: "pyo3::class::number::PyNumberRLShiftProtocol",
++ default: "pyo3::class::number::PyNumberRLShiftProtocol",
+ },
+ MethodProto::Binary {
+ name: "__rrshift__",
+ arg: "Other",
+ pyres: true,
+ proto: "pyo3::class::number::PyNumberRRShiftProtocol",
++ default: "pyo3::class::number::PyNumberRRShiftProtocol",
+ },
+ MethodProto::Binary {
+ name: "__rand__",
+ arg: "Other",
+ pyres: true,
+ proto: "pyo3::class::number::PyNumberRAndProtocol",
++ default: "pyo3::class::number::PyNumberRAndProtocol",
+ },
+ MethodProto::Binary {
+ name: "__rxor__",
+ arg: "Other",
+ pyres: true,
+ proto: "pyo3::class::number::PyNumberRXorProtocol",
++ default: "pyo3::class::number::PyNumberRXorProtocol",
+ },
+ MethodProto::Binary {
+ name: "__ror__",
+ arg: "Other",
+ pyres: true,
+ proto: "pyo3::class::number::PyNumberROrProtocol",
++ default: "pyo3::class::number::PyNumberROrProtocol",
+ },
+ MethodProto::Binary {
+ name: "__iadd__",
+ arg: "Other",
+ pyres: false,
+ proto: "pyo3::class::number::PyNumberIAddProtocol",
++ default: "pyo3::class::number::PyNumberIAddProtocol",
+ },
+ MethodProto::Binary {
+ name: "__isub__",
+ arg: "Other",
+ pyres: false,
+ proto: "pyo3::class::number::PyNumberISubProtocol",
++ default: "pyo3::class::number::PyNumberISubProtocol",
+ },
+ MethodProto::Binary {
+ name: "__imul__",
+ arg: "Other",
+ pyres: false,
+ proto: "pyo3::class::number::PyNumberIMulProtocol",
++ default: "pyo3::class::number::PyNumberIMulProtocol",
+ },
+ MethodProto::Binary {
+ name: "__imatmul__",
+ arg: "Other",
+ pyres: false,
+ proto: "pyo3::class::number::PyNumberIMatmulProtocol",
++ default: "pyo3::class::number::PyNumberIMatmulProtocol",
+ },
+ MethodProto::Binary {
+ name: "__itruediv__",
+ arg: "Other",
+ pyres: false,
+ proto: "pyo3::class::number::PyNumberITruedivProtocol",
++ default: "pyo3::class::number::PyNumberITruedivProtocol",
+ },
+ MethodProto::Binary {
+ name: "__ifloordiv__",
+ arg: "Other",
+ pyres: false,
+ proto: "pyo3::class::number::PyNumberIFloordivProtocol",
++ default: "pyo3::class::number::PyNumberIFloordivProtocol",
+ },
+ MethodProto::Binary {
+ name: "__imod__",
+ arg: "Other",
+ pyres: false,
+ proto: "pyo3::class::number::PyNumberIModProtocol",
++ default: "pyo3::class::number::PyNumberIModProtocol",
+ },
+ MethodProto::Ternary {
+ name: "__ipow__",
+@@ -616,81 +712,96 @@ const NUM: Proto = Proto {
+ arg2: "Modulo",
+ pyres: false,
+ proto: "pyo3::class::number::PyNumberIPowProtocol",
++ default: "pyo3::class::number::PyNumberIPowProtocol",
+ },
+ MethodProto::Binary {
+ name: "__ilshift__",
+ arg: "Other",
+ pyres: false,
+ proto: "pyo3::class::number::PyNumberILShiftProtocol",
++ default: "pyo3::class::number::PyNumberILShiftProtocol",
+ },
+ MethodProto::Binary {
+ name: "__irshift__",
+ arg: "Other",
+ pyres: false,
+ proto: "pyo3::class::number::PyNumberIRShiftProtocol",
++ default: "pyo3::class::number::PyNumberIRShiftProtocol",
+ },
+ MethodProto::Binary {
+ name: "__iand__",
+ arg: "Other",
+ pyres: false,
+ proto: "pyo3::class::number::PyNumberIAndProtocol",
++ default: "pyo3::class::number::PyNumberIAndProtocol",
+ },
+ MethodProto::Binary {
+ name: "__ixor__",
+ arg: "Other",
+ pyres: false,
+ proto: "pyo3::class::number::PyNumberIXorProtocol",
++ default: "pyo3::class::number::PyNumberIXorProtocol",
+ },
+ MethodProto::Binary {
+ name: "__ior__",
+ arg: "Other",
+ pyres: false,
+ proto: "pyo3::class::number::PyNumberIOrProtocol",
++ default: "pyo3::class::number::PyNumberIOrProtocol",
+ },
+ MethodProto::Unary {
+ name: "__neg__",
+ pyres: true,
+ proto: "pyo3::class::number::PyNumberNegProtocol",
++ default: "pyo3::class::number::PyNumberNegProtocol",
+ },
+ MethodProto::Unary {
+ name: "__pos__",
+ pyres: true,
+ proto: "pyo3::class::number::PyNumberPosProtocol",
++ default: "pyo3::class::number::PyNumberPosProtocol",
+ },
+ MethodProto::Unary {
+ name: "__abs__",
+ pyres: true,
+ proto: "pyo3::class::number::PyNumberAbsProtocol",
++ default: "pyo3::class::number::PyNumberAbsProtocol",
+ },
+ MethodProto::Unary {
+ name: "__invert__",
+ pyres: true,
+ proto: "pyo3::class::number::PyNumberInvertProtocol",
++ default: "pyo3::class::number::PyNumberInvertProtocol",
+ },
+ MethodProto::Unary {
+ name: "__complex__",
+ pyres: true,
+ proto: "pyo3::class::number::PyNumberComplexProtocol",
++ default: "pyo3::class::number::PyNumberComplexProtocol",
+ },
+ MethodProto::Unary {
+ name: "__int__",
+ pyres: true,
+ proto: "pyo3::class::number::PyNumberIntProtocol",
++ default: "pyo3::class::number::PyNumberIntProtocol",
+ },
+ MethodProto::Unary {
+ name: "__float__",
+ pyres: true,
+ proto: "pyo3::class::number::PyNumberFloatProtocol",
++ default: "pyo3::class::number::PyNumberFloatProtocol",
+ },
+ MethodProto::Unary {
+ name: "__round__",
+ pyres: true,
+ proto: "pyo3::class::number::PyNumberRoundProtocol",
++ default: "pyo3::class::number::PyNumberRoundProtocol",
+ },
+ MethodProto::Unary {
+ name: "__index__",
+ pyres: true,
+ proto: "pyo3::class::number::PyNumberIndexProtocol",
++ default: "pyo3::class::number::PyNumberIndexProtocol",
+ },
+ ],
+ py_methods: &[
+@@ -765,8 +876,12 @@ const PROTOCOLS: &[Proto] = &[
+ OBJECT, ASYNC, MAPPING, ITER, CONTEXT, SEQ, NUM, DESCR, BUFFER, GC,
+ ];
+
++pub fn all_protocols() -> &'static [Proto] {
++ PROTOCOLS
++}
++
+ pub fn find_protocol(protocol_trait: &str) -> Option<&'static Proto> {
+ PROTOCOLS
+ .iter()
+- .find(|p| p.protocol_trait() == protocol_trait)
++ .find(|p| p.protocol_trait.ends_with(protocol_trait))
+ }
+diff --git a/pyo3-derive-backend/src/func.rs b/pyo3-derive-backend/src/func.rs
+index 2b7f69aca..ce06716f4 100644
+--- a/pyo3-derive-backend/src/func.rs
++++ b/pyo3-derive-backend/src/func.rs
+@@ -12,17 +12,20 @@ pub enum MethodProto {
+ Free {
+ name: &'static str,
+ proto: &'static str,
++ default: &'static str,
+ },
+ Unary {
+ name: &'static str,
+ pyres: bool,
+ proto: &'static str,
++ default: &'static str,
+ },
+ Binary {
+ name: &'static str,
+ arg: &'static str,
+ pyres: bool,
+ proto: &'static str,
++ default: &'static str,
+ },
+ BinaryS {
+ name: &'static str,
+@@ -30,6 +33,7 @@ pub enum MethodProto {
+ arg2: &'static str,
+ pyres: bool,
+ proto: &'static str,
++ default: &'static str,
+ },
+ Ternary {
+ name: &'static str,
+@@ -37,6 +41,7 @@ pub enum MethodProto {
+ arg2: &'static str,
+ pyres: bool,
+ proto: &'static str,
++ default: &'static str,
+ },
+ TernaryS {
+ name: &'static str,
+@@ -45,6 +50,7 @@ pub enum MethodProto {
+ arg3: &'static str,
+ pyres: bool,
+ proto: &'static str,
++ default: &'static str,
+ },
+ Quaternary {
+ name: &'static str,
+@@ -52,6 +58,7 @@ pub enum MethodProto {
+ arg2: &'static str,
+ arg3: &'static str,
+ proto: &'static str,
++ default: &'static str,
+ },
+ }
+
+@@ -69,6 +76,31 @@ impl PartialEq<str> for MethodProto {
+ }
+ }
+
++impl MethodProto {
++ pub fn get_proto(&self) -> &'static str {
++ match *self {
++ MethodProto::Free { proto: p, .. } => p,
++ MethodProto::Unary { proto: p, .. } => p,
++ MethodProto::Binary { proto: p, .. } => p,
++ MethodProto::BinaryS { proto: p, .. } => p,
++ MethodProto::Ternary { proto: p, .. } => p,
++ MethodProto::TernaryS { proto: p, .. } => p,
++ MethodProto::Quaternary { proto: p, .. } => p,
++ }
++ }
++ pub fn get_default(&self) -> &'static str {
++ match *self {
++ MethodProto::Free { default: d, .. } => d,
++ MethodProto::Unary { default: d, .. } => d,
++ MethodProto::Binary { default: d, .. } => d,
++ MethodProto::BinaryS { default: d, .. } => d,
++ MethodProto::Ternary { default: d, .. } => d,
++ MethodProto::TernaryS { default: d, .. } => d,
++ MethodProto::Quaternary { default: d, .. } => d,
++ }
++ }
++}
++
+ pub fn impl_method_proto(
+ cls: &syn::Type,
+ sig: &mut syn::Signature,
+@@ -119,6 +151,7 @@ pub fn impl_method_proto(
+ arg,
+ pyres,
+ proto,
++ default: _,
+ } => {
+ if sig.inputs.len() <= 1 {
+ println!("Not enough arguments for {}", name);
+@@ -164,6 +197,7 @@ pub fn impl_method_proto(
+ arg2,
+ pyres,
+ proto,
++ default: _,
+ } => {
+ if sig.inputs.len() <= 1 {
+ print_err(format!("Not enough arguments {}", name), quote!(sig));
+@@ -213,6 +247,7 @@ pub fn impl_method_proto(
+ arg2,
+ pyres,
+ proto,
++ default: _,
+ } => {
+ if sig.inputs.len() <= 2 {
+ print_err(format!("Not enough arguments {}", name), quote!(sig));
+@@ -266,6 +301,7 @@ pub fn impl_method_proto(
+ arg3,
+ pyres,
+ proto,
++ default: _,
+ } => {
+ if sig.inputs.len() <= 2 {
+ print_err(format!("Not enough arguments {}", name), quote!(sig));
+@@ -322,6 +358,7 @@ pub fn impl_method_proto(
+ arg2,
+ arg3,
+ proto,
++ default: _,
+ } => {
+ if sig.inputs.len() <= 3 {
+ print_err(format!("Not enough arguments {}", name), quote!(sig));
+diff --git a/pyo3-derive-backend/src/pyclass.rs b/pyo3-derive-backend/src/pyclass.rs
+index 3ac5d4cde..59a0ab29f 100644
+--- a/pyo3-derive-backend/src/pyclass.rs
++++ b/pyo3-derive-backend/src/pyclass.rs
+@@ -1,10 +1,10 @@
+ // Copyright (c) 2017-present PyO3 Project and Contributors
+-
++use crate::defs;
+ use crate::method::{FnArg, FnSpec, FnType};
+ use crate::pymethod::{impl_py_getter_def, impl_py_setter_def, impl_wrap_getter, impl_wrap_setter};
+ use crate::utils;
+ use proc_macro2::{Span, TokenStream};
+-use quote::quote;
++use quote::{format_ident, quote};
+ use syn::parse::{Parse, ParseStream};
+ use syn::punctuated::Punctuated;
+ use syn::{parse_quote, Expr, Token};
+@@ -326,6 +326,14 @@ fn impl_class(
+ extra
+ };
+
++ let extra = {
++ let default_impls = impl_default_protocols(&cls, &attr);
++ quote! {
++ #default_impls
++ #extra
++ }
++ };
++
+ // insert space for weak ref
+ let mut has_weakref = false;
+ let mut has_dict = false;
+@@ -414,6 +422,9 @@ fn impl_class(
+ }
+ }
+
++ //impl<T: pyo3::type_object::PyTypeInfo> pyo3::AsPyRefDispatch<T> for #cls {}
++ //impl pyo3::ManagedPyRefDispatch for #cls {}
++
+ #inventory_impl
+
+ #extra
+@@ -531,3 +542,22 @@ fn check_generics(class: &mut syn::ItemStruct) -> syn::Result<()> {
+ ))
+ }
+ }
++
++fn impl_default_protocols(cls: &syn::Ident, attr: &PyClassArgs) -> TokenStream {
++ let impls: Vec<TokenStream> = defs::all_protocols()
++ .iter()
++ .filter_map(|proto| {
++ if attr
++ .protocols
++ .iter()
++ .any(|x| proto.protocol_trait.ends_with(&x.to_string()))
++ {
++ None
++ } else {
++ let impl_trait: syn::Path = syn::parse_str(proto.impl_trait).unwrap();
++ Some(quote! { impl #impl_trait for #cls {} })
++ }
++ })
++ .collect();
++ quote! { #(#impls)* }
++}
+diff --git a/pyo3-derive-backend/src/pyproto.rs b/pyo3-derive-backend/src/pyproto.rs
+index 41f1deaf9..a73232e1f 100644
+--- a/pyo3-derive-backend/src/pyproto.rs
++++ b/pyo3-derive-backend/src/pyproto.rs
+@@ -1,7 +1,7 @@
+ // Copyright (c) 2017-present PyO3 Project and Contributors
+
+ use crate::defs;
+-use crate::func::impl_method_proto;
++use crate::func::{impl_method_proto, MethodProto};
+ use crate::method::FnSpec;
+ use crate::pymethod;
+ use proc_macro2::Span;
+@@ -53,49 +53,70 @@ fn impl_proto_impl(
+ let mut tokens = TokenStream::new();
+ let mut py_methods = Vec::new();
+
++ let mut unimpl_methods: Vec<&MethodProto> = proto.methods.iter().collect();
++ let mut unimpl_py_methods: Vec<&defs::PyMethod> = proto.py_methods.iter().collect();
++
+ for iimpl in impls.iter_mut() {
+ if let syn::ImplItem::Method(ref mut met) = iimpl {
+- for m in proto.methods {
+- if m == met.sig.ident.to_string().as_str() {
+- impl_method_proto(ty, &mut met.sig, m).to_tokens(&mut tokens);
+- }
+- }
+- for m in proto.py_methods {
+- let ident = met.sig.ident.clone();
+- if m.name == ident.to_string().as_str() {
+- let name = syn::Ident::new(m.name, Span::call_site());
+- let proto: syn::Path = syn::parse_str(m.proto).unwrap();
+-
+- let fn_spec = match FnSpec::parse(&ident, &met.sig, &mut met.attrs) {
+- Ok(fn_spec) => fn_spec,
+- Err(err) => return err.to_compile_error(),
+- };
+- let meth = pymethod::impl_proto_wrap(ty, &ident, &fn_spec);
+-
+- py_methods.push(quote! {
+- impl #proto for #ty
+- {
+- #[inline]
+- fn #name() -> Option<pyo3::class::methods::PyMethodDef> {
+- #meth
+-
+- Some(pyo3::class::PyMethodDef {
+- ml_name: stringify!(#name),
+- ml_meth: pyo3::class::PyMethodType::PyCFunctionWithKeywords(__wrap),
+- ml_flags: pyo3::ffi::METH_VARARGS | pyo3::ffi::METH_KEYWORDS,
+- ml_doc: ""
+- })
+- }
++ let method_name = met.sig.ident.to_string();
++ // Find the method in unimpl_methods, remove it and implement it
++ unimpl_methods
++ .iter()
++ .position(|m| *m == method_name.as_str())
++ .map(|idx| {
++ let method = unimpl_methods.swap_remove(idx);
++ impl_method_proto(ty, &mut met.sig, method).to_tokens(&mut tokens);
++ });
++
++ // MJDFIXME - undo this change
++ let py_method_name = &met.sig.ident;
++ let method = unimpl_py_methods
++ .iter()
++ .position(|m| m.name == py_method_name.to_string().as_str())
++ .map(|idx| unimpl_py_methods.swap_remove(idx));
++
++ if let Some(m) = method {
++ let name = syn::Ident::new(m.name, Span::call_site());
++ let proto: syn::Path = syn::parse_str(m.proto).unwrap();
++
++ let fn_spec = match FnSpec::parse(&py_method_name, &met.sig, &mut met.attrs) {
++ Ok(fn_spec) => fn_spec,
++ Err(err) => return err.to_compile_error(),
++ };
++ let meth = pymethod::impl_proto_wrap(ty, &py_method_name, &fn_spec);
++
++ py_methods.push(quote! {
++ impl #proto for #ty
++ {
++ #[inline]
++ fn #name() -> Option<pyo3::class::methods::PyMethodDef> {
++ #meth
++
++ Some(pyo3::class::PyMethodDef {
++ ml_name: stringify!(#name),
++ ml_meth: pyo3::class::PyMethodType::PyCFunctionWithKeywords(__wrap),
++ ml_flags: pyo3::ffi::METH_VARARGS | pyo3::ffi::METH_KEYWORDS,
++ ml_doc: ""
++ })
+ }
+- });
+- }
+- }
++ }
++ });
++ };
+ }
+ }
+
++ let default_impls: Vec<_> = unimpl_methods
++ .iter()
++ .map(|m| {
++ let proto: syn::Path = syn::parse_str(m.get_default()).unwrap();
++ quote! { impl #proto for #ty {} }
++ })
++ .collect();
+ quote! {
+ #tokens
+
+ #(#py_methods)*
++
++ #(#default_impls)*
+ }
+ }
+diff --git a/src/buffer.rs b/src/buffer.rs
+index 91c317f6e..cdb305ad4 100644
+--- a/src/buffer.rs
++++ b/src/buffer.rs
+@@ -710,8 +710,9 @@ mod test {
+ fn test_array_buffer() {
+ let gil = Python::acquire_gil();
+ let py = gil.python();
+- let array = py
+- .import("array")
++ let arr = py.import("array");
++ println!("{:?}", arr);
++ let array = arr
+ .unwrap()
+ .call_method("array", ("f", (1.0, 1.5, 2.0, 2.5)), None)
+ .unwrap();
+diff --git a/src/class/buffer.rs b/src/class/buffer.rs
+index 32d1a25af..48ecc58ce 100644
+--- a/src/class/buffer.rs
++++ b/src/class/buffer.rs
+@@ -91,3 +91,9 @@ where
+ Some(wrap::<T>)
+ }
+ }
++
++pub trait PyBufferReleaseBufferProtocolImpl {
++ fn cb_bf_releasebuffer() -> Option<ffi::releasebufferproc> {
++ None
++ }
++}
+diff --git a/src/lib.rs b/src/lib.rs
+index 65fb611db..49e71ef6d 100755
+--- a/src/lib.rs
++++ b/src/lib.rs
+@@ -122,7 +122,9 @@ pub use crate::conversion::{
+ };
+ pub use crate::err::{PyDowncastError, PyErr, PyErrArguments, PyErrValue, PyResult};
+ pub use crate::gil::{init_once, GILGuard, GILPool};
+-pub use crate::instance::{AsPyRef, ManagedPyRef, Py, PyNativeType, PyRef, PyRefMut};
++pub use crate::instance::{
++ AsPyRef, AsPyRefDispatch, ManagedPyRef, ManagedPyRefDispatch, Py, PyNativeType, PyRef, PyRefMut,
++};
+ pub use crate::object::PyObject;
+ pub use crate::objectprotocol::ObjectProtocol;
+ pub use crate::python::{prepare_freethreaded_python, Python};
+diff --git a/tests/test_arithmetics.rp b/tests/test_arithmetics.rp
+index 77e8b64fe..42e378b5c 100644
+--- a/tests/test_arithmetics.rp
++++ b/tests/test_arithmetics.rp
+@@ -8,7 +8,7 @@ use pyo3::types::PyAny;
+
+ mod common;
+
+-#[pyclass]
++#[pyclass(protocols=[PyNumberProtocol])]
+ struct UnaryArithmetic {}
+
+ #[pyproto]
+@@ -42,7 +42,7 @@ fn unary_arithmetic() {
+ py_run!(py, c, "assert ~c == 'invert'");
+ }
+
+-#[pyclass]
++#[pyclass(protocols=[PyNumberProtocol, PyObjectProtocol])]
+ struct BinaryArithmetic {}
+
+ #[pyproto]
+@@ -52,7 +52,7 @@ impl PyObjectProtocol for BinaryArithmetic {
+ }
+ }
+
+-#[pyclass]
++#[pyclass(protocols=[PyNumberProtocol, PyObjectProtocol])]
+ struct InPlaceOperations {
+ value: u32,
+ }
+@@ -188,7 +188,7 @@ fn binary_arithmetic() {
+ py_run!(py, c, "assert 1 | c == '1 | BA'");
+ }
+
+-#[pyclass]
++#[pyclass(protocols=[PyNumberProtocol])]
+ struct RhsArithmetic {}
+
+ #[pyproto]
+@@ -210,7 +210,7 @@ fn rhs_arithmetic() {
+ // py_run!(py, c, "assert 1 + c == '1 + RA'");
+ }
+
+-#[pyclass]
++#[pyclass(protocols=[PyObjectProtocol])]
+ struct RichComparisons {}
+
+ #[pyproto]
+@@ -231,7 +231,7 @@ impl PyObjectProtocol for RichComparisons {
+ }
+ }
+
+-#[pyclass]
++#[pyclass(protocols=[PyObjectProtocol])]
+ struct RichComparisons2 {}
+
+ #[pyproto]
+diff --git a/tests/test_buffer_protocol.rp b/tests/test_buffer_protocol.rs
+similarity index 98%
+rename from tests/test_buffer_protocol.rp
+rename to tests/test_buffer_protocol.rs
+index 64aa4b944..ecbc6038d 100644
+--- a/tests/test_buffer_protocol.rp
++++ b/tests/test_buffer_protocol.rs
+@@ -7,7 +7,7 @@ use std::ffi::CStr;
+ use std::os::raw::{c_int, c_void};
+ use std::ptr;
+
+-#[pyclass]
++#[pyclass(protocols=[PyBufferProtocol])]
+ struct TestClass {
+ vec: Vec<u8>,
+ }
+diff --git a/tests/test_class_basics.rs b/tests/test_class_basics.rs
+index c8e1a42df..7b3ff6bc8 100644
+--- a/tests/test_class_basics.rs
++++ b/tests/test_class_basics.rs
+@@ -5,20 +5,9 @@ use pyo3::type_object::initialize_type;
+
+ mod common;
+
+-#[pyclass(protocols=[PySequenceProtocol])]
++#[pyclass]
+ struct EmptyClass {}
+
+-impl class::gc::PyGCProtocolImpl for EmptyClass {}
+-impl class::buffer::PyBufferProtocolImpl for EmptyClass {}
+-impl class::context::PyContextProtocolImpl for EmptyClass {}
+-impl class::iter::PyIterProtocolImpl for EmptyClass {}
+-impl class::descr::PyDescrProtocolImpl for EmptyClass {}
+-impl class::basic::PyObjectProtocolImpl for EmptyClass {}
+-impl class::number::PyNumberProtocolImpl for EmptyClass {}
+-impl class::mapping::PyMappingProtocolImpl for EmptyClass {}
+-impl class::sequence::PySequenceProtocolImpl for EmptyClass {}
+-impl class::pyasync::PyAsyncProtocolImpl for EmptyClass {}
+-
+ #[test]
+ fn empty_class() {
+ let gil = Python::acquire_gil();
+@@ -29,7 +18,7 @@ fn empty_class() {
+
+ py_assert!(py, typeobj, "typeobj.__name__ == 'EmptyClass'");
+ }
+-/*
++
+ /// Line1
+ ///Line2
+ /// Line3
+@@ -89,4 +78,4 @@ fn empty_class_in_module() {
+ initialize_type::<EmptyClassInModule>(py, Some("test_module.nested")).unwrap();
+ let module: String = ty.getattr("__module__").unwrap().extract().unwrap();
+ assert_eq!(module, "test_module.nested");
+-}*/
++}
+diff --git a/tests/test_class_new.rp b/tests/test_class_new.rs
+similarity index 100%
+rename from tests/test_class_new.rp
+rename to tests/test_class_new.rs
+diff --git a/tests/test_compile_error.rp b/tests/test_compile_error.rs
+similarity index 100%
+rename from tests/test_compile_error.rp
+rename to tests/test_compile_error.rs
+diff --git a/tests/test_datetime.rp b/tests/test_datetime.rp
+index 2819f92c4..a8de5f638 100644
+--- a/tests/test_datetime.rp
++++ b/tests/test_datetime.rp
+@@ -1,5 +1,3 @@
+-#![feature(concat_idents)]
+-
+ use pyo3::ffi::*;
+ use pyo3::prelude::*;
+ use pyo3::types::{IntoPyDict, PyAny};
+diff --git a/tests/test_gc.rp b/tests/test_gc.rs
+similarity index 98%
+rename from tests/test_gc.rp
+rename to tests/test_gc.rs
+index 26465438a..fa0c3d9cf 100644
+--- a/tests/test_gc.rp
++++ b/tests/test_gc.rs
+@@ -132,7 +132,7 @@ fn create_pointers_in_drop() {
+ }
+
+ #[allow(dead_code)]
+-#[pyclass]
++#[pyclass(protocols=[PyGCProtocol])]
+ struct GCIntegration {
+ self_ref: RefCell<PyObject>,
+ dropped: TestDropCall,
+@@ -177,7 +177,7 @@ fn gc_integration() {
+ assert!(drop_called.load(Ordering::Relaxed));
+ }
+
+-#[pyclass(gc)]
++#[pyclass(gc, protocols=[PyGCProtocol])]
+ struct GCIntegration2 {}
+
+ #[pyproto]
+diff --git a/tests/test_getter_setter.rp b/tests/test_getter_setter.rs
+similarity index 100%
+rename from tests/test_getter_setter.rp
+rename to tests/test_getter_setter.rs
+diff --git a/tests/test_sequence.rp b/tests/test_sequence.rs
+similarity index 99%
+rename from tests/test_sequence.rp
+rename to tests/test_sequence.rs
+index 6241f33ec..861ba6988 100644
+--- a/tests/test_sequence.rp
++++ b/tests/test_sequence.rs
+@@ -6,7 +6,7 @@ use pyo3::types::IntoPyDict;
+ use pyo3::types::PyAny;
+ use pyo3::types::PyList;
+
+-#[pyclass]
++#[pyclass(protocols=[PySequenceProtocol])]
+ struct ByteSequence {
+ elements: Vec<u8>,
+ }
+diff --git a/tests/test_variable_arguments.rp b/tests/test_variable_arguments.rs
+similarity index 100%
+rename from tests/test_variable_arguments.rp
+rename to tests/test_variable_arguments.rs
+diff --git a/tests/test_various.rp b/tests/test_various.rs
+similarity index 98%
+rename from tests/test_various.rp
+rename to tests/test_various.rs
+index 655101db2..101bdabb0 100644
+--- a/tests/test_various.rp
++++ b/tests/test_various.rs
+@@ -33,7 +33,8 @@ fn mut_ref_arg() {
+ let d = [("inst1", &inst1), ("inst2", &inst2)].into_py_dict(py);
+
+ py.run("inst1.set_other(inst2)", None, Some(d)).unwrap();
+- assert_eq!(inst2.as_ref(py).n, 100);
++ // MJDFIXME
++ //assert_eq!(inst2.as_ref(py).n, 100);
+ }
+
+ #[pyclass]
diff --git a/srcpkgs/anki/files/pyo3-patches/0017-specialization-c27d10fcd8932c3d83fe73b07412969cc42ff686.patch b/srcpkgs/anki/files/pyo3-patches/0017-specialization-c27d10fcd8932c3d83fe73b07412969cc42ff686.patch
new file mode 100644
index 00000000000..c9946de5852
--- /dev/null
+++ b/srcpkgs/anki/files/pyo3-patches/0017-specialization-c27d10fcd8932c3d83fe73b07412969cc42ff686.patch
@@ -0,0 +1,38 @@
+From c27d10fcd8932c3d83fe73b07412969cc42ff686 Mon Sep 17 00:00:00 2001
+From: Martin Donlon <github-martin@donlons.com>
+Date: Sun, 3 Nov 2019 19:29:06 -0800
+Subject: [PATCH] impl AsPyRefDispatch for every pyclass
+
+---
+ pyo3-derive-backend/src/pyclass.rs | 3 +--
+ tests/test_various.rs | 3 +--
+ 2 files changed, 2 insertions(+), 4 deletions(-)
+
+diff --git a/pyo3-derive-backend/src/pyclass.rs b/pyo3-derive-backend/src/pyclass.rs
+index 59a0ab29f..ea6c0f513 100644
+--- a/pyo3-derive-backend/src/pyclass.rs
++++ b/pyo3-derive-backend/src/pyclass.rs
+@@ -422,8 +422,7 @@ fn impl_class(
+ }
+ }
+
+- //impl<T: pyo3::type_object::PyTypeInfo> pyo3::AsPyRefDispatch<T> for #cls {}
+- //impl pyo3::ManagedPyRefDispatch for #cls {}
++ impl pyo3::AsPyRefDispatch<#cls> for Py<#cls> {}
+
+ #inventory_impl
+
+diff --git a/tests/test_various.rs b/tests/test_various.rs
+index 101bdabb0..655101db2 100644
+--- a/tests/test_various.rs
++++ b/tests/test_various.rs
+@@ -33,8 +33,7 @@ fn mut_ref_arg() {
+ let d = [("inst1", &inst1), ("inst2", &inst2)].into_py_dict(py);
+
+ py.run("inst1.set_other(inst2)", None, Some(d)).unwrap();
+- // MJDFIXME
+- //assert_eq!(inst2.as_ref(py).n, 100);
++ assert_eq!(inst2.as_ref(py).n, 100);
+ }
+
+ #[pyclass]
diff --git a/srcpkgs/anki/files/pyo3-patches/0018-specialization-d6102a4b93b16ba9b7b43a1c73614efbcb6e9814.patch b/srcpkgs/anki/files/pyo3-patches/0018-specialization-d6102a4b93b16ba9b7b43a1c73614efbcb6e9814.patch
new file mode 100644
index 00000000000..a66cb076d41
--- /dev/null
+++ b/srcpkgs/anki/files/pyo3-patches/0018-specialization-d6102a4b93b16ba9b7b43a1c73614efbcb6e9814.patch
@@ -0,0 +1,732 @@
+From d6102a4b93b16ba9b7b43a1c73614efbcb6e9814 Mon Sep 17 00:00:00 2001
+From: Martin Donlon <github-martin@donlons.com>
+Date: Mon, 4 Nov 2019 21:13:08 -0800
+Subject: [PATCH] Hack and slash to get arithmetic tests working
+
+---
+ pyo3-derive-backend/src/defs.rs | 127 +++++++++---------
+ src/class/basic.rs | 14 +-
+ src/class/number.rs | 28 ----
+ ...est_arithmetics.rp => test_arithmetics.rs} | 3 -
+ 4 files changed, 75 insertions(+), 97 deletions(-)
+ rename tests/{test_arithmetics.rp => test_arithmetics.rs} (99%)
+
+diff --git a/pyo3-derive-backend/src/defs.rs b/pyo3-derive-backend/src/defs.rs
+index 06c1c6754..d793c9628 100644
+--- a/pyo3-derive-backend/src/defs.rs
++++ b/pyo3-derive-backend/src/defs.rs
+@@ -24,7 +24,7 @@ const OBJECT: Proto = Proto {
+ arg: "Name",
+ pyres: true,
+ proto: "pyo3::class::basic::PyObjectGetAttrProtocol",
+- default: "pyo3::class::basic::PyObjectGetAttrProtocol",
++ default: "pyo3::class::basic::GetAttrProtocolImpl",
+ },
+ MethodProto::Ternary {
+ name: "__setattr__",
+@@ -32,58 +32,65 @@ const OBJECT: Proto = Proto {
+ arg2: "Value",
+ pyres: false,
+ proto: "pyo3::class::basic::PyObjectSetAttrProtocol",
+- default: "pyo3::class::basic::PyObjectSetAttrProtocol",
++ default: "pyo3::class::basic::tp_setattro_impl::SetAttr",
+ },
+ MethodProto::Binary {
+ name: "__delattr__",
+ arg: "Name",
+ pyres: true,
+ proto: "pyo3::class::basic::PyObjectDelAttrProtocol",
+- default: "pyo3::class::basic::PyObjectDelAttrProtocol",
++ default: "pyo3::class::basic::tp_setattro_impl::DelAttr",
+ },
+ MethodProto::Unary {
+ name: "__str__",
+ pyres: true,
+ proto: "pyo3::class::basic::PyObjectStrProtocol",
+- default: "pyo3::class::basic::PyObjectStrProtocol",
++ default: "pyo3::class::basic::StrProtocolImpl",
+ },
+ MethodProto::Unary {
+ name: "__repr__",
+ pyres: true,
+ proto: "pyo3::class::basic::PyObjectReprProtocol",
+- default: "pyo3::class::basic::PyObjectReprProtocol",
++ default: "pyo3::class::basic::ReprProtocolImpl",
+ },
+ MethodProto::Binary {
+ name: "__format__",
+ arg: "Format",
+ pyres: true,
+ proto: "pyo3::class::basic::PyObjectFormatProtocol",
+- default: "pyo3::class::basic::PyObjectFormatProtocol",
++ default: "pyo3::class::basic::FormatProtocolImpl",
+ },
+ MethodProto::Unary {
+ name: "__hash__",
+ pyres: false,
+ proto: "pyo3::class::basic::PyObjectHashProtocol",
+- default: "pyo3::class::basic::PyObjectHashProtocol",
++ default: "pyo3::class::basic::HashProtocolImpl",
+ },
+ MethodProto::Unary {
+ name: "__bytes__",
+ pyres: true,
+ proto: "pyo3::class::basic::PyObjectBytesProtocol",
+- default: "pyo3::class::basic::PyObjectBytesProtocol",
++ default: "pyo3::class::basic::BytesProtocolImpl",
++ },
++ MethodProto::Unary {
++ // MJDFIXME ???
++ name: "__unicode__",
++ pyres: true,
++ proto: "pyo3::class::basic::PyObjectUnicodeProtocol",
++ default: "pyo3::class::basic::UnicodeProtocolImpl",
+ },
+ MethodProto::Unary {
+ name: "__bool__",
+ pyres: false,
+ proto: "pyo3::class::basic::PyObjectBoolProtocol",
+- default: "pyo3::class::basic::PyObjectBoolProtocol",
++ default: "pyo3::class::basic::BoolProtocolImpl",
+ },
+ MethodProto::Binary {
+ name: "__richcmp__",
+ arg: "Other",
+ pyres: true,
+ proto: "pyo3::class::basic::PyObjectRichcmpProtocol",
+- default: "pyo3::class::basic::PyObjectRichcmpProtocol",
++ default: "pyo3::class::basic::RichcmpProtocolImpl",
+ },
+ ],
+ py_methods: &[
+@@ -451,7 +458,7 @@ const NUM: Proto = Proto {
+ arg2: "Right",
+ pyres: true,
+ proto: "pyo3::class::number::PyNumberAddProtocol",
+- default: "pyo3::class::number::PyNumberAddProtocol",
++ default: "pyo3::class::number::PyNumberAddProtocolImpl",
+ },
+ MethodProto::BinaryS {
+ name: "__sub__",
+@@ -459,7 +466,7 @@ const NUM: Proto = Proto {
+ arg2: "Right",
+ pyres: true,
+ proto: "pyo3::class::number::PyNumberSubProtocol",
+- default: "pyo3::class::number::PyNumberSubProtocol",
++ default: "pyo3::class::number::PyNumberSubProtocolImpl",
+ },
+ MethodProto::BinaryS {
+ name: "__mul__",
+@@ -467,7 +474,7 @@ const NUM: Proto = Proto {
+ arg2: "Right",
+ pyres: true,
+ proto: "pyo3::class::number::PyNumberMulProtocol",
+- default: "pyo3::class::number::PyNumberMulProtocol",
++ default: "pyo3::class::number::PyNumberMulProtocolImpl",
+ },
+ MethodProto::BinaryS {
+ name: "__matmul__",
+@@ -475,7 +482,7 @@ const NUM: Proto = Proto {
+ arg2: "Right",
+ pyres: true,
+ proto: "pyo3::class::number::PyNumberMatmulProtocol",
+- default: "pyo3::class::number::PyNumberMatmulProtocol",
++ default: "pyo3::class::number::PyNumberMatmulProtocolImpl",
+ },
+ MethodProto::BinaryS {
+ name: "__truediv__",
+@@ -483,7 +490,7 @@ const NUM: Proto = Proto {
+ arg2: "Right",
+ pyres: true,
+ proto: "pyo3::class::number::PyNumberTruedivProtocol",
+- default: "pyo3::class::number::PyNumberTruedivProtocol",
++ default: "pyo3::class::number::PyNumberTruedivProtocolImpl",
+ },
+ MethodProto::BinaryS {
+ name: "__floordiv__",
+@@ -491,7 +498,7 @@ const NUM: Proto = Proto {
+ arg2: "Right",
+ pyres: true,
+ proto: "pyo3::class::number::PyNumberFloordivProtocol",
+- default: "pyo3::class::number::PyNumberFloordivProtocol",
++ default: "pyo3::class::number::PyNumberFloordivProtocolImpl",
+ },
+ MethodProto::BinaryS {
+ name: "__mod__",
+@@ -499,7 +506,7 @@ const NUM: Proto = Proto {
+ arg2: "Right",
+ pyres: true,
+ proto: "pyo3::class::number::PyNumberModProtocol",
+- default: "pyo3::class::number::PyNumberModProtocol",
++ default: "pyo3::class::number::PyNumberModProtocolImpl",
+ },
+ MethodProto::BinaryS {
+ name: "__divmod__",
+@@ -507,7 +514,7 @@ const NUM: Proto = Proto {
+ arg2: "Right",
+ pyres: true,
+ proto: "pyo3::class::number::PyNumberDivmodProtocol",
+- default: "pyo3::class::number::PyNumberDivmodProtocol",
++ default: "pyo3::class::number::PyNumberDivmodProtocolImpl",
+ },
+ MethodProto::TernaryS {
+ name: "__pow__",
+@@ -516,7 +523,7 @@ const NUM: Proto = Proto {
+ arg3: "Modulo",
+ pyres: true,
+ proto: "pyo3::class::number::PyNumberPowProtocol",
+- default: "pyo3::class::number::PyNumberPowProtocol",
++ default: "pyo3::class::number::PyNumberPowProtocolImpl",
+ },
+ MethodProto::BinaryS {
+ name: "__lshift__",
+@@ -524,7 +531,7 @@ const NUM: Proto = Proto {
+ arg2: "Right",
+ pyres: true,
+ proto: "pyo3::class::number::PyNumberLShiftProtocol",
+- default: "pyo3::class::number::PyNumberLShiftProtocol",
++ default: "pyo3::class::number::PyNumberLShiftProtocolImpl",
+ },
+ MethodProto::BinaryS {
+ name: "__rshift__",
+@@ -532,7 +539,7 @@ const NUM: Proto = Proto {
+ arg2: "Right",
+ pyres: true,
+ proto: "pyo3::class::number::PyNumberRShiftProtocol",
+- default: "pyo3::class::number::PyNumberRShiftProtocol",
++ default: "pyo3::class::number::PyNumberRShiftProtocolImpl",
+ },
+ MethodProto::BinaryS {
+ name: "__and__",
+@@ -540,7 +547,7 @@ const NUM: Proto = Proto {
+ arg2: "Right",
+ pyres: true,
+ proto: "pyo3::class::number::PyNumberAndProtocol",
+- default: "pyo3::class::number::PyNumberAndProtocol",
++ default: "pyo3::class::number::PyNumberAndProtocolImpl",
+ },
+ MethodProto::BinaryS {
+ name: "__xor__",
+@@ -548,7 +555,7 @@ const NUM: Proto = Proto {
+ arg2: "Right",
+ pyres: true,
+ proto: "pyo3::class::number::PyNumberXorProtocol",
+- default: "pyo3::class::number::PyNumberXorProtocol",
++ default: "pyo3::class::number::PyNumberXorProtocolImpl",
+ },
+ MethodProto::BinaryS {
+ name: "__or__",
+@@ -556,63 +563,63 @@ const NUM: Proto = Proto {
+ arg2: "Right",
+ pyres: true,
+ proto: "pyo3::class::number::PyNumberOrProtocol",
+- default: "pyo3::class::number::PyNumberOrProtocol",
++ default: "pyo3::class::number::PyNumberOrProtocolImpl",
+ },
+ MethodProto::Binary {
+ name: "__radd__",
+ arg: "Other",
+ pyres: true,
+ proto: "pyo3::class::number::PyNumberRAddProtocol",
+- default: "pyo3::class::number::PyNumberRAddProtocol",
++ default: "pyo3::class::number::PyNumberRAddProtocolImpl",
+ },
+ MethodProto::Binary {
+ name: "__rsub__",
+ arg: "Other",
+ pyres: true,
+ proto: "pyo3::class::number::PyNumberRSubProtocol",
+- default: "pyo3::class::number::PyNumberRSubProtocol",
++ default: "pyo3::class::number::PyNumberRSubProtocolImpl",
+ },
+ MethodProto::Binary {
+ name: "__rmul__",
+ arg: "Other",
+ pyres: true,
+ proto: "pyo3::class::number::PyNumberRMulProtocol",
+- default: "pyo3::class::number::PyNumberRMulProtocol",
++ default: "pyo3::class::number::PyNumberRMulProtocolImpl",
+ },
+ MethodProto::Binary {
+ name: "__rmatmul__",
+ arg: "Other",
+ pyres: true,
+ proto: "pyo3::class::number::PyNumberRMatmulProtocol",
+- default: "pyo3::class::number::PyNumberRMatmulProtocol",
++ default: "pyo3::class::number::PyNumberRMatmulProtocolImpl",
+ },
+ MethodProto::Binary {
+ name: "__rtruediv__",
+ arg: "Other",
+ pyres: true,
+ proto: "pyo3::class::number::PyNumberRTruedivProtocol",
+- default: "pyo3::class::number::PyNumberRTruedivProtocol",
++ default: "pyo3::class::number::PyNumberRTruedivProtocolImpl",
+ },
+ MethodProto::Binary {
+ name: "__rfloordiv__",
+ arg: "Other",
+ pyres: true,
+ proto: "pyo3::class::number::PyNumberRFloordivProtocol",
+- default: "pyo3::class::number::PyNumberRFloordivProtocol",
++ default: "pyo3::class::number::PyNumberRFloordivProtocolImpl",
+ },
+ MethodProto::Binary {
+ name: "__rmod__",
+ arg: "Other",
+ pyres: true,
+ proto: "pyo3::class::number::PyNumberRModProtocol",
+- default: "pyo3::class::number::PyNumberRModProtocol",
++ default: "pyo3::class::number::PyNumberRModProtocolImpl",
+ },
+ MethodProto::Binary {
+ name: "__rdivmod__",
+ arg: "Other",
+ pyres: true,
+ proto: "pyo3::class::number::PyNumberRDivmodProtocol",
+- default: "pyo3::class::number::PyNumberRDivmodProtocol",
++ default: "pyo3::class::number::PyNumberRDivmodProtocolImpl",
+ },
+ MethodProto::Ternary {
+ name: "__rpow__",
+@@ -620,91 +627,91 @@ const NUM: Proto = Proto {
+ arg2: "Modulo",
+ pyres: true,
+ proto: "pyo3::class::number::PyNumberRPowProtocol",
+- default: "pyo3::class::number::PyNumberRPowProtocol",
++ default: "pyo3::class::number::PyNumberRPowProtocolImpl",
+ },
+ MethodProto::Binary {
+ name: "__rlshift__",
+ arg: "Other",
+ pyres: true,
+ proto: "pyo3::class::number::PyNumberRLShiftProtocol",
+- default: "pyo3::class::number::PyNumberRLShiftProtocol",
++ default: "pyo3::class::number::PyNumberRLShiftProtocolImpl",
+ },
+ MethodProto::Binary {
+ name: "__rrshift__",
+ arg: "Other",
+ pyres: true,
+ proto: "pyo3::class::number::PyNumberRRShiftProtocol",
+- default: "pyo3::class::number::PyNumberRRShiftProtocol",
++ default: "pyo3::class::number::PyNumberRRShiftProtocolImpl",
+ },
+ MethodProto::Binary {
+ name: "__rand__",
+ arg: "Other",
+ pyres: true,
+ proto: "pyo3::class::number::PyNumberRAndProtocol",
+- default: "pyo3::class::number::PyNumberRAndProtocol",
++ default: "pyo3::class::number::PyNumberRAndProtocolImpl",
+ },
+ MethodProto::Binary {
+ name: "__rxor__",
+ arg: "Other",
+ pyres: true,
+ proto: "pyo3::class::number::PyNumberRXorProtocol",
+- default: "pyo3::class::number::PyNumberRXorProtocol",
++ default: "pyo3::class::number::PyNumberRXorProtocolImpl",
+ },
+ MethodProto::Binary {
+ name: "__ror__",
+ arg: "Other",
+ pyres: true,
+ proto: "pyo3::class::number::PyNumberROrProtocol",
+- default: "pyo3::class::number::PyNumberROrProtocol",
++ default: "pyo3::class::number::PyNumberROrProtocolImpl",
+ },
+ MethodProto::Binary {
+ name: "__iadd__",
+ arg: "Other",
+ pyres: false,
+ proto: "pyo3::class::number::PyNumberIAddProtocol",
+- default: "pyo3::class::number::PyNumberIAddProtocol",
++ default: "pyo3::class::number::PyNumberIAddProtocolImpl",
+ },
+ MethodProto::Binary {
+ name: "__isub__",
+ arg: "Other",
+ pyres: false,
+ proto: "pyo3::class::number::PyNumberISubProtocol",
+- default: "pyo3::class::number::PyNumberISubProtocol",
++ default: "pyo3::class::number::PyNumberISubProtocolImpl",
+ },
+ MethodProto::Binary {
+ name: "__imul__",
+ arg: "Other",
+ pyres: false,
+ proto: "pyo3::class::number::PyNumberIMulProtocol",
+- default: "pyo3::class::number::PyNumberIMulProtocol",
++ default: "pyo3::class::number::PyNumberIMulProtocolImpl",
+ },
+ MethodProto::Binary {
+ name: "__imatmul__",
+ arg: "Other",
+ pyres: false,
+ proto: "pyo3::class::number::PyNumberIMatmulProtocol",
+- default: "pyo3::class::number::PyNumberIMatmulProtocol",
++ default: "pyo3::class::number::PyNumberIMatmulProtocolImpl",
+ },
+ MethodProto::Binary {
+ name: "__itruediv__",
+ arg: "Other",
+ pyres: false,
+ proto: "pyo3::class::number::PyNumberITruedivProtocol",
+- default: "pyo3::class::number::PyNumberITruedivProtocol",
++ default: "pyo3::class::number::PyNumberITruedivProtocolImpl",
+ },
+ MethodProto::Binary {
+ name: "__ifloordiv__",
+ arg: "Other",
+ pyres: false,
+ proto: "pyo3::class::number::PyNumberIFloordivProtocol",
+- default: "pyo3::class::number::PyNumberIFloordivProtocol",
++ default: "pyo3::class::number::PyNumberIFloordivProtocolImpl",
+ },
+ MethodProto::Binary {
+ name: "__imod__",
+ arg: "Other",
+ pyres: false,
+ proto: "pyo3::class::number::PyNumberIModProtocol",
+- default: "pyo3::class::number::PyNumberIModProtocol",
++ default: "pyo3::class::number::PyNumberIModProtocolImpl",
+ },
+ MethodProto::Ternary {
+ name: "__ipow__",
+@@ -712,96 +719,96 @@ const NUM: Proto = Proto {
+ arg2: "Modulo",
+ pyres: false,
+ proto: "pyo3::class::number::PyNumberIPowProtocol",
+- default: "pyo3::class::number::PyNumberIPowProtocol",
++ default: "pyo3::class::number::PyNumberIPowProtocolImpl",
+ },
+ MethodProto::Binary {
+ name: "__ilshift__",
+ arg: "Other",
+ pyres: false,
+ proto: "pyo3::class::number::PyNumberILShiftProtocol",
+- default: "pyo3::class::number::PyNumberILShiftProtocol",
++ default: "pyo3::class::number::PyNumberILShiftProtocolImpl",
+ },
+ MethodProto::Binary {
+ name: "__irshift__",
+ arg: "Other",
+ pyres: false,
+ proto: "pyo3::class::number::PyNumberIRShiftProtocol",
+- default: "pyo3::class::number::PyNumberIRShiftProtocol",
++ default: "pyo3::class::number::PyNumberIRShiftProtocolImpl",
+ },
+ MethodProto::Binary {
+ name: "__iand__",
+ arg: "Other",
+ pyres: false,
+ proto: "pyo3::class::number::PyNumberIAndProtocol",
+- default: "pyo3::class::number::PyNumberIAndProtocol",
++ default: "pyo3::class::number::PyNumberIAndProtocolImpl",
+ },
+ MethodProto::Binary {
+ name: "__ixor__",
+ arg: "Other",
+ pyres: false,
+ proto: "pyo3::class::number::PyNumberIXorProtocol",
+- default: "pyo3::class::number::PyNumberIXorProtocol",
++ default: "pyo3::class::number::PyNumberIXorProtocolImpl",
+ },
+ MethodProto::Binary {
+ name: "__ior__",
+ arg: "Other",
+ pyres: false,
+ proto: "pyo3::class::number::PyNumberIOrProtocol",
+- default: "pyo3::class::number::PyNumberIOrProtocol",
++ default: "pyo3::class::number::PyNumberIOrProtocolImpl",
+ },
+ MethodProto::Unary {
+ name: "__neg__",
+ pyres: true,
+ proto: "pyo3::class::number::PyNumberNegProtocol",
+- default: "pyo3::class::number::PyNumberNegProtocol",
++ default: "pyo3::class::number::PyNumberNegProtocolImpl",
+ },
+ MethodProto::Unary {
+ name: "__pos__",
+ pyres: true,
+ proto: "pyo3::class::number::PyNumberPosProtocol",
+- default: "pyo3::class::number::PyNumberPosProtocol",
++ default: "pyo3::class::number::PyNumberPosProtocolImpl",
+ },
+ MethodProto::Unary {
+ name: "__abs__",
+ pyres: true,
+ proto: "pyo3::class::number::PyNumberAbsProtocol",
+- default: "pyo3::class::number::PyNumberAbsProtocol",
++ default: "pyo3::class::number::PyNumberAbsProtocolImpl",
+ },
+ MethodProto::Unary {
+ name: "__invert__",
+ pyres: true,
+ proto: "pyo3::class::number::PyNumberInvertProtocol",
+- default: "pyo3::class::number::PyNumberInvertProtocol",
++ default: "pyo3::class::number::PyNumberInvertProtocolImpl",
+ },
+ MethodProto::Unary {
+ name: "__complex__",
+ pyres: true,
+ proto: "pyo3::class::number::PyNumberComplexProtocol",
+- default: "pyo3::class::number::PyNumberComplexProtocol",
++ default: "pyo3::class::number::PyNumberComplexProtocolImpl",
+ },
+ MethodProto::Unary {
+ name: "__int__",
+ pyres: true,
+ proto: "pyo3::class::number::PyNumberIntProtocol",
+- default: "pyo3::class::number::PyNumberIntProtocol",
++ default: "pyo3::class::number::PyNumberIntProtocolImpl",
+ },
+ MethodProto::Unary {
+ name: "__float__",
+ pyres: true,
+ proto: "pyo3::class::number::PyNumberFloatProtocol",
+- default: "pyo3::class::number::PyNumberFloatProtocol",
++ default: "pyo3::class::number::PyNumberFloatProtocolImpl",
+ },
+ MethodProto::Unary {
+ name: "__round__",
+ pyres: true,
+ proto: "pyo3::class::number::PyNumberRoundProtocol",
+- default: "pyo3::class::number::PyNumberRoundProtocol",
++ default: "pyo3::class::number::PyNumberRoundProtocolImpl",
+ },
+ MethodProto::Unary {
+ name: "__index__",
+ pyres: true,
+ proto: "pyo3::class::number::PyNumberIndexProtocol",
+- default: "pyo3::class::number::PyNumberIndexProtocol",
++ default: "pyo3::class::number::PyNumberIndexProtocolImpl",
+ },
+ ],
+ py_methods: &[
+diff --git a/src/class/basic.rs b/src/class/basic.rs
+index f87a0d029..15d682886 100644
+--- a/src/class/basic.rs
++++ b/src/class/basic.rs
+@@ -166,13 +166,15 @@ pub trait PyObjectProtocolImpl {
+ impl<'p, T> PyObjectProtocolImpl for T
+ where
+ T: PyObjectProtocol<'p>
+- + PyObjectSetAttrProtocol<'p>
+ + GetAttrProtocolImpl
+ + StrProtocolImpl
+ + ReprProtocolImpl
+ + HashProtocolImpl
+ + RichcmpProtocolImpl
+ + BoolProtocolImpl
++ + FormatProtocolImpl
++ + BytesProtocolImpl
++ + UnicodeProtocolImpl
+ + tp_setattro_impl::DelAttr
+ + tp_setattro_impl::SetAttr
+ + tp_setattro_impl::SetDelAttr,
+@@ -253,7 +255,7 @@ where
+ /// and may support deleting attributes (by implementing PyObjectDelAttrProtocol)
+ /// and we need to generate a single extern c function that supports only setting, only deleting
+ /// or both, and return None in case none of the two is supported.
+-mod tp_setattro_impl {
++pub mod tp_setattro_impl {
+ use super::*;
+
+ /// setattrofunc PyTypeObject.tp_setattro
+@@ -314,6 +316,9 @@ mod tp_setattro_impl {
+ }
+ }
+
++ impl<T> SetDelAttr for T {}
++
++ /* MJDFIXME
+ impl<T> SetDelAttr for T
+ where
+ T: for<'p> PyObjectSetAttrProtocol<'p> + for<'p> PyObjectDelAttrProtocol<'p>,
+@@ -327,7 +332,7 @@ mod tp_setattro_impl {
+ __delattr__
+ )
+ }
+- }
++ } */
+ }
+
+ pub trait StrProtocolImpl {
+@@ -376,7 +381,6 @@ pub trait FormatProtocolImpl {
+ None
+ }
+ }
+-impl<'p, T> FormatProtocolImpl for T where T: PyObjectProtocol<'p> {}
+
+ #[doc(hidden)]
+ pub trait BytesProtocolImpl {
+@@ -384,7 +388,6 @@ pub trait BytesProtocolImpl {
+ None
+ }
+ }
+-impl<'p, T> BytesProtocolImpl for T where T: PyObjectProtocol<'p> {}
+
+ #[doc(hidden)]
+ pub trait UnicodeProtocolImpl {
+@@ -392,7 +395,6 @@ pub trait UnicodeProtocolImpl {
+ None
+ }
+ }
+-impl<'p, T> UnicodeProtocolImpl for T where T: PyObjectProtocol<'p> {}
+
+ pub trait HashProtocolImpl {
+ fn tp_hash() -> Option<ffi::hashfunc> {
+diff --git a/src/class/number.rs b/src/class/number.rs
+index 796a1c7ea..faad83039 100644
+--- a/src/class/number.rs
++++ b/src/class/number.rs
+@@ -1273,8 +1273,6 @@ pub trait PyNumberRAddProtocolImpl {
+ }
+ }
+
+-impl<'p, T> PyNumberRAddProtocolImpl for T where T: PyNumberProtocol<'p> {}
+-
+ #[doc(hidden)]
+ pub trait PyNumberRSubProtocolImpl {
+ fn __rsub__() -> Option<PyMethodDef> {
+@@ -1282,8 +1280,6 @@ pub trait PyNumberRSubProtocolImpl {
+ }
+ }
+
+-impl<'p, T> PyNumberRSubProtocolImpl for T where T: PyNumberProtocol<'p> {}
+-
+ #[doc(hidden)]
+ pub trait PyNumberRMulProtocolImpl {
+ fn __rmul__() -> Option<PyMethodDef> {
+@@ -1291,8 +1287,6 @@ pub trait PyNumberRMulProtocolImpl {
+ }
+ }
+
+-impl<'p, T> PyNumberRMulProtocolImpl for T where T: PyNumberProtocol<'p> {}
+-
+ #[doc(hidden)]
+ pub trait PyNumberRMatmulProtocolImpl {
+ fn __rmatmul__() -> Option<PyMethodDef> {
+@@ -1300,8 +1294,6 @@ pub trait PyNumberRMatmulProtocolImpl {
+ }
+ }
+
+-impl<'p, T> PyNumberRMatmulProtocolImpl for T where T: PyNumberProtocol<'p> {}
+-
+ #[doc(hidden)]
+ pub trait PyNumberRTruedivProtocolImpl {
+ fn __rtruediv__() -> Option<PyMethodDef> {
+@@ -1309,8 +1301,6 @@ pub trait PyNumberRTruedivProtocolImpl {
+ }
+ }
+
+-impl<'p, T> PyNumberRTruedivProtocolImpl for T where T: PyNumberProtocol<'p> {}
+-
+ #[doc(hidden)]
+ pub trait PyNumberRFloordivProtocolImpl {
+ fn __rfloordiv__() -> Option<PyMethodDef> {
+@@ -1318,8 +1308,6 @@ pub trait PyNumberRFloordivProtocolImpl {
+ }
+ }
+
+-impl<'p, T> PyNumberRFloordivProtocolImpl for T where T: PyNumberProtocol<'p> {}
+-
+ #[doc(hidden)]
+ pub trait PyNumberRModProtocolImpl {
+ fn __rmod__() -> Option<PyMethodDef> {
+@@ -1327,8 +1315,6 @@ pub trait PyNumberRModProtocolImpl {
+ }
+ }
+
+-impl<'p, T> PyNumberRModProtocolImpl for T where T: PyNumberProtocol<'p> {}
+-
+ #[doc(hidden)]
+ pub trait PyNumberRDivmodProtocolImpl {
+ fn __rdivmod__() -> Option<PyMethodDef> {
+@@ -1336,8 +1322,6 @@ pub trait PyNumberRDivmodProtocolImpl {
+ }
+ }
+
+-impl<'p, T> PyNumberRDivmodProtocolImpl for T where T: PyNumberProtocol<'p> {}
+-
+ #[doc(hidden)]
+ pub trait PyNumberRPowProtocolImpl {
+ fn __rpow__() -> Option<PyMethodDef> {
+@@ -1345,8 +1329,6 @@ pub trait PyNumberRPowProtocolImpl {
+ }
+ }
+
+-impl<'p, T> PyNumberRPowProtocolImpl for T where T: PyNumberProtocol<'p> {}
+-
+ #[doc(hidden)]
+ pub trait PyNumberRLShiftProtocolImpl {
+ fn __rlshift__() -> Option<PyMethodDef> {
+@@ -1354,8 +1336,6 @@ pub trait PyNumberRLShiftProtocolImpl {
+ }
+ }
+
+-impl<'p, T> PyNumberRLShiftProtocolImpl for T where T: PyNumberProtocol<'p> {}
+-
+ #[doc(hidden)]
+ pub trait PyNumberRRShiftProtocolImpl {
+ fn __rrshift__() -> Option<PyMethodDef> {
+@@ -1363,8 +1343,6 @@ pub trait PyNumberRRShiftProtocolImpl {
+ }
+ }
+
+-impl<'p, T> PyNumberRRShiftProtocolImpl for T where T: PyNumberProtocol<'p> {}
+-
+ #[doc(hidden)]
+ pub trait PyNumberRAndProtocolImpl {
+ fn __rand__() -> Option<PyMethodDef> {
+@@ -1372,8 +1350,6 @@ pub trait PyNumberRAndProtocolImpl {
+ }
+ }
+
+-impl<'p, T> PyNumberRAndProtocolImpl for T where T: PyNumberProtocol<'p> {}
+-
+ #[doc(hidden)]
+ pub trait PyNumberRXorProtocolImpl {
+ fn __rxor__() -> Option<PyMethodDef> {
+@@ -1381,8 +1357,6 @@ pub trait PyNumberRXorProtocolImpl {
+ }
+ }
+
+-impl<'p, T> PyNumberRXorProtocolImpl for T where T: PyNumberProtocol<'p> {}
+-
+ #[doc(hidden)]
+ pub trait PyNumberROrProtocolImpl {
+ fn __ror__() -> Option<PyMethodDef> {
+@@ -1390,8 +1364,6 @@ pub trait PyNumberROrProtocolImpl {
+ }
+ }
+
+-impl<'p, T> PyNumberROrProtocolImpl for T where T: PyNumberProtocol<'p> {}
+-
+ pub trait PyNumberNegProtocolImpl {
+ fn nb_negative() -> Option<ffi::unaryfunc> {
+ None
+diff --git a/tests/test_arithmetics.rp b/tests/test_arithmetics.rs
+similarity index 99%
+rename from tests/test_arithmetics.rp
+rename to tests/test_arithmetics.rs
+index 42e378b5c..2fb25adf5 100644
+--- a/tests/test_arithmetics.rp
++++ b/tests/test_arithmetics.rs
+@@ -1,5 +1,3 @@
+-#![feature(specialization)]
+-
+ use pyo3::class::basic::CompareOp;
+ use pyo3::class::*;
+ use pyo3::prelude::*;
+@@ -16,7 +14,6 @@ impl PyNumberProtocol for UnaryArithmetic {
+ fn __neg__(&self) -> PyResult<&'static str> {
+ Ok("neg")
+ }
+-
+ fn __pos__(&self) -> PyResult<&'static str> {
+ Ok("pos")
+ }
diff --git a/srcpkgs/anki/files/pyo3-patches/0019-specialization-ac0158f18c02de6ab9dd9a6b96fd97a935d6f9b5.patch b/srcpkgs/anki/files/pyo3-patches/0019-specialization-ac0158f18c02de6ab9dd9a6b96fd97a935d6f9b5.patch
new file mode 100644
index 00000000000..20781e716f9
--- /dev/null
+++ b/srcpkgs/anki/files/pyo3-patches/0019-specialization-ac0158f18c02de6ab9dd9a6b96fd97a935d6f9b5.patch
@@ -0,0 +1,1321 @@
+From ac0158f18c02de6ab9dd9a6b96fd97a935d6f9b5 Mon Sep 17 00:00:00 2001
+From: Martin Donlon <github-martin@donlons.com>
+Date: Sun, 17 Nov 2019 08:23:49 -0800
+Subject: [PATCH] But default impls into a separate array in defs rather than
+ storing them in the MethodProto
+
+---
+ pyo3-derive-backend/src/defs.rs | 500 ++++++++++++++----
+ pyo3-derive-backend/src/func.rs | 23 -
+ pyo3-derive-backend/src/pyproto.rs | 17 +-
+ .../{test_dict_iter.rp => test_dict_iter.rs} | 0
+ tests/test_dunder.rp | 26 +-
+ 5 files changed, 426 insertions(+), 140 deletions(-)
+ rename tests/{test_dict_iter.rp => test_dict_iter.rs} (100%)
+
+diff --git a/pyo3-derive-backend/src/defs.rs b/pyo3-derive-backend/src/defs.rs
+index d793c9628..f7ac2da01 100644
+--- a/pyo3-derive-backend/src/defs.rs
++++ b/pyo3-derive-backend/src/defs.rs
+@@ -7,6 +7,7 @@ pub struct Proto {
+ pub impl_trait: &'static str,
+ pub methods: &'static [MethodProto],
+ pub py_methods: &'static [PyMethod],
++ pub default_impls: &'static [DefaultImpl],
+ }
+
+ pub struct PyMethod {
+@@ -14,6 +15,11 @@ pub struct PyMethod {
+ pub proto: &'static str,
+ }
+
++pub struct DefaultImpl {
++ pub name: &'static str,
++ pub default: &'static str,
++}
++
+ const OBJECT: Proto = Proto {
+ name: "Object",
+ protocol_trait: "pyo3::class::basic::PyObjectProtocol",
+@@ -24,7 +30,6 @@ const OBJECT: Proto = Proto {
+ arg: "Name",
+ pyres: true,
+ proto: "pyo3::class::basic::PyObjectGetAttrProtocol",
+- default: "pyo3::class::basic::GetAttrProtocolImpl",
+ },
+ MethodProto::Ternary {
+ name: "__setattr__",
+@@ -32,65 +37,49 @@ const OBJECT: Proto = Proto {
+ arg2: "Value",
+ pyres: false,
+ proto: "pyo3::class::basic::PyObjectSetAttrProtocol",
+- default: "pyo3::class::basic::tp_setattro_impl::SetAttr",
+ },
+ MethodProto::Binary {
+ name: "__delattr__",
+ arg: "Name",
+ pyres: true,
+ proto: "pyo3::class::basic::PyObjectDelAttrProtocol",
+- default: "pyo3::class::basic::tp_setattro_impl::DelAttr",
+ },
+ MethodProto::Unary {
+ name: "__str__",
+ pyres: true,
+ proto: "pyo3::class::basic::PyObjectStrProtocol",
+- default: "pyo3::class::basic::StrProtocolImpl",
+ },
+ MethodProto::Unary {
+ name: "__repr__",
+ pyres: true,
+ proto: "pyo3::class::basic::PyObjectReprProtocol",
+- default: "pyo3::class::basic::ReprProtocolImpl",
+ },
+ MethodProto::Binary {
+ name: "__format__",
+ arg: "Format",
+ pyres: true,
+ proto: "pyo3::class::basic::PyObjectFormatProtocol",
+- default: "pyo3::class::basic::FormatProtocolImpl",
+ },
+ MethodProto::Unary {
+ name: "__hash__",
+ pyres: false,
+ proto: "pyo3::class::basic::PyObjectHashProtocol",
+- default: "pyo3::class::basic::HashProtocolImpl",
+ },
+ MethodProto::Unary {
+ name: "__bytes__",
+ pyres: true,
+ proto: "pyo3::class::basic::PyObjectBytesProtocol",
+- default: "pyo3::class::basic::BytesProtocolImpl",
+- },
+- MethodProto::Unary {
+- // MJDFIXME ???
+- name: "__unicode__",
+- pyres: true,
+- proto: "pyo3::class::basic::PyObjectUnicodeProtocol",
+- default: "pyo3::class::basic::UnicodeProtocolImpl",
+ },
+ MethodProto::Unary {
+ name: "__bool__",
+ pyres: false,
+ proto: "pyo3::class::basic::PyObjectBoolProtocol",
+- default: "pyo3::class::basic::BoolProtocolImpl",
+ },
+ MethodProto::Binary {
+ name: "__richcmp__",
+ arg: "Other",
+ pyres: true,
+ proto: "pyo3::class::basic::PyObjectRichcmpProtocol",
+- default: "pyo3::class::basic::RichcmpProtocolImpl",
+ },
+ ],
+ py_methods: &[
+@@ -107,6 +96,52 @@ const OBJECT: Proto = Proto {
+ proto: "pyo3::class::basic::UnicodeProtocolImpl",
+ },
+ ],
++ default_impls: &[
++ DefaultImpl {
++ name: "__getattr__",
++ default: "pyo3::class::basic::GetAttrProtocolImpl",
++ },
++ DefaultImpl {
++ name: "__setattr__",
++ default: "pyo3::class::basic::tp_setattro_impl::SetAttr",
++ },
++ DefaultImpl {
++ name: "__delattr__",
++ default: "pyo3::class::basic::tp_setattro_impl::DelAttr",
++ },
++ DefaultImpl {
++ name: "__str__",
++ default: "pyo3::class::basic::StrProtocolImpl",
++ },
++ DefaultImpl {
++ name: "__repr__",
++ default: "pyo3::class::basic::ReprProtocolImpl",
++ },
++ DefaultImpl {
++ name: "__format__",
++ default: "pyo3::class::basic::FormatProtocolImpl",
++ },
++ DefaultImpl {
++ name: "__hash__",
++ default: "pyo3::class::basic::HashProtocolImpl",
++ },
++ DefaultImpl {
++ name: "__bytes__",
++ default: "pyo3::class::basic::BytesProtocolImpl",
++ },
++ DefaultImpl {
++ name: "__unicode__",
++ default: "pyo3::class::basic::UnicodeProtocolImpl",
++ },
++ DefaultImpl {
++ name: "__bool__",
++ default: "pyo3::class::basic::BoolProtocolImpl",
++ },
++ DefaultImpl {
++ name: "__richcmp__",
++ default: "pyo3::class::basic::RichcmpProtocolImpl",
++ },
++ ],
+ };
+
+ const ASYNC: Proto = Proto {
+@@ -118,25 +153,21 @@ const ASYNC: Proto = Proto {
+ name: "__await__",
+ pyres: true,
+ proto: "pyo3::class::pyasync::PyAsyncAwaitProtocol",
+- default: "pyo3::class::pyasync::PyAsyncAwaitProtocol",
+ },
+ MethodProto::Unary {
+ name: "__aiter__",
+ pyres: true,
+ proto: "pyo3::class::pyasync::PyAsyncAiterProtocol",
+- default: "pyo3::class::pyasync::PyAsyncAiterProtocol",
+ },
+ MethodProto::Unary {
+ name: "__anext__",
+ pyres: true,
+ proto: "pyo3::class::pyasync::PyAsyncAnextProtocol",
+- default: "pyo3::class::pyasync::PyAsyncAnextProtocol",
+ },
+ MethodProto::Unary {
+ name: "__aenter__",
+ pyres: true,
+ proto: "pyo3::class::pyasync::PyAsyncAenterProtocol",
+- default: "pyo3::class::pyasync::PyAsyncAenterProtocol",
+ },
+ MethodProto::Quaternary {
+ name: "__aexit__",
+@@ -144,7 +175,6 @@ const ASYNC: Proto = Proto {
+ arg2: "ExcValue",
+ arg3: "Traceback",
+ proto: "pyo3::class::pyasync::PyAsyncAexitProtocol",
+- default: "pyo3::class::pyasync::PyAsyncAexitProtocol",
+ },
+ ],
+ py_methods: &[
+@@ -157,6 +187,28 @@ const ASYNC: Proto = Proto {
+ proto: "pyo3::class::pyasync::PyAsyncAexitProtocolImpl",
+ },
+ ],
++ default_impls: &[
++ DefaultImpl {
++ name: "__await__",
++ default: "pyo3::class::pyasync::PyAsyncAwaitProtocol",
++ },
++ DefaultImpl {
++ name: "__aiter__",
++ default: "pyo3::class::pyasync::PyAsyncAiterProtocol",
++ },
++ DefaultImpl {
++ name: "__anext__",
++ default: "pyo3::class::pyasync::PyAsyncAnextProtocol",
++ },
++ DefaultImpl {
++ name: "__aenter__",
++ default: "pyo3::class::pyasync::PyAsyncAenterProtocol",
++ },
++ DefaultImpl {
++ name: "__aexit__",
++ default: "pyo3::class::pyasync::PyAsyncAexitProtocol",
++ },
++ ],
+ };
+
+ const BUFFER: Proto = Proto {
+@@ -168,16 +220,24 @@ const BUFFER: Proto = Proto {
+ name: "bf_getbuffer",
+ pyres: false,
+ proto: "pyo3::class::buffer::PyBufferGetBufferProtocol",
+- default: "pyo3::class::buffer::PyBufferGetBufferProtocolImpl",
+ },
+ MethodProto::Unary {
+ name: "bf_releasebuffer",
+ pyres: false,
+ proto: "pyo3::class::buffer::PyBufferReleaseBufferProtocol",
+- default: "pyo3::class::buffer::PyBufferReleaseBufferProtocolImpl",
+ },
+ ],
+ py_methods: &[],
++ default_impls: &[
++ DefaultImpl {
++ name: "bf_getbuffer",
++ default: "pyo3::class::buffer::PyBufferGetBufferProtocolImpl",
++ },
++ DefaultImpl {
++ name: "bf_releasebuffer",
++ default: "pyo3::class::buffer::PyBufferReleaseBufferProtocolImpl",
++ },
++ ],
+ };
+
+ const CONTEXT: Proto = Proto {
+@@ -189,7 +249,6 @@ const CONTEXT: Proto = Proto {
+ name: "__enter__",
+ pyres: true,
+ proto: "pyo3::class::context::PyContextEnterProtocol",
+- default: "pyo3::class::context::PyContextEnterProtocol",
+ },
+ MethodProto::Quaternary {
+ name: "__exit__",
+@@ -197,7 +256,6 @@ const CONTEXT: Proto = Proto {
+ arg2: "ExcValue",
+ arg3: "Traceback",
+ proto: "pyo3::class::context::PyContextExitProtocol",
+- default: "pyo3::class::context::PyContextExitProtocol",
+ },
+ ],
+ py_methods: &[
+@@ -210,6 +268,16 @@ const CONTEXT: Proto = Proto {
+ proto: "pyo3::class::context::PyContextExitProtocolImpl",
+ },
+ ],
++ default_impls: &[
++ DefaultImpl {
++ name: "__enter__",
++ default: "pyo3::class::context::PyContextEnterProtocol",
++ },
++ DefaultImpl {
++ name: "__exit__",
++ default: "pyo3::class::context::PyContextExitProtocol",
++ },
++ ],
+ };
+
+ const GC: Proto = Proto {
+@@ -221,15 +289,23 @@ const GC: Proto = Proto {
+ MethodProto::Free {
+ name: "__traverse__",
+ proto: "pyo3::class::gc::PyGCTraverseProtocol",
+- default: "pyo3::class::gc::PyGCTraverseProtocolImpl",
+ },
+ MethodProto::Free {
+ name: "__clear__",
+ proto: "pyo3::class::gc::PyGCClearProtocol",
+- default: "pyo3::class::gc::PyGCClearProtocolImpl",
+ },
+ ],
+ py_methods: &[],
++ default_impls: &[
++ DefaultImpl {
++ name: "__traverse__",
++ default: "pyo3::class::gc::PyGCTraverseProtocolImpl",
++ },
++ DefaultImpl {
++ name: "__clear__",
++ default: "pyo3::class::gc::PyGCClearProtocolImpl",
++ },
++ ],
+ };
+
+ const DESCR: Proto = Proto {
+@@ -244,7 +320,6 @@ const DESCR: Proto = Proto {
+ arg2: "Owner",
+ pyres: true,
+ proto: "pyo3::class::descr::PyDescrGetProtocol",
+- default: "pyo3::class::descr::PyDescrGetProtocol",
+ },
+ MethodProto::Ternary {
+ name: "__set__",
+@@ -252,21 +327,18 @@ const DESCR: Proto = Proto {
+ arg2: "Value",
+ pyres: true,
+ proto: "pyo3::class::descr::PyDescrSetProtocol",
+- default: "pyo3::class::descr::PyDescrSetProtocol",
+ },
+ MethodProto::Binary {
+ name: "__det__",
+ arg: "Inst",
+ pyres: false,
+ proto: "pyo3::class::descr::PyDescrDelProtocol",
+- default: "pyo3::class::descr::PyDescrDelProtocol",
+ },
+ MethodProto::Binary {
+ name: "__set_name__",
+ arg: "Inst",
+ pyres: false,
+ proto: "pyo3::class::descr::PyDescrSetNameProtocol",
+- default: "pyo3::class::descr::PyDescrSetNameProtocol",
+ },
+ ],
+ py_methods: &[
+@@ -279,6 +351,24 @@ const DESCR: Proto = Proto {
+ proto: "pyo3::class::context::PyDescrNameProtocolImpl",
+ },
+ ],
++ default_impls: &[
++ DefaultImpl {
++ name: "__get__",
++ default: "pyo3::class::descr::PyDescrGetProtocol",
++ },
++ DefaultImpl {
++ name: "__set__",
++ default: "pyo3::class::descr::PyDescrSetProtocol",
++ },
++ DefaultImpl {
++ name: "__det__",
++ default: "pyo3::class::descr::PyDescrDelProtocol",
++ },
++ DefaultImpl {
++ name: "__set_name__",
++ default: "pyo3::class::descr::PyDescrSetNameProtocol",
++ },
++ ],
+ };
+
+ const ITER: Proto = Proto {
+@@ -292,12 +382,20 @@ const ITER: Proto = Proto {
+ name: "__iter__",
+ pyres: true,
+ proto: "pyo3::class::iter::PyIterIterProtocol",
+- default: "pyo3::class::iter::PyIterIterProtocol",
+ },
+ MethodProto::Unary {
+ name: "__next__",
+ pyres: true,
+ proto: "pyo3::class::iter::PyIterNextProtocol",
++ },
++ ],
++ default_impls: &[
++ DefaultImpl {
++ name: "__iter__",
++ default: "pyo3::class::iter::PyIterIterProtocol",
++ },
++ DefaultImpl {
++ name: "__next__",
+ default: "pyo3::class::iter::PyIterNextProtocol",
+ },
+ ],
+@@ -313,14 +411,12 @@ const MAPPING: Proto = Proto {
+ name: "__len__",
+ pyres: false,
+ proto: "pyo3::class::mapping::PyMappingLenProtocol",
+- default: "pyo3::class::mapping::PyMappingLenProtocol",
+ },
+ MethodProto::Binary {
+ name: "__getitem__",
+ arg: "Key",
+ pyres: true,
+ proto: "pyo3::class::mapping::PyMappingGetItemProtocol",
+- default: "pyo3::class::mapping::PyMappingGetItemProtocol",
+ },
+ MethodProto::Ternary {
+ name: "__setitem__",
+@@ -328,33 +424,28 @@ const MAPPING: Proto = Proto {
+ arg2: "Value",
+ pyres: false,
+ proto: "pyo3::class::mapping::PyMappingSetItemProtocol",
+- default: "pyo3::class::mapping::PyMappingSetItemProtocol",
+ },
+ MethodProto::Binary {
+ name: "__delitem__",
+ arg: "Key",
+ pyres: false,
+ proto: "pyo3::class::mapping::PyMappingDelItemProtocol",
+- default: "pyo3::class::mapping::PyMappingDelItemProtocol",
+ },
+ MethodProto::Binary {
+ name: "__contains__",
+ arg: "Value",
+ pyres: false,
+ proto: "pyo3::class::mapping::PyMappingContainsProtocol",
+- default: "pyo3::class::mapping::PyMappingContainsProtocol",
+ },
+ MethodProto::Unary {
+ name: "__reversed__",
+ pyres: true,
+ proto: "pyo3::class::mapping::PyMappingReversedProtocol",
+- default: "pyo3::class::mapping::PyMappingReversedProtocol",
+ },
+ MethodProto::Unary {
+ name: "__iter__",
+ pyres: true,
+ proto: "pyo3::class::mapping::PyMappingIterProtocol",
+- default: "pyo3::class::mapping::PyMappingIterProtocol",
+ },
+ ],
+ py_methods: &[
+@@ -371,6 +462,36 @@ const MAPPING: Proto = Proto {
+ proto: "pyo3::class::mapping::PyMappingReversedProtocolImpl",
+ },
+ ],
++ default_impls: &[
++ DefaultImpl {
++ name: "__len__",
++ default: "pyo3::class::mapping::PyMappingLenProtocolImpl",
++ },
++ DefaultImpl {
++ name: "__getitem__",
++ default: "pyo3::class::mapping::PyMappingGetItemProtocolImpl",
++ },
++ DefaultImpl {
++ name: "__setitem__",
++ default: "pyo3::class::mapping::PyMappingSetItemProtocolImpl",
++ },
++ DefaultImpl {
++ name: "__delitem__",
++ default: "pyo3::class::mapping::PyMappingDelItemProtocolNotImpl",
++ },
++ DefaultImpl {
++ name: "__contains__",
++ default: "pyo3::class::mapping::PyMappingContainsProtocolImpl",
++ },
++ DefaultImpl {
++ name: "__reversed__",
++ default: "pyo3::class::mapping::PyMappingReversedProtocolImpl",
++ },
++ DefaultImpl {
++ name: "__iter__",
++ default: "pyo3::class::mapping::PyMappingIterProtocolImpl",
++ },
++ ],
+ };
+
+ const SEQ: Proto = Proto {
+@@ -383,14 +504,12 @@ const SEQ: Proto = Proto {
+ name: "__len__",
+ pyres: false,
+ proto: "pyo3::class::sequence::PySequenceLenProtocol",
+- default: "pyo3::class::sequence::PySequenceLenProtocolImpl",
+ },
+ MethodProto::Binary {
+ name: "__getitem__",
+ arg: "Index",
+ pyres: true,
+ proto: "pyo3::class::sequence::PySequenceGetItemProtocol",
+- default: "pyo3::class::sequence::PySequenceGetItemProtocolImpl",
+ },
+ MethodProto::Ternary {
+ name: "__setitem__",
+@@ -398,52 +517,83 @@ const SEQ: Proto = Proto {
+ arg2: "Value",
+ pyres: false,
+ proto: "pyo3::class::sequence::PySequenceSetItemProtocol",
+- default: "pyo3::class::sequence::PySequenceSetItemProtocolImpl",
+ },
+ MethodProto::Binary {
+ name: "__delitem__",
+ arg: "Index",
+ pyres: false,
+ proto: "pyo3::class::sequence::PySequenceDelItemProtocol",
+- default: "pyo3::class::sequence::PySequenceDelItemProtocolImpl",
+ },
+ MethodProto::Binary {
+ name: "__contains__",
+ arg: "Item",
+ pyres: false,
+ proto: "pyo3::class::sequence::PySequenceContainsProtocol",
+- default: "pyo3::class::sequence::PySequenceContainsProtocolImpl",
+ },
+ MethodProto::Binary {
+ name: "__concat__",
+ arg: "Other",
+ pyres: true,
+ proto: "pyo3::class::sequence::PySequenceConcatProtocol",
+- default: "pyo3::class::sequence::PySequenceConcatProtocolImpl",
+ },
+ MethodProto::Binary {
+ name: "__repeat__",
+ arg: "Index",
+ pyres: true,
+ proto: "pyo3::class::sequence::PySequenceRepeatProtocol",
+- default: "pyo3::class::sequence::PySequenceRepeatProtocolImpl",
+ },
+ MethodProto::Binary {
+ name: "__inplace_concat__",
+ arg: "Other",
+ pyres: true,
+ proto: "pyo3::class::sequence::PySequenceInplaceConcatProtocol",
+- default: "pyo3::class::sequence::PySequenceInplaceConcatProtocolImpl",
+ },
+ MethodProto::Binary {
+ name: "__inplace_repeat__",
+ arg: "Index",
+ pyres: true,
+ proto: "pyo3::class::sequence::PySequenceInplaceRepeatProtocol",
+- default: "pyo3::class::sequence::PySequenceInplaceRepeatProtocolImpl",
+ },
+ ],
+ py_methods: &[],
++ default_impls: &[
++ DefaultImpl {
++ name: "__len__",
++ default: "pyo3::class::sequence::PySequenceLenProtocolImpl",
++ },
++ DefaultImpl {
++ name: "__getitem__",
++ default: "pyo3::class::sequence::PySequenceGetItemProtocolImpl",
++ },
++ DefaultImpl {
++ name: "__setitem__",
++ default: "pyo3::class::sequence::PySequenceSetItemProtocolImpl",
++ },
++ DefaultImpl {
++ name: "__delitem__",
++ default: "pyo3::class::sequence::PySequenceDelItemProtocolImpl",
++ },
++ DefaultImpl {
++ name: "__contains__",
++ default: "pyo3::class::sequence::PySequenceContainsProtocolImpl",
++ },
++ DefaultImpl {
++ name: "__concat__",
++ default: "pyo3::class::sequence::PySequenceConcatProtocolImpl",
++ },
++ DefaultImpl {
++ name: "__repeat__",
++ default: "pyo3::class::sequence::PySequenceRepeatProtocolImpl",
++ },
++ DefaultImpl {
++ name: "__inplace_concat__",
++ default: "pyo3::class::sequence::PySequenceInplaceConcatProtocolImpl",
++ },
++ DefaultImpl {
++ name: "__inplace_repeat__",
++ default: "pyo3::class::sequence::PySequenceInplaceRepeatProtocolImpl",
++ },
++ ],
+ };
+
+ const NUM: Proto = Proto {
+@@ -458,7 +608,6 @@ const NUM: Proto = Proto {
+ arg2: "Right",
+ pyres: true,
+ proto: "pyo3::class::number::PyNumberAddProtocol",
+- default: "pyo3::class::number::PyNumberAddProtocolImpl",
+ },
+ MethodProto::BinaryS {
+ name: "__sub__",
+@@ -466,7 +615,6 @@ const NUM: Proto = Proto {
+ arg2: "Right",
+ pyres: true,
+ proto: "pyo3::class::number::PyNumberSubProtocol",
+- default: "pyo3::class::number::PyNumberSubProtocolImpl",
+ },
+ MethodProto::BinaryS {
+ name: "__mul__",
+@@ -474,7 +622,6 @@ const NUM: Proto = Proto {
+ arg2: "Right",
+ pyres: true,
+ proto: "pyo3::class::number::PyNumberMulProtocol",
+- default: "pyo3::class::number::PyNumberMulProtocolImpl",
+ },
+ MethodProto::BinaryS {
+ name: "__matmul__",
+@@ -482,7 +629,6 @@ const NUM: Proto = Proto {
+ arg2: "Right",
+ pyres: true,
+ proto: "pyo3::class::number::PyNumberMatmulProtocol",
+- default: "pyo3::class::number::PyNumberMatmulProtocolImpl",
+ },
+ MethodProto::BinaryS {
+ name: "__truediv__",
+@@ -490,7 +636,6 @@ const NUM: Proto = Proto {
+ arg2: "Right",
+ pyres: true,
+ proto: "pyo3::class::number::PyNumberTruedivProtocol",
+- default: "pyo3::class::number::PyNumberTruedivProtocolImpl",
+ },
+ MethodProto::BinaryS {
+ name: "__floordiv__",
+@@ -498,7 +643,6 @@ const NUM: Proto = Proto {
+ arg2: "Right",
+ pyres: true,
+ proto: "pyo3::class::number::PyNumberFloordivProtocol",
+- default: "pyo3::class::number::PyNumberFloordivProtocolImpl",
+ },
+ MethodProto::BinaryS {
+ name: "__mod__",
+@@ -506,7 +650,6 @@ const NUM: Proto = Proto {
+ arg2: "Right",
+ pyres: true,
+ proto: "pyo3::class::number::PyNumberModProtocol",
+- default: "pyo3::class::number::PyNumberModProtocolImpl",
+ },
+ MethodProto::BinaryS {
+ name: "__divmod__",
+@@ -514,7 +657,6 @@ const NUM: Proto = Proto {
+ arg2: "Right",
+ pyres: true,
+ proto: "pyo3::class::number::PyNumberDivmodProtocol",
+- default: "pyo3::class::number::PyNumberDivmodProtocolImpl",
+ },
+ MethodProto::TernaryS {
+ name: "__pow__",
+@@ -523,7 +665,6 @@ const NUM: Proto = Proto {
+ arg3: "Modulo",
+ pyres: true,
+ proto: "pyo3::class::number::PyNumberPowProtocol",
+- default: "pyo3::class::number::PyNumberPowProtocolImpl",
+ },
+ MethodProto::BinaryS {
+ name: "__lshift__",
+@@ -531,7 +672,6 @@ const NUM: Proto = Proto {
+ arg2: "Right",
+ pyres: true,
+ proto: "pyo3::class::number::PyNumberLShiftProtocol",
+- default: "pyo3::class::number::PyNumberLShiftProtocolImpl",
+ },
+ MethodProto::BinaryS {
+ name: "__rshift__",
+@@ -539,7 +679,6 @@ const NUM: Proto = Proto {
+ arg2: "Right",
+ pyres: true,
+ proto: "pyo3::class::number::PyNumberRShiftProtocol",
+- default: "pyo3::class::number::PyNumberRShiftProtocolImpl",
+ },
+ MethodProto::BinaryS {
+ name: "__and__",
+@@ -547,7 +686,6 @@ const NUM: Proto = Proto {
+ arg2: "Right",
+ pyres: true,
+ proto: "pyo3::class::number::PyNumberAndProtocol",
+- default: "pyo3::class::number::PyNumberAndProtocolImpl",
+ },
+ MethodProto::BinaryS {
+ name: "__xor__",
+@@ -555,7 +693,6 @@ const NUM: Proto = Proto {
+ arg2: "Right",
+ pyres: true,
+ proto: "pyo3::class::number::PyNumberXorProtocol",
+- default: "pyo3::class::number::PyNumberXorProtocolImpl",
+ },
+ MethodProto::BinaryS {
+ name: "__or__",
+@@ -563,63 +700,54 @@ const NUM: Proto = Proto {
+ arg2: "Right",
+ pyres: true,
+ proto: "pyo3::class::number::PyNumberOrProtocol",
+- default: "pyo3::class::number::PyNumberOrProtocolImpl",
+ },
+ MethodProto::Binary {
+ name: "__radd__",
+ arg: "Other",
+ pyres: true,
+ proto: "pyo3::class::number::PyNumberRAddProtocol",
+- default: "pyo3::class::number::PyNumberRAddProtocolImpl",
+ },
+ MethodProto::Binary {
+ name: "__rsub__",
+ arg: "Other",
+ pyres: true,
+ proto: "pyo3::class::number::PyNumberRSubProtocol",
+- default: "pyo3::class::number::PyNumberRSubProtocolImpl",
+ },
+ MethodProto::Binary {
+ name: "__rmul__",
+ arg: "Other",
+ pyres: true,
+ proto: "pyo3::class::number::PyNumberRMulProtocol",
+- default: "pyo3::class::number::PyNumberRMulProtocolImpl",
+ },
+ MethodProto::Binary {
+ name: "__rmatmul__",
+ arg: "Other",
+ pyres: true,
+ proto: "pyo3::class::number::PyNumberRMatmulProtocol",
+- default: "pyo3::class::number::PyNumberRMatmulProtocolImpl",
+ },
+ MethodProto::Binary {
+ name: "__rtruediv__",
+ arg: "Other",
+ pyres: true,
+ proto: "pyo3::class::number::PyNumberRTruedivProtocol",
+- default: "pyo3::class::number::PyNumberRTruedivProtocolImpl",
+ },
+ MethodProto::Binary {
+ name: "__rfloordiv__",
+ arg: "Other",
+ pyres: true,
+ proto: "pyo3::class::number::PyNumberRFloordivProtocol",
+- default: "pyo3::class::number::PyNumberRFloordivProtocolImpl",
+ },
+ MethodProto::Binary {
+ name: "__rmod__",
+ arg: "Other",
+ pyres: true,
+ proto: "pyo3::class::number::PyNumberRModProtocol",
+- default: "pyo3::class::number::PyNumberRModProtocolImpl",
+ },
+ MethodProto::Binary {
+ name: "__rdivmod__",
+ arg: "Other",
+ pyres: true,
+ proto: "pyo3::class::number::PyNumberRDivmodProtocol",
+- default: "pyo3::class::number::PyNumberRDivmodProtocolImpl",
+ },
+ MethodProto::Ternary {
+ name: "__rpow__",
+@@ -627,91 +755,78 @@ const NUM: Proto = Proto {
+ arg2: "Modulo",
+ pyres: true,
+ proto: "pyo3::class::number::PyNumberRPowProtocol",
+- default: "pyo3::class::number::PyNumberRPowProtocolImpl",
+ },
+ MethodProto::Binary {
+ name: "__rlshift__",
+ arg: "Other",
+ pyres: true,
+ proto: "pyo3::class::number::PyNumberRLShiftProtocol",
+- default: "pyo3::class::number::PyNumberRLShiftProtocolImpl",
+ },
+ MethodProto::Binary {
+ name: "__rrshift__",
+ arg: "Other",
+ pyres: true,
+ proto: "pyo3::class::number::PyNumberRRShiftProtocol",
+- default: "pyo3::class::number::PyNumberRRShiftProtocolImpl",
+ },
+ MethodProto::Binary {
+ name: "__rand__",
+ arg: "Other",
+ pyres: true,
+ proto: "pyo3::class::number::PyNumberRAndProtocol",
+- default: "pyo3::class::number::PyNumberRAndProtocolImpl",
+ },
+ MethodProto::Binary {
+ name: "__rxor__",
+ arg: "Other",
+ pyres: true,
+ proto: "pyo3::class::number::PyNumberRXorProtocol",
+- default: "pyo3::class::number::PyNumberRXorProtocolImpl",
+ },
+ MethodProto::Binary {
+ name: "__ror__",
+ arg: "Other",
+ pyres: true,
+ proto: "pyo3::class::number::PyNumberROrProtocol",
+- default: "pyo3::class::number::PyNumberROrProtocolImpl",
+ },
+ MethodProto::Binary {
+ name: "__iadd__",
+ arg: "Other",
+ pyres: false,
+ proto: "pyo3::class::number::PyNumberIAddProtocol",
+- default: "pyo3::class::number::PyNumberIAddProtocolImpl",
+ },
+ MethodProto::Binary {
+ name: "__isub__",
+ arg: "Other",
+ pyres: false,
+ proto: "pyo3::class::number::PyNumberISubProtocol",
+- default: "pyo3::class::number::PyNumberISubProtocolImpl",
+ },
+ MethodProto::Binary {
+ name: "__imul__",
+ arg: "Other",
+ pyres: false,
+ proto: "pyo3::class::number::PyNumberIMulProtocol",
+- default: "pyo3::class::number::PyNumberIMulProtocolImpl",
+ },
+ MethodProto::Binary {
+ name: "__imatmul__",
+ arg: "Other",
+ pyres: false,
+ proto: "pyo3::class::number::PyNumberIMatmulProtocol",
+- default: "pyo3::class::number::PyNumberIMatmulProtocolImpl",
+ },
+ MethodProto::Binary {
+ name: "__itruediv__",
+ arg: "Other",
+ pyres: false,
+ proto: "pyo3::class::number::PyNumberITruedivProtocol",
+- default: "pyo3::class::number::PyNumberITruedivProtocolImpl",
+ },
+ MethodProto::Binary {
+ name: "__ifloordiv__",
+ arg: "Other",
+ pyres: false,
+ proto: "pyo3::class::number::PyNumberIFloordivProtocol",
+- default: "pyo3::class::number::PyNumberIFloordivProtocolImpl",
+ },
+ MethodProto::Binary {
+ name: "__imod__",
+ arg: "Other",
+ pyres: false,
+ proto: "pyo3::class::number::PyNumberIModProtocol",
+- default: "pyo3::class::number::PyNumberIModProtocolImpl",
+ },
+ MethodProto::Ternary {
+ name: "__ipow__",
+@@ -719,96 +834,81 @@ const NUM: Proto = Proto {
+ arg2: "Modulo",
+ pyres: false,
+ proto: "pyo3::class::number::PyNumberIPowProtocol",
+- default: "pyo3::class::number::PyNumberIPowProtocolImpl",
+ },
+ MethodProto::Binary {
+ name: "__ilshift__",
+ arg: "Other",
+ pyres: false,
+ proto: "pyo3::class::number::PyNumberILShiftProtocol",
+- default: "pyo3::class::number::PyNumberILShiftProtocolImpl",
+ },
+ MethodProto::Binary {
+ name: "__irshift__",
+ arg: "Other",
+ pyres: false,
+ proto: "pyo3::class::number::PyNumberIRShiftProtocol",
+- default: "pyo3::class::number::PyNumberIRShiftProtocolImpl",
+ },
+ MethodProto::Binary {
+ name: "__iand__",
+ arg: "Other",
+ pyres: false,
+ proto: "pyo3::class::number::PyNumberIAndProtocol",
+- default: "pyo3::class::number::PyNumberIAndProtocolImpl",
+ },
+ MethodProto::Binary {
+ name: "__ixor__",
+ arg: "Other",
+ pyres: false,
+ proto: "pyo3::class::number::PyNumberIXorProtocol",
+- default: "pyo3::class::number::PyNumberIXorProtocolImpl",
+ },
+ MethodProto::Binary {
+ name: "__ior__",
+ arg: "Other",
+ pyres: false,
+ proto: "pyo3::class::number::PyNumberIOrProtocol",
+- default: "pyo3::class::number::PyNumberIOrProtocolImpl",
+ },
+ MethodProto::Unary {
+ name: "__neg__",
+ pyres: true,
+ proto: "pyo3::class::number::PyNumberNegProtocol",
+- default: "pyo3::class::number::PyNumberNegProtocolImpl",
+ },
+ MethodProto::Unary {
+ name: "__pos__",
+ pyres: true,
+ proto: "pyo3::class::number::PyNumberPosProtocol",
+- default: "pyo3::class::number::PyNumberPosProtocolImpl",
+ },
+ MethodProto::Unary {
+ name: "__abs__",
+ pyres: true,
+ proto: "pyo3::class::number::PyNumberAbsProtocol",
+- default: "pyo3::class::number::PyNumberAbsProtocolImpl",
+ },
+ MethodProto::Unary {
+ name: "__invert__",
+ pyres: true,
+ proto: "pyo3::class::number::PyNumberInvertProtocol",
+- default: "pyo3::class::number::PyNumberInvertProtocolImpl",
+ },
+ MethodProto::Unary {
+ name: "__complex__",
+ pyres: true,
+ proto: "pyo3::class::number::PyNumberComplexProtocol",
+- default: "pyo3::class::number::PyNumberComplexProtocolImpl",
+ },
+ MethodProto::Unary {
+ name: "__int__",
+ pyres: true,
+ proto: "pyo3::class::number::PyNumberIntProtocol",
+- default: "pyo3::class::number::PyNumberIntProtocolImpl",
+ },
+ MethodProto::Unary {
+ name: "__float__",
+ pyres: true,
+ proto: "pyo3::class::number::PyNumberFloatProtocol",
+- default: "pyo3::class::number::PyNumberFloatProtocolImpl",
+ },
+ MethodProto::Unary {
+ name: "__round__",
+ pyres: true,
+ proto: "pyo3::class::number::PyNumberRoundProtocol",
+- default: "pyo3::class::number::PyNumberRoundProtocolImpl",
+ },
+ MethodProto::Unary {
+ name: "__index__",
+ pyres: true,
+ proto: "pyo3::class::number::PyNumberIndexProtocol",
+- default: "pyo3::class::number::PyNumberIndexProtocolImpl",
+ },
+ ],
+ py_methods: &[
+@@ -877,6 +977,208 @@ const NUM: Proto = Proto {
+ proto: "pyo3::class::number::PyNumberRoundProtocolImpl",
+ },
+ ],
++ default_impls: &[
++ DefaultImpl {
++ name: "__add__",
++ default: "pyo3::class::number::PyNumberAddProtocolImpl",
++ },
++ DefaultImpl {
++ name: "__sub__",
++ default: "pyo3::class::number::PyNumberSubProtocolImpl",
++ },
++ DefaultImpl {
++ name: "__mul__",
++ default: "pyo3::class::number::PyNumberMulProtocolImpl",
++ },
++ DefaultImpl {
++ name: "__matmul__",
++ default: "pyo3::class::number::PyNumberMatmulProtocolImpl",
++ },
++ DefaultImpl {
++ name: "__truediv__",
++ default: "pyo3::class::number::PyNumberTruedivProtocolImpl",
++ },
++ DefaultImpl {
++ name: "__floordiv__",
++ default: "pyo3::class::number::PyNumberFloordivProtocolImpl",
++ },
++ DefaultImpl {
++ name: "__mod__",
++ default: "pyo3::class::number::PyNumberModProtocolImpl",
++ },
++ DefaultImpl {
++ name: "__divmod__",
++ default: "pyo3::class::number::PyNumberDivmodProtocolImpl",
++ },
++ DefaultImpl {
++ name: "__pow__",
++ default: "pyo3::class::number::PyNumberPowProtocolImpl",
++ },
++ DefaultImpl {
++ name: "__lshift__",
++ default: "pyo3::class::number::PyNumberLShiftProtocolImpl",
++ },
++ DefaultImpl {
++ name: "__rshift__",
++ default: "pyo3::class::number::PyNumberRShiftProtocolImpl",
++ },
++ DefaultImpl {
++ name: "__and__",
++ default: "pyo3::class::number::PyNumberAndProtocolImpl",
++ },
++ DefaultImpl {
++ name: "__xor__",
++ default: "pyo3::class::number::PyNumberXorProtocolImpl",
++ },
++ DefaultImpl {
++ name: "__or__",
++ default: "pyo3::class::number::PyNumberOrProtocolImpl",
++ },
++ DefaultImpl {
++ name: "__radd__",
++ default: "pyo3::class::number::PyNumberRAddProtocolImpl",
++ },
++ DefaultImpl {
++ name: "__rsub__",
++ default: "pyo3::class::number::PyNumberRSubProtocolImpl",
++ },
++ DefaultImpl {
++ name: "__rmul__",
++ default: "pyo3::class::number::PyNumberRMulProtocolImpl",
++ },
++ DefaultImpl {
++ name: "__rmatmul__",
++ default: "pyo3::class::number::PyNumberRMatmulProtocolImpl",
++ },
++ DefaultImpl {
++ name: "__rtruediv__",
++ default: "pyo3::class::number::PyNumberRTruedivProtocolImpl",
++ },
++ DefaultImpl {
++ name: "__rfloordiv__",
++ default: "pyo3::class::number::PyNumberRFloordivProtocolImpl",
++ },
++ DefaultImpl {
++ name: "__rmod__",
++ default: "pyo3::class::number::PyNumberRModProtocolImpl",
++ },
++ DefaultImpl {
++ name: "__rdivmod__",
++ default: "pyo3::class::number::PyNumberRDivmodProtocolImpl",
++ },
++ DefaultImpl {
++ name: "__rpow__",
++ default: "pyo3::class::number::PyNumberRPowProtocolImpl",
++ },
++ DefaultImpl {
++ name: "__rlshift__",
++ default: "pyo3::class::number::PyNumberRLShiftProtocolImpl",
++ },
++ DefaultImpl {
++ name: "__rrshift__",
++ default: "pyo3::class::number::PyNumberRRShiftProtocolImpl",
++ },
++ DefaultImpl {
++ name: "__rand__",
++ default: "pyo3::class::number::PyNumberRAndProtocolImpl",
++ },
++ DefaultImpl {
++ name: "__rxor__",
++ default: "pyo3::class::number::PyNumberRXorProtocolImpl",
++ },
++ DefaultImpl {
++ name: "__ror__",
++ default: "pyo3::class::number::PyNumberROrProtocolImpl",
++ },
++ DefaultImpl {
++ name: "__iadd__",
++ default: "pyo3::class::number::PyNumberIAddProtocolImpl",
++ },
++ DefaultImpl {
++ name: "__isub__",
++ default: "pyo3::class::number::PyNumberISubProtocolImpl",
++ },
++ DefaultImpl {
++ name: "__imul__",
++ default: "pyo3::class::number::PyNumberIMulProtocolImpl",
++ },
++ DefaultImpl {
++ name: "__imatmul__",
++ default: "pyo3::class::number::PyNumberIMatmulProtocolImpl",
++ },
++ DefaultImpl {
++ name: "__itruediv__",
++ default: "pyo3::class::number::PyNumberITruedivProtocolImpl",
++ },
++ DefaultImpl {
++ name: "__ifloordiv__",
++ default: "pyo3::class::number::PyNumberIFloordivProtocolImpl",
++ },
++ DefaultImpl {
++ name: "__imod__",
++ default: "pyo3::class::number::PyNumberIModProtocolImpl",
++ },
++ DefaultImpl {
++ name: "__ipow__",
++ default: "pyo3::class::number::PyNumberIPowProtocolImpl",
++ },
++ DefaultImpl {
++ name: "__ilshift__",
++ default: "pyo3::class::number::PyNumberILShiftProtocolImpl",
++ },
++ DefaultImpl {
++ name: "__irshift__",
++ default: "pyo3::class::number::PyNumberIRShiftProtocolImpl",
++ },
++ DefaultImpl {
++ name: "__iand__",
++ default: "pyo3::class::number::PyNumberIAndProtocolImpl",
++ },
++ DefaultImpl {
++ name: "__ixor__",
++ default: "pyo3::class::number::PyNumberIXorProtocolImpl",
++ },
++ DefaultImpl {
++ name: "__ior__",
++ default: "pyo3::class::number::PyNumberIOrProtocolImpl",
++ },
++ DefaultImpl {
++ name: "__neg__",
++ default: "pyo3::class::number::PyNumberNegProtocolImpl",
++ },
++ DefaultImpl {
++ name: "__pos__",
++ default: "pyo3::class::number::PyNumberPosProtocolImpl",
++ },
++ DefaultImpl {
++ name: "__abs__",
++ default: "pyo3::class::number::PyNumberAbsProtocolImpl",
++ },
++ DefaultImpl {
++ name: "__invert__",
++ default: "pyo3::class::number::PyNumberInvertProtocolImpl",
++ },
++ DefaultImpl {
++ name: "__complex__",
++ default: "pyo3::class::number::PyNumberComplexProtocolImpl",
++ },
++ DefaultImpl {
++ name: "__int__",
++ default: "pyo3::class::number::PyNumberIntProtocolImpl",
++ },
++ DefaultImpl {
++ name: "__float__",
++ default: "pyo3::class::number::PyNumberFloatProtocolImpl",
++ },
++ DefaultImpl {
++ name: "__round__",
++ default: "pyo3::class::number::PyNumberRoundProtocolImpl",
++ },
++ DefaultImpl {
++ name: "__index__",
++ default: "pyo3::class::number::PyNumberIndexProtocolImpl",
++ },
++ ],
+ };
+
+ const PROTOCOLS: &[Proto] = &[
+diff --git a/pyo3-derive-backend/src/func.rs b/pyo3-derive-backend/src/func.rs
+index ce06716f4..05aede490 100644
+--- a/pyo3-derive-backend/src/func.rs
++++ b/pyo3-derive-backend/src/func.rs
+@@ -12,20 +12,17 @@ pub enum MethodProto {
+ Free {
+ name: &'static str,
+ proto: &'static str,
+- default: &'static str,
+ },
+ Unary {
+ name: &'static str,
+ pyres: bool,
+ proto: &'static str,
+- default: &'static str,
+ },
+ Binary {
+ name: &'static str,
+ arg: &'static str,
+ pyres: bool,
+ proto: &'static str,
+- default: &'static str,
+ },
+ BinaryS {
+ name: &'static str,
+@@ -33,7 +30,6 @@ pub enum MethodProto {
+ arg2: &'static str,
+ pyres: bool,
+ proto: &'static str,
+- default: &'static str,
+ },
+ Ternary {
+ name: &'static str,
+@@ -41,7 +37,6 @@ pub enum MethodProto {
+ arg2: &'static str,
+ pyres: bool,
+ proto: &'static str,
+- default: &'static str,
+ },
+ TernaryS {
+ name: &'static str,
+@@ -50,7 +45,6 @@ pub enum MethodProto {
+ arg3: &'static str,
+ pyres: bool,
+ proto: &'static str,
+- default: &'static str,
+ },
+ Quaternary {
+ name: &'static str,
+@@ -58,7 +52,6 @@ pub enum MethodProto {
+ arg2: &'static str,
+ arg3: &'static str,
+ proto: &'static str,
+- default: &'static str,
+ },
+ }
+
+@@ -88,17 +81,6 @@ impl MethodProto {
+ MethodProto::Quaternary { proto: p, .. } => p,
+ }
+ }
+- pub fn get_default(&self) -> &'static str {
+- match *self {
+- MethodProto::Free { default: d, .. } => d,
+- MethodProto::Unary { default: d, .. } => d,
+- MethodProto::Binary { default: d, .. } => d,
+- MethodProto::BinaryS { default: d, .. } => d,
+- MethodProto::Ternary { default: d, .. } => d,
+- MethodProto::TernaryS { default: d, .. } => d,
+- MethodProto::Quaternary { default: d, .. } => d,
+- }
+- }
+ }
+
+ pub fn impl_method_proto(
+@@ -151,7 +133,6 @@ pub fn impl_method_proto(
+ arg,
+ pyres,
+ proto,
+- default: _,
+ } => {
+ if sig.inputs.len() <= 1 {
+ println!("Not enough arguments for {}", name);
+@@ -197,7 +178,6 @@ pub fn impl_method_proto(
+ arg2,
+ pyres,
+ proto,
+- default: _,
+ } => {
+ if sig.inputs.len() <= 1 {
+ print_err(format!("Not enough arguments {}", name), quote!(sig));
+@@ -247,7 +227,6 @@ pub fn impl_method_proto(
+ arg2,
+ pyres,
+ proto,
+- default: _,
+ } => {
+ if sig.inputs.len() <= 2 {
+ print_err(format!("Not enough arguments {}", name), quote!(sig));
+@@ -301,7 +280,6 @@ pub fn impl_method_proto(
+ arg3,
+ pyres,
+ proto,
+- default: _,
+ } => {
+ if sig.inputs.len() <= 2 {
+ print_err(format!("Not enough arguments {}", name), quote!(sig));
+@@ -358,7 +336,6 @@ pub fn impl_method_proto(
+ arg2,
+ arg3,
+ proto,
+- default: _,
+ } => {
+ if sig.inputs.len() <= 3 {
+ print_err(format!("Not enough arguments {}", name), quote!(sig));
+diff --git a/pyo3-derive-backend/src/pyproto.rs b/pyo3-derive-backend/src/pyproto.rs
+index a73232e1f..807be9052 100644
+--- a/pyo3-derive-backend/src/pyproto.rs
++++ b/pyo3-derive-backend/src/pyproto.rs
+@@ -9,6 +9,8 @@ use proc_macro2::TokenStream;
+ use quote::quote;
+ use quote::ToTokens;
+
++use std::collections::HashSet;
++
+ pub fn build_py_proto(ast: &mut syn::ItemImpl) -> syn::Result<TokenStream> {
+ if let Some((_, ref mut path, _)) = ast.trait_ {
+ let proto = if let Some(ref mut segment) = path.segments.last() {
+@@ -52,6 +54,7 @@ fn impl_proto_impl(
+ ) -> TokenStream {
+ let mut tokens = TokenStream::new();
+ let mut py_methods = Vec::new();
++ let mut implemented = HashSet::new();
+
+ let mut unimpl_methods: Vec<&MethodProto> = proto.methods.iter().collect();
+ let mut unimpl_py_methods: Vec<&defs::PyMethod> = proto.py_methods.iter().collect();
+@@ -59,6 +62,7 @@ fn impl_proto_impl(
+ for iimpl in impls.iter_mut() {
+ if let syn::ImplItem::Method(ref mut met) = iimpl {
+ let method_name = met.sig.ident.to_string();
++ implemented.insert(method_name.clone());
+ // Find the method in unimpl_methods, remove it and implement it
+ unimpl_methods
+ .iter()
+@@ -105,13 +109,18 @@ fn impl_proto_impl(
+ }
+ }
+
+- let default_impls: Vec<_> = unimpl_methods
++ let default_impls: Vec<_> = proto
++ .default_impls
+ .iter()
+- .map(|m| {
+- let proto: syn::Path = syn::parse_str(m.get_default()).unwrap();
+- quote! { impl #proto for #ty {} }
++ .filter_map(|def| match implemented.contains(def.name) {
++ true => None,
++ false => {
++ let proto: syn::Path = syn::parse_str(def.default).unwrap();
++ Some(quote! { impl #proto for #ty {} })
++ }
+ })
+ .collect();
++
+ quote! {
+ #tokens
+
+diff --git a/tests/test_dict_iter.rp b/tests/test_dict_iter.rs
+similarity index 100%
+rename from tests/test_dict_iter.rp
+rename to tests/test_dict_iter.rs
diff --git a/srcpkgs/anki/files/pyo3-patches/0020-remove-nightly-check.patch b/srcpkgs/anki/files/pyo3-patches/0020-remove-nightly-check.patch
new file mode 100644
index 00000000000..a92cfe08a5b
--- /dev/null
+++ b/srcpkgs/anki/files/pyo3-patches/0020-remove-nightly-check.patch
@@ -0,0 +1,17 @@
+--- a/build.rs 2020-06-01 19:27:44.819141296 +1000
++++ b/build.rs 2020-06-01 19:29:51.770147574 +1000
+@@ -539,14 +539,6 @@
+ MIN_VERSION, actual_version
+ )
+ }
+-
+- let actual_date = Date::read().expect("Failed to determine the rustc date");
+- if !actual_date.at_least(MIN_DATE) {
+- panic!(
+- "pyo3 requires at least rustc {}, while the current rustc date is {}",
+- MIN_DATE, actual_date
+- )
+- }
+ }
+
+ fn main() -> Result<(), String> {
diff --git a/srcpkgs/anki/patches/0001-aqt_data-fhs.patch b/srcpkgs/anki/patches/0001-aqt_data-fhs.patch
new file mode 100644
index 00000000000..ac0d29ec082
--- /dev/null
+++ b/srcpkgs/anki/patches/0001-aqt_data-fhs.patch
@@ -0,0 +1,45 @@
+From a0a9ac1aeb8b8678f1102aed81010a901ad8d9e1 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Johannes=20L=C3=B6thberg?= <johannes@kyriasis.com>
+Date: Sun, 29 Mar 2020 06:24:43 +0200
+Subject: [PATCH 1/4] Move aqt_data to sys.prefix/share
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+These files do _not_ belong right under sys.prefix.
+
+Signed-off-by: Johannes Löthberg <johannes@kyriasis.com>
+---
+ qt/aqt/utils.py | 2 +-
+ qt/setup.py | 2 +-
+ 2 files changed, 2 insertions(+), 2 deletions(-)
+
+diff --git qt/aqt/utils.py qt/aqt/utils.py
+index a0e12362..4d8c8c34 100644
+--- qt/aqt/utils.py
++++ qt/aqt/utils.py
+@@ -21,7 +21,7 @@ from aqt.theme import theme_manager
+
+ def aqt_data_folder() -> str:
+ # wheel install?
+- dir = os.path.join(sys.prefix, "aqt_data")
++ dir = os.path.join(sys.prefix,"share", "aqt_data")
+ if not os.path.exists(dir) or not os.listdir(dir):
+ # running in place?
+ dir = os.path.join(os.path.dirname(__file__), "..", "aqt_data")
+diff --git qt/setup.py qt/setup.py
+index 38f4e2b7..bdda3baa 100644
+--- qt/setup.py
++++ qt/setup.py
+@@ -8,7 +8,7 @@ import setuptools
+ def package_files(directory):
+ entries = []
+ for (path, directories, filenames) in os.walk(directory):
+- entries.append((path, [os.path.join(path, f) for f in filenames]))
++ entries.append((os.path.join("share", path), [os.path.join(path, f) for f in filenames]))
+ return entries
+
+
+--
+2.26.2
+
diff --git a/srcpkgs/anki/patches/0002-rust-nightly-fix.patch b/srcpkgs/anki/patches/0002-rust-nightly-fix.patch
new file mode 100644
index 00000000000..3d70aa36aad
--- /dev/null
+++ b/srcpkgs/anki/patches/0002-rust-nightly-fix.patch
@@ -0,0 +1,274 @@
+From fb578a0c2dc391f37de7cb6969c40f34d0de845c Mon Sep 17 00:00:00 2001
+From: Damien Elmes <gpg@ankiweb.net>
+Date: Fri, 24 Apr 2020 13:39:14 +1000
+Subject: [PATCH] switch to owned strings in ParsedTemplate
+
+will make it easier to cache the parsed results in the future,
+and handle field renames & other transformations
+---
+ rslib/src/notetype/cardgen.rs | 6 +-
+ rslib/src/notetype/templates.rs | 2 +-
+ rslib/src/template.rs | 98 +++++++++++++++++----------------
+ 3 files changed, 56 insertions(+), 50 deletions(-)
+
+Backported by fossy to stable. notetype patch is not needed.
+
+diff --git rslib/src/template.rs rslib/src/template.rs
+index 4479899009..ed5fe7e916 100644
+--- rslib/src/template.rs
++++ rslib/src/template.rs
+@@ -147,26 +147,26 @@ fn legacy_tokens(mut data: &str) -> impl Iterator<Item = TemplateResult<Token>>
+ //----------------------------------------
+
+ #[derive(Debug, PartialEq)]
+-enum ParsedNode<'a> {
+- Text(&'a str),
++enum ParsedNode {
++ Text(String),
+ Replacement {
+- key: &'a str,
+- filters: Vec<&'a str>,
++ key: String,
++ filters: Vec<String>,
+ },
+ Conditional {
+- key: &'a str,
+- children: Vec<ParsedNode<'a>>,
++ key: String,
++ children: Vec<ParsedNode>,
+ },
+ NegatedConditional {
+- key: &'a str,
+- children: Vec<ParsedNode<'a>>,
++ key: String,
++ children: Vec<ParsedNode>,
+ },
+ }
+
+ #[derive(Debug)]
+-pub struct ParsedTemplate<'a>(Vec<ParsedNode<'a>>);
++pub struct ParsedTemplate(Vec<ParsedNode>);
+
+-impl ParsedTemplate<'_> {
++impl ParsedTemplate {
+ /// Create a template from the provided text.
+ pub fn from_text(template: &str) -> TemplateResult<ParsedTemplate> {
+ let mut iter = tokens(template);
+@@ -177,26 +177,26 @@ impl ParsedTemplate<'_> {
+ fn parse_inner<'a, I: Iterator<Item = TemplateResult<Token<'a>>>>(
+ iter: &mut I,
+ open_tag: Option<&'a str>,
+-) -> TemplateResult<Vec<ParsedNode<'a>>> {
++) -> TemplateResult<Vec<ParsedNode>> {
+ let mut nodes = vec![];
+
+ while let Some(token) = iter.next() {
+ use Token::*;
+ nodes.push(match token? {
+- Text(t) => ParsedNode::Text(t),
++ Text(t) => ParsedNode::Text(t.into()),
+ Replacement(t) => {
+ let mut it = t.rsplit(':');
+ ParsedNode::Replacement {
+- key: it.next().unwrap(),
+- filters: it.collect(),
++ key: it.next().unwrap().into(),
++ filters: it.map(Into::into).collect(),
+ }
+ }
+ OpenConditional(t) => ParsedNode::Conditional {
+- key: t,
++ key: t.into(),
+ children: parse_inner(iter, Some(t))?,
+ },
+ OpenNegated(t) => ParsedNode::NegatedConditional {
+- key: t,
++ key: t.into(),
+ children: parse_inner(iter, Some(t))?,
+ },
+ CloseConditional(t) => {
+@@ -285,27 +285,27 @@ fn localized_template_error(i18n: &I18n, err: TemplateError) -> String {
+ // Checking if template is empty
+ //----------------------------------------
+
+-impl ParsedTemplate<'_> {
++impl ParsedTemplate {
+ /// true if provided fields are sufficient to render the template
+ pub fn renders_with_fields(&self, nonempty_fields: &HashSet<&str>) -> bool {
+ !template_is_empty(nonempty_fields, &self.0)
+ }
+ }
+
+-fn template_is_empty<'a>(nonempty_fields: &HashSet<&str>, nodes: &[ParsedNode<'a>]) -> bool {
++fn template_is_empty(nonempty_fields: &HashSet<&str>, nodes: &[ParsedNode]) -> bool {
+ use ParsedNode::*;
+ for node in nodes {
+ match node {
+ // ignore normal text
+ Text(_) => (),
+ Replacement { key, .. } => {
+- if nonempty_fields.contains(*key) {
++ if nonempty_fields.contains(key.as_str()) {
+ // a single replacement is enough
+ return false;
+ }
+ }
+ Conditional { key, children } => {
+- if !nonempty_fields.contains(*key) {
++ if !nonempty_fields.contains(key.as_str()) {
+ continue;
+ }
+ if !template_is_empty(nonempty_fields, children) {
+@@ -347,7 +347,7 @@ pub(crate) struct RenderContext<'a> {
+ pub card_ord: u16,
+ }
+
+-impl ParsedTemplate<'_> {
++impl ParsedTemplate {
+ /// Render the template with the provided fields.
+ ///
+ /// Replacements that use only standard filters will become part of
+@@ -373,10 +373,7 @@ fn render_into(
+ Text(text) => {
+ append_str_to_nodes(rendered_nodes, text);
+ }
+- Replacement {
+- key: key @ "FrontSide",
+- ..
+- } => {
++ Replacement { key, .. } if key == "FrontSide" => {
+ // defer FrontSide rendering to Python, as extra
+ // filters may be required
+ rendered_nodes.push(RenderedNode::Replacement {
+@@ -385,27 +382,36 @@ fn render_into(
+ current_text: "".into(),
+ });
+ }
+- Replacement { key: "", filters } if !filters.is_empty() => {
++ Replacement { key, filters } if key == "" && !filters.is_empty() => {
+ // if a filter is provided, we accept an empty field name to
+ // mean 'pass an empty string to the filter, and it will add
+ // its own text'
+ rendered_nodes.push(RenderedNode::Replacement {
+ field_name: "".to_string(),
+ current_text: "".to_string(),
+- filters: filters.iter().map(|&f| f.to_string()).collect(),
++ filters: filters.clone(),
+ })
+ }
+ Replacement { key, filters } => {
+ // apply built in filters if field exists
+- let (text, remaining_filters) = match context.fields.get(key) {
+- Some(text) => apply_filters(text, filters, key, context),
++ let (text, remaining_filters) = match context.fields.get(key.as_str()) {
++ Some(text) => apply_filters(
++ text,
++ filters
++ .iter()
++ .map(|s| s.as_str())
++ .collect::<Vec<_>>()
++ .as_slice(),
++ key,
++ context,
++ ),
+ None => {
+ // unknown field encountered
+ let filters_str = filters
+ .iter()
+ .rev()
+ .cloned()
+- .chain(iter::once(""))
++ .chain(iter::once("".into()))
+ .collect::<Vec<_>>()
+ .join(":");
+ return Err(TemplateError::FieldNotFound {
+@@ -427,12 +433,12 @@ fn render_into(
+ }
+ }
+ Conditional { key, children } => {
+- if context.nonempty_fields.contains(key) {
++ if context.nonempty_fields.contains(key.as_str()) {
+ render_into(rendered_nodes, children.as_ref(), context)?;
+ }
+ }
+ NegatedConditional { key, children } => {
+- if !context.nonempty_fields.contains(key) {
++ if !context.nonempty_fields.contains(key.as_str()) {
+ render_into(rendered_nodes, children.as_ref(), context)?;
+ }
+ }
+@@ -542,7 +548,7 @@ pub enum FieldRequirements {
+ None,
+ }
+
+-impl ParsedTemplate<'_> {
++impl ParsedTemplate {
+ /// Return fields required by template.
+ ///
+ /// This is not able to represent negated expressions or combinations of
+@@ -613,11 +619,11 @@
+ vec![
+- Text("foo "),
++ Text("foo ".into()),
+ Replacement {
+- key: "bar",
++ key: "bar".into(),
+ filters: vec![]
+ },
+- Text(" "),
++ Text(" ".into()),
+ Conditional {
+- key: "baz",
+- children: vec![Text(" quux ")]
++ key: "baz".into(),
++ children: vec![Text(" quux ".into())]
+ }
+ ]
+@@ -630,7 +636,7 @@ mod test {
+ assert_eq!(
+ tmpl.0,
+ vec![NegatedConditional {
+- key: "baz",
++ key: "baz".into(),
+ children: vec![]
+ }]
+ );
+@@ -643,7 +649,7 @@ mod test {
+ assert_eq!(
+ PT::from_text("{{ tag }}").unwrap().0,
+ vec![Replacement {
+- key: "tag",
++ key: "tag".into(),
+ filters: vec![]
+ }]
+ );
+@@ -651,7 +657,7 @@ mod test {
+ // stray closing characters (like in javascript) are ignored
+ assert_eq!(
+ PT::from_text("text }} more").unwrap().0,
+- vec![Text("text }} more")]
++ vec![Text("text }} more".into())]
+ );
+
+ PT::from_text("{{").unwrap_err();
+@@ -737,15 +743,15 @@ mod test {
+ assert_eq!(
+ PT::from_text(input).unwrap().0,
+ vec![
+- Text("\n"),
++ Text("\n".into()),
+ Replacement {
+- key: "Front",
++ key: "Front".into(),
+ filters: vec![]
+ },
+- Text("\n"),
++ Text("\n".into()),
+ Conditional {
+- key: "Back",
+- children: vec![Text("\n")]
++ key: "Back".into(),
++ children: vec![Text("\n".into())]
+ }
+ ]
+ );
diff --git a/srcpkgs/anki/patches/0003-rustc-cross-compile.patch b/srcpkgs/anki/patches/0003-rustc-cross-compile.patch
new file mode 100644
index 00000000000..15239ea4cf1
--- /dev/null
+++ b/srcpkgs/anki/patches/0003-rustc-cross-compile.patch
@@ -0,0 +1,11 @@
+--- rspy/Makefile 2020-05-23 12:02:29.758286838 +1000
++++ rspy/Makefile 2020-05-08 18:17:57.000000000 +1000
+@@ -69,7 +69,7 @@
+ .build/build: $(DEPS)
+ touch ../proto/backend.proto
+ ${BUILD_VARIABLES} \
+- maturin build -i "${PYTHON_FILE}" -o "$(OUTDIR)" $(BUILDFLAGS)
++ maturin build -i "${PYTHON_FILE}" -o "$(OUTDIR)" $(BUILDFLAGS) --target $(RUST_TARGET)
+ touch $@
+
+ check: .build/check
diff --git a/srcpkgs/anki/patches/0004-vendored-deps.patch b/srcpkgs/anki/patches/0004-vendored-deps.patch
new file mode 100644
index 00000000000..7ca936804fc
--- /dev/null
+++ b/srcpkgs/anki/patches/0004-vendored-deps.patch
@@ -0,0 +1,91 @@
+diff -u -r Makefile Makefile
+--- Makefile 2020-05-08 18:17:57.000000000 +1000
++++ Makefile 2020-05-19 18:40:54.345223164 +1000
+@@ -92,7 +92,7 @@
+ fi
+
+ .PHONY: develop
+-develop: pyenv buildhash prepare
++develop: buildhash prepare
+ @set -eu -o pipefail ${SHELLFLAGS}; \
+ . "${ACTIVATE_SCRIPT}"; \
+ for dir in $(DEVEL); do \
+diff -u -r pylib/Makefile pylib/Makefile
+--- pylib/Makefile 2020-05-08 18:17:57.000000000 +1000
++++ pylib/Makefile 2020-05-19 18:50:01.075182994 +1000
+@@ -52,7 +52,7 @@
+ python -m black anki/hooks.py
+ @touch $@
+
+-BUILD_STEPS := .build/vernum .build/run-deps .build/dev-deps .build/py-proto anki/buildinfo.py .build/hooks
++BUILD_STEPS := .build/vernum .build/py-proto anki/buildinfo.py .build/hooks
+
+ # Checking
+ ######################
+diff -u -r qt/Makefile qt/Makefile
+--- qt/Makefile 2020-05-08 18:17:57.000000000 +1000
++++ qt/Makefile 2020-05-19 18:50:17.520181786 +1000
+@@ -64,7 +64,7 @@
+ python -m black aqt/gui_hooks.py
+ @touch $@
+
+-BUILD_STEPS := .build/vernum .build/run-deps .build/dev-deps .build/js .build/ui aqt/buildinfo.py .build/hooks .build/i18n
++BUILD_STEPS := .build/vernum .build/js .build/ui aqt/buildinfo.py .build/hooks .build/i18n
+
+ # Checking
+ ######################
+--- Makefile 2020-05-08 18:17:57.000000000 +1000
++++ Makefile 2020-05-19 19:01:35.602131965 +1000
+@@ -122,7 +122,7 @@
+ @echo "Build complete."
+
+ .PHONY: build-rspy
+-build-rspy: pyenv buildhash
++build-rspy: buildhash
+ @set -eu -o pipefail ${SHELLFLAGS}; \
+ . "${ACTIVATE_SCRIPT}"; \
+ $(SUBMAKE) -C rspy build BUILDFLAGS="$(BUILDFLAGS)"
+--- Makefile 2020-05-19 19:41:44.191955000 +1000
++++ Makefile 2020-05-19 19:42:21.423952264 +1000
+@@ -124,19 +124,16 @@
+ .PHONY: build-rspy
+ build-rspy: buildhash
+ @set -eu -o pipefail ${SHELLFLAGS}; \
+- . "${ACTIVATE_SCRIPT}"; \
+ $(SUBMAKE) -C rspy build BUILDFLAGS="$(BUILDFLAGS)"
+
+ .PHONY: build-pylib
+ build-pylib:
+ @set -eu -o pipefail ${SHELLFLAGS}; \
+- . "${ACTIVATE_SCRIPT}"; \
+ $(SUBMAKE) -C pylib build
+
+ .PHONY: build-qt
+ build-qt:
+ @set -eu -o pipefail ${SHELLFLAGS}; \
+- . "${ACTIVATE_SCRIPT}"; \
+ $(SUBMAKE) -C qt build
+
+ .PHONY: clean
+--- pylib/Makefile 2020-05-22 08:46:14.988607539 +1000
++++ pylib/Makefile 2020-05-22 08:46:38.376605821 +1000
+@@ -41,7 +41,7 @@
+
+ PROTODEPS := $(wildcard ../proto/*.proto)
+
+-.build/py-proto: .build/dev-deps $(PROTODEPS)
++.build/py-proto: $(PROTODEPS)
+ protoc --proto_path=../proto --python_out=anki --mypy_out=anki $(PROTODEPS)
+ perl -i'' -pe 's/from fluent_pb2/from anki.fluent_pb2/' anki/backend_pb2.pyi
+ perl -i'' -pe 's/import fluent_pb2/import anki.fluent_pb2/' anki/backend_pb2.py
+--- rspy/Makefile 2020-05-31 08:59:03.810152342 +1000
++++ rspy/Makefile 2020-05-08 18:17:57.000000000 +1000
+@@ -51,7 +51,7 @@
+
+ develop: .build/develop
+
+-DEPS := .build/tools .build/vernum ../meta/buildhash \
++DEPS := .build/vernum ../meta/buildhash \
+ $(wildcard $(QT_FTL_TEMPLATES)/*.ftl) \
+ $(wildcard $(QT_FTL_LOCALES)/*/*.ftl) \
+ $(shell "${FIND}" ../rslib/src -name '*.rs') $(wildcard ../proto/*) \
diff --git a/srcpkgs/anki/patches/0005-patched-pyo3.patch b/srcpkgs/anki/patches/0005-patched-pyo3.patch
new file mode 100644
index 00000000000..15844cc15fe
--- /dev/null
+++ b/srcpkgs/anki/patches/0005-patched-pyo3.patch
@@ -0,0 +1,11 @@
+--- rspy/Cargo.toml 2020-05-08 18:17:57.000000000 +1000
++++ rspy/Cargo.toml.new 2020-05-30 17:46:26.548157472 +1000
+@@ -12,7 +12,7 @@
+ tokio = "0.2.11"
+
+ [dependencies.pyo3]
+-version = "0.8.0"
++path = "../../pyo3"
+ features = ["extension-module"]
+
+ [lib]
diff --git a/srcpkgs/anki/template b/srcpkgs/anki/template
index 680e008a9d4..4b89be6f8d0 100644
--- a/srcpkgs/anki/template
+++ b/srcpkgs/anki/template
@@ -1,23 +1,78 @@
# Template file for 'anki'
+#
+# NOTE: This template does use rust stable. It has a rather large
+# pyo3 patchset taken from github.com/wickerwaka/pyo3/removing-specialization
+# which allows it to operate on rust stable. But, it is currently on pyo3
+# 0.8.1. This patchset should ideally be rebased for the new version.
+# Preliminary tests found this would be slightly difficult. Anki dosen't
+# need a newer version.. yet.
+#
pkgname=anki
-version=2.1.15
-revision=2
-archs=noarch
+version=2.1.26
+revision=1
+_pyo3_version=0.8.1
build_style=gnu-makefile
pycompile_dirs="/usr/share/anki/anki /usr/share/anki/aqt"
+hostmakedepends="git python3 rust cargo maturin which protobuf
+ mypy-protobuf-python python3-stringcase black python3-wheel
+ rsync nodejs python3-PyQt5-devel-tools gettext
+ qt5-translations python3-pip strace"
depends="python3-PyQt5-webengine python3-requests python3-SQLAlchemy
python3-PyAudio python3-mpv python3-Markdown python3-send2trash
- python3-BeautifulSoup4 python3-decorator python3-jsonschema"
+ python3-BeautifulSoup4 python3-decorator python3-jsonschema
+ python3-protobuf"
short_desc="Spaced repetition flashcard program"
maintainer="Steve Prybylski <sa.prybylx@gmail.com>"
license="AGPL-3.0-or-later"
homepage="https://apps.ankiweb.net"
changelog="https://apps.ankiweb.net/docs/changes.html"
-distfiles="https://apps.ankiweb.net/downloads/current/anki-${version}-source.tgz"
-checksum=5a53760164c77d619f55107a13099cffe620566a7f610b61b6c4b52487f3bb89
-
+distfiles="https://github.com/ankitects/anki/archive/${version}.tar.gz
+ https://github.com/PyO3/pyo3/archive/v${_pyo3_version}.tar.gz"
+checksum="f5a0c41f3eebe0e77de9d46f2a5cbbe20f7c3a4787f0f02e1d33f298428acbdf
+ 437a5fcb54113da9e2999fb957c8948ca40f4f31081b6e8cf1d798033071eb57"
python_version=3
+post_extract() {
+ # Constant place for 0006-patched-pyo3.patch
+ mv "${XBPS_BUILDDIR}/pyo3-${_pyo3_version}" "${XBPS_BUILDDIR}/pyo3"
+}
+
+post_patch() {
+ # Apply patches for pyo3
+ cd "${XBPS_BUILDDIR}/pyo3"
+ for p in ${FILESDIR}/pyo3-patches/*.patch ; do
+ msg_normal "Applying ${p} to pyo3\n"
+ patch -Np1 -i ${p}
+ done
+}
+
+pre_build() {
+ mkdir -p dist
+ make prepare
+}
+
+do_build() {
+ RUSTFLAGS="-C target-feature=-crt-static" make build
+}
+
+do_install() {
+ pushd pylib
+ python3 setup.py install --prefix=/usr --root=${DESTDIR}
+ popd
+
+ pushd qt
+ python3 setup.py install --prefix=/usr --root=${DESTDIR}
+ popd
+
+ # maturin generates a .whl, this is all we can do
+ PIP_CONFIG_FILE=/dev/null pip3 install --isolated --root=${DESTDIR} --prefix=/usr --ignore-installed --no-deps dist/ankirspy*.whl
+
+ # Copied from arch's PKGBUILD
+ install -Dm755 qt/runanki "${DESTDIR}/usr/bin/anki"
+ install -Dm644 qt/anki.desktop "${DESTDIR}/usr/share/applications/anki.desktop"
+ install -Dm644 qt/anki.png "${DESTDIR}/usr/share/pixmaps/anki.png"
+}
+
post_install() {
vlicense LICENSE
}
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: WIP: anki: update to 2.1.26
2020-05-23 6:18 [PR PATCH] WIP: anki: update to 2.1.26 fosslinux
` (7 preceding siblings ...)
2020-06-01 10:05 ` [PR PATCH] [Updated] " fosslinux
@ 2020-06-01 10:28 ` fosslinux
2020-06-01 12:05 ` stpx
` (3 subsequent siblings)
12 siblings, 0 replies; 14+ messages in thread
From: fosslinux @ 2020-06-01 10:28 UTC (permalink / raw)
To: ml
[-- Attachment #1: Type: text/plain, Size: 285 bytes --]
New comment by fosslinux on void-packages repository
https://github.com/void-linux/void-packages/pull/22219#issuecomment-636769476
Comment:
@stpx Since this has pretty much morphed into a different, much more complex package, would you mind if I took maintainership of this package?
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: WIP: anki: update to 2.1.26
2020-05-23 6:18 [PR PATCH] WIP: anki: update to 2.1.26 fosslinux
` (8 preceding siblings ...)
2020-06-01 10:28 ` fosslinux
@ 2020-06-01 12:05 ` stpx
2020-12-23 1:33 ` [PR PATCH] [Closed]: " fosslinux
` (2 subsequent siblings)
12 siblings, 0 replies; 14+ messages in thread
From: stpx @ 2020-06-01 12:05 UTC (permalink / raw)
To: ml
[-- Attachment #1: Type: text/plain, Size: 708 bytes --]
New comment by stpx on void-packages repository
https://github.com/void-linux/void-packages/pull/22219#issuecomment-636819582
Comment:
Yes
On Mon, Jun 1, 2020, 6:28 AM fosslinux <notifications@github.com> wrote:
> @stpx <https://github.com/stpx> Since this has pretty much morphed into a
> different, much more complex package, would you mind if I took
> maintainership of this package?
>
> —
> You are receiving this because you were mentioned.
> Reply to this email directly, view it on GitHub
> <https://github.com/void-linux/void-packages/pull/22219#issuecomment-636769476>,
> or unsubscribe
> <https://github.com/notifications/unsubscribe-auth/AA4QBBOZCGOT5TG3MIIXYS3RUN7EBANCNFSM4NIKDL6A>
> .
>
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PR PATCH] [Closed]: WIP: anki: update to 2.1.26
2020-05-23 6:18 [PR PATCH] WIP: anki: update to 2.1.26 fosslinux
` (9 preceding siblings ...)
2020-06-01 12:05 ` stpx
@ 2020-12-23 1:33 ` fosslinux
2021-05-19 14:54 ` ericonr
2021-05-19 16:12 ` sgn
12 siblings, 0 replies; 14+ messages in thread
From: fosslinux @ 2020-12-23 1:33 UTC (permalink / raw)
To: ml
[-- Attachment #1: Type: text/plain, Size: 1831 bytes --]
There's a closed pull request on the void-packages repository
WIP: anki: update to 2.1.26
https://github.com/void-linux/void-packages/pull/22219
Description:
This has a wide variety of changes as if you have heard my ranting in #xbps it has turned into a Bad Build System - there is rust, nodejs, python, etc etc, no proper install target...
A few things to note:
- python3-mypy is updated as mypy-protobuf needs the new version, otherwise the build failed.
- same thing with python-protobuf, but for anki and at runtime
- maturin is some weird build system at the intersection of rust and python.
- mypy-protobuf-python is what anki uses for binding python and rust together, partly.
- mypy-protobuf-go is the go implementation of mypy-protobuf-python that I thought should be packaged anywway.
- python-stringcase is a new dependency.
- anki is an archd package (not nocross), because the rust code is obviously platform specific.
Still todo:
- [x] Apply archlinux's aqt_build patch, which stops it from polluting /usr directly (:vomiting_face:)
- [x] Update python3-protobuf - hopefully will fix `AttributeError: module 'google.protobuf.descriptor' has no attribute '_internal_create_key'`.
- [x] Look into travis musl error. https://github.com/rust-lang/rust/issues/40174. Hopefully, using rust 1.44 as the rust version *should* fix this. What a PITA. I understand that this is because it works when I cross-compile to x86_64-musl from x86_64 but we need it to work native build from x86_64-musl for the builders...
- [x] Get off rustup and onto rust stable. Needs either a) pyo3 to work on stable or b) anki to be patched for rust-cpython.
- [x] Blocked by rust 1.44. Blocked by #22739
- [ ] Travis wth on i686?
- [x] Make it open.
- [x] More extensive runtime testing.
- [ ] Runtime test on musl.
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: WIP: anki: update to 2.1.26
2020-05-23 6:18 [PR PATCH] WIP: anki: update to 2.1.26 fosslinux
` (10 preceding siblings ...)
2020-12-23 1:33 ` [PR PATCH] [Closed]: " fosslinux
@ 2021-05-19 14:54 ` ericonr
2021-05-19 16:12 ` sgn
12 siblings, 0 replies; 14+ messages in thread
From: ericonr @ 2021-05-19 14:54 UTC (permalink / raw)
To: ml
[-- Attachment #1: Type: text/plain, Size: 229 bytes --]
New comment by ericonr on void-packages repository
https://github.com/void-linux/void-packages/pull/22219#issuecomment-844184088
Comment:
@fosslinux we supposedly have working maturin in repos now, if you want to try it again?
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: WIP: anki: update to 2.1.26
2020-05-23 6:18 [PR PATCH] WIP: anki: update to 2.1.26 fosslinux
` (11 preceding siblings ...)
2021-05-19 14:54 ` ericonr
@ 2021-05-19 16:12 ` sgn
12 siblings, 0 replies; 14+ messages in thread
From: sgn @ 2021-05-19 16:12 UTC (permalink / raw)
To: ml
[-- Attachment #1: Type: text/plain, Size: 238 bytes --]
New comment by sgn on void-packages repository
https://github.com/void-linux/void-packages/pull/22219#issuecomment-844254110
Comment:
The situation has been changed. Last I check, anki has been moved to bazel, which is another monster.
^ permalink raw reply [flat|nested] 14+ messages in thread
end of thread, other threads:[~2021-05-19 16:12 UTC | newest]
Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-05-23 6:18 [PR PATCH] WIP: anki: update to 2.1.26 fosslinux
2020-05-23 7:07 ` [PR PATCH] [Updated] " fosslinux
2020-05-24 5:37 ` fosslinux
2020-05-24 5:39 ` fosslinux
2020-05-28 7:38 ` [PR PATCH] [Updated] " fosslinux
2020-05-30 1:53 ` fosslinux
2020-06-01 9:58 ` fosslinux
2020-06-01 9:59 ` fosslinux
2020-06-01 10:05 ` [PR PATCH] [Updated] " fosslinux
2020-06-01 10:28 ` fosslinux
2020-06-01 12:05 ` stpx
2020-12-23 1:33 ` [PR PATCH] [Closed]: " fosslinux
2021-05-19 14:54 ` ericonr
2021-05-19 16:12 ` sgn
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).