Support Cython 3 (and also Python 3.13).
Description
Fixes the build on Python 3.13 (with Cython 3). Fixes #926 and fixes #947.
Types of change
Removal of Cython version restriction and a small fix.
Checklist
- [x] I confirm that I have the right to submit this contribution under the project's MIT license.
- [ ] I ran the tests, and all new and existing tests passed.
- [x] My changes don't require a change to the documentation, or if they do, I've added all required information.
It would also be neat to check the Cython 3.1 alpha release or Cython's master branch against free-threaded 3.13.
See https://py-free-threading.github.io for more info about supporting free-threaded Python in native code.
Any progress on getting this in and cutting a new release? Python 3.13 is now 4 months old.
I would be willing to test this in conda-forge (where we run the test suite anyway), but thinc depends on srsly, confection & wasabi, so those need to be solved first.
Xref https://github.com/conda-forge/srsly-feedstock/pull/53
I would be willing to test this in conda-forge (where we run the test suite anyway), but
thincdepends onsrsly,confection&wasabi, so those need to be solved first.
It seems that all of srsly, confection & wasabi now install under Python 3.13. Atleast in my environment.
I am getting lots of warnings while running tests under 3.13:
thinc/tests/layers/test_layers_api.py: 1594 warnings
thinc/tests/layers/test_lstm.py: 238 warnings
thinc/tests/layers/test_transforms.py: 296 warnings
thinc/tests/layers/test_with_transforms.py: 2508 warnings
thinc/tests/model/test_validation.py: 145 warnings
thinc/tests/test_config.py: 66 warnings
/tmp/virt/lib/python3.13/site-packages/pydantic/v1/typing.py:68: DeprecationWarning: Failing to pass a value to the 'type_params' parameter of 'typing.ForwardRef._evaluate' is deprecated, as it leads to incorrect behaviour when calling typing.ForwardRef._evaluate on a stringified annotation that references a PEP 695 type parameter. It will be disallowed in Python 3.15.
return cast(Any, type_)._evaluate(globalns, localns, recursive_guard=set())
Also some errors:
============================================================================================= short test summary info =============================================================================================
FAILED thinc/tests/backends/test_ops.py::test_ops_consistency[NumpyOps] - AssertionError: alloc
FAILED thinc/tests/layers/test_layers_api.py::test_layers_from_config[SparseLinear.v1-kwargs55-in_data55-out_data55] - NameError: name 'InT' is not defined
FAILED thinc/tests/layers/test_layers_api.py::test_layers_from_config[SparseLinear.v2-kwargs56-in_data56-out_data56] - NameError: name 'InT' is not defined
FAILED thinc/tests/layers/test_layers_api.py::test_layers_from_config[premap_ids.v1-kwargs59-in_data59-out_data59] - NameError: name 'InT' is not defined
FAILED thinc/tests/layers/test_layers_api.py::test_dropout[data2] - thinc.util.DataValidationError:
FAILED thinc/tests/layers/test_layers_api.py::test_layers_batching_all[premap_ids.v1-kwargs59-in_data59-out_data59] - NameError: name 'InT' is not defined
which expand out to this, and are clearly connected to the warning:
thinc/tests/layers/test_layers_api.py:211: in util_batch_unbatch_array
model.initialize(in_data, out_data)
thinc/model.py:316: in initialize
validate_fwd_input_output(self.name, self._func, X, Y)
thinc/util.py:588: in validate_fwd_input_output
ArgModel.update_forward_refs(**types.__dict__)
../virt/lib/python3.13/site-packages/pydantic/v1/main.py:814: in update_forward_refs
update_model_forward_refs(cls, cls.__fields__.values(), cls.__config__.json_encoders, localns)
../virt/lib/python3.13/site-packages/pydantic/v1/typing.py:559: in update_model_forward_refs
update_field_forward_refs(f, globalns=globalns, localns=localns)
../virt/lib/python3.13/site-packages/pydantic/v1/typing.py:525: in update_field_forward_refs
field.type_ = evaluate_forwardref(field.type_, globalns, localns or None)
../virt/lib/python3.13/site-packages/pydantic/v1/typing.py:68: in evaluate_forwardref
return cast(Any, type_)._evaluate(globalns, localns, recursive_guard=set())
/usr/lib/python3.13/typing.py:1081: in _evaluate
eval(self.__forward_code__, globalns, localns),
Seems to be an upstream pydantic issue: https://github.com/pydantic/pydantic/issues/9613
Pinging this. Could anyone have a look, fix the failing test and merge? It is blocking a lot of people depending on spacy.
requirements.txt should also be updated, since it's referenced in the README.
If no-one responds in a few more weeks, maybe email Explosion.
I tried this in https://github.com/conda-forge/thinc-feedstock/pull/126. On python <3.13, the test suite fails with:
=============================== warnings summary ===============================
$PREFIX/lib/python3.12/site-packages/thinc/tests/layers/test_mnist.py:81
$PREFIX/lib/python3.12/site-packages/thinc/tests/layers/test_mnist.py:81: PytestUnknownMarkWarning: Unknown pytest.mark.slow - is this a typo? You can register custom marks to avoid this warning - for details, see https://docs.pytest.org/en/stable/how-to/mark.html
@pytest.mark.slow
$PREFIX/lib/python3.12/site-packages/thinc/tests/regression/issue519/test_issue519.py:13
$PREFIX/lib/python3.12/site-packages/thinc/tests/regression/issue519/test_issue519.py:13: PytestUnknownMarkWarning: Unknown pytest.mark.slow - is this a typo? You can register custom marks to avoid this warning - for details, see https://docs.pytest.org/en/stable/how-to/mark.html
@pytest.mark.slow
tests/layers/test_shim.py::test_shim_can_roundtrip_with_path_subclass
tests/model/test_model.py::test_model_can_roundtrip_with_path_subclass
$PREFIX/lib/python3.12/site-packages/thinc/tests/conftest.py:54: PytestDeprecationWarning:
Module 'pathy' was found, but when imported by pytest it raised:
ImportError("cannot import name '_PosixFlavour' from 'pathlib' ($PREFIX/lib/python3.12/pathlib.py)")
In pytest 9.1 this warning will become an error by default.
You can fix the underlying problem, or alternatively overwrite this behavior and silence this warning by passing exc_type=ImportError explicitly.
See https://docs.pytest.org/en/stable/deprecations.html#pytest-importorskip-default-behavior-regarding-importerror
pytest.importorskip("pathy")
Docs: https://docs.pytest.org/en/stable/how-to/capture-warnings.html
=========================== short test summary info ============================
FAILED tests/backends/test_ops.py::test_ops_consistency[NumpyOps] - AssertionError: alloc
assert 'Shape' == 'typing.Tuple[int, ...]'
- typing.Tuple[int, ...]
+ Shape
FAILED tests/layers/test_layers_api.py::test_layers_from_config[SparseLinear.v1-kwargs55-in_data55-out_data55] - NameError: name 'InT' is not defined
FAILED tests/layers/test_layers_api.py::test_layers_from_config[SparseLinear.v2-kwargs56-in_data56-out_data56] - NameError: name 'InT' is not defined
FAILED tests/layers/test_layers_api.py::test_layers_from_config[premap_ids.v1-kwargs59-in_data59-out_data59] - NameError: name 'InT' is not defined
FAILED tests/layers/test_layers_api.py::test_dropout[data2] - thinc.util.DataValidationError:
Data validation error in 'dropout'
X: <class 'thinc.types.Padded'> Y: <class 'thinc.types.Padded'>
X not a valid numpy or cupy array
X not a valid numpy or cupy array
X not a valid numpy or cupy array
X not a valid numpy or cupy array
X not a valid numpy or cupy array
X not a valid numpy or cupy array
X not a valid numpy or cupy array
X not a valid numpy or cupy array
X value is not a valid sequence
X instance of Ragged, tuple or dict expected
X -> size_at_t wrong array data type (expected int32/int64/uint32/uint64, got float32)
Y -> 0 not a valid numpy or cupy array
Y -> 0 not a valid numpy or cupy array
Y -> 0 not a valid numpy or cupy array
Y -> 0 not a valid numpy or cupy array
Y -> 0 not a valid numpy or cupy array
Y -> 0 not a valid numpy or cupy array
Y -> 0 not a valid numpy or cupy array
Y -> 0 not a valid numpy or cupy array
Y -> 0 value is not a valid sequence
Y -> 0 instance of Ragged, tuple or dict expected
Y -> 0 -> size_at_t wrong array data type (expected int32/int64/uint32/uint64, got float32)
FAILED tests/layers/test_layers_api.py::test_layers_batching_all[premap_ids.v1-kwargs59-in_data59-out_data59] - NameError: name 'InT' is not defined
=========== 6 failed, 1219 passed, 119 skipped, 4 warnings in 11.81s ===========
For 3.13, we'd also need to lift the cap here https://github.com/explosion/thinc/blob/256e403d027c63422742f01bc01fcf9ced7acc4f/setup.cfg#L37 because we only have 3.13 builds for blis>=1.1 (though it's technically possible to backport this to 1.0, that makes no sense IMO in terms of policy).
I can confirm that this PR allows to build thinc on Arch Linux with Python 3.13
But for tests also need this change
diff --git i/thinc/tests/layers/test_linear.py w/thinc/tests/layers/test_linear.py
index 345669d8..d91061a4 100644
--- i/thinc/tests/layers/test_linear.py
+++ w/thinc/tests/layers/test_linear.py
@@ -1,7 +1,7 @@
import numpy
import pytest
from hypothesis import given, settings
-from mock import MagicMock
+from unittest.mock import MagicMock
from numpy.testing import assert_allclose
from thinc.api import SGD, Dropout, Linear, chain
diff --git i/thinc/tests/layers/test_with_debug.py w/thinc/tests/layers/test_with_debug.py
index 3f65a3ac..3e31c71f 100644
--- i/thinc/tests/layers/test_with_debug.py
+++ w/thinc/tests/layers/test_with_debug.py
@@ -1,4 +1,4 @@
-from mock import MagicMock
+from unittest.mock import MagicMock
from thinc.api import Linear, with_debug
I can confirm that this PR allows to build
thincon Arch Linux with Python 3.13But for tests also need this change
diff --git i/thinc/tests/layers/test_linear.py w/thinc/tests/layers/test_linear.py index 345669d8..d91061a4 100644 --- i/thinc/tests/layers/test_linear.py +++ w/thinc/tests/layers/test_linear.py @@ -1,7 +1,7 @@ import numpy import pytest from hypothesis import given, settings -from mock import MagicMock +from unittest.mock import MagicMock from numpy.testing import assert_allclose from thinc.api import SGD, Dropout, Linear, chain diff --git i/thinc/tests/layers/test_with_debug.py w/thinc/tests/layers/test_with_debug.py index 3f65a3ac..3e31c71f 100644 --- i/thinc/tests/layers/test_with_debug.py +++ w/thinc/tests/layers/test_with_debug.py @@ -1,4 +1,4 @@ -from mock import MagicMock +from unittest.mock import MagicMock from thinc.api import Linear, with_debug
Does this fix all of the test failures? I haven't had a chance to try.
It only fixes so that tests itself run.
There are some test failures but I'm not sure if they're due Python 3.13 as they might be because of some other reason.
==================================================================== FAILURES =====================================================================
_________________________________________________________ test_ops_consistency[NumpyOps] __________________________________________________________
op = <class 'thinc.backends.numpy_ops.NumpyOps'>
@pytest.mark.parametrize("op", [NumpyOps, CupyOps])
def test_ops_consistency(op):
"""Test that specific ops don't define any methods that are not on the
Ops base class and that all ops methods define the exact same arguments."""
attrs = [m for m in dir(op) if not m.startswith("_")]
for attr in attrs:
assert hasattr(Ops, attr)
method = getattr(op, attr)
if hasattr(method, "__call__"):
sig = inspect.signature(method)
params = [p for p in sig.parameters][1:]
base_sig = inspect.signature(getattr(Ops, attr))
base_params = [p for p in base_sig.parameters][1:]
assert params == base_params, attr
defaults = [p.default for p in sig.parameters.values()][1:]
base_defaults = [p.default for p in base_sig.parameters.values()][1:]
assert defaults == base_defaults, attr
# If args are type annotated, their types should be the same
annots = [p.annotation for p in sig.parameters.values()][1:]
base_annots = [p.annotation for p in base_sig.parameters.values()][1:]
for i, (p1, p2) in enumerate(zip(annots, base_annots)):
if p1 != inspect.Parameter.empty and p2 != inspect.Parameter.empty:
# Need to check string value to handle TypeVars etc.
> assert str(p1) == str(p2), attr
E AssertionError: alloc
E assert 'Shape' == 'typing.Tuple[int, ...]'
E
E - typing.Tuple[int, ...]
E + Shape
thinc/tests/backends/test_ops.py:155: AssertionError
_____________________________________ test_layers_from_config[SparseLinear.v1-kwargs55-in_data55-out_data55] ______________________________________
name = 'SparseLinear.v1', kwargs = {}, in_data = (array([1, 2, 3], dtype=uint64), array([1., 2., 3.], dtype=float32), array([1, 1], dtype=int32))
out_data = array([[4., 2., 3., 4.],
[1., 5., 3., 1.],
[9., 8., 5., 7.]], dtype=float32)
@pytest.mark.parametrize("name,kwargs,in_data,out_data", TEST_CASES)
def test_layers_from_config(name, kwargs, in_data, out_data):
cfg = {"@layers": name, **kwargs}
filled_cfg = registry.fill({"config": cfg})
assert srsly.is_json_serializable(filled_cfg)
model = registry.resolve({"config": cfg})["config"]
if "LSTM" in name:
model = with_padded(model)
valid = True
with data_validation(valid):
> model.initialize(in_data, out_data)
thinc/tests/layers/test_layers_api.py:153:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
thinc/model.py:316: in initialize
validate_fwd_input_output(self.name, self._func, X, Y)
thinc/util.py:588: in validate_fwd_input_output
ArgModel.update_forward_refs(**types.__dict__)
pydantic/v1/main.py:814: in update_forward_refs
update_model_forward_refs(cls, cls.__fields__.values(), cls.__config__.json_encoders, localns)
pydantic/v1/typing.py:559: in update_model_forward_refs
update_field_forward_refs(f, globalns=globalns, localns=localns)
pydantic/v1/typing.py:525: in update_field_forward_refs
field.type_ = evaluate_forwardref(field.type_, globalns, localns or None)
pydantic/v1/typing.py:68: in evaluate_forwardref
return cast(Any, type_)._evaluate(globalns, localns, recursive_guard=set())
typing.py:1081: in _evaluate
eval(self.__forward_code__, globalns, localns),
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
> ???
E NameError: name 'InT' is not defined
<string>:1: NameError
_____________________________________ test_layers_from_config[SparseLinear.v2-kwargs56-in_data56-out_data56] ______________________________________
name = 'SparseLinear.v2', kwargs = {}, in_data = (array([1, 2, 3], dtype=uint64), array([1., 2., 3.], dtype=float32), array([1, 1], dtype=int32))
out_data = array([[4., 2., 3., 4.],
[1., 5., 3., 1.],
[9., 8., 5., 7.]], dtype=float32)
@pytest.mark.parametrize("name,kwargs,in_data,out_data", TEST_CASES)
def test_layers_from_config(name, kwargs, in_data, out_data):
cfg = {"@layers": name, **kwargs}
filled_cfg = registry.fill({"config": cfg})
assert srsly.is_json_serializable(filled_cfg)
model = registry.resolve({"config": cfg})["config"]
if "LSTM" in name:
model = with_padded(model)
valid = True
with data_validation(valid):
> model.initialize(in_data, out_data)
thinc/tests/layers/test_layers_api.py:153:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
thinc/model.py:316: in initialize
validate_fwd_input_output(self.name, self._func, X, Y)
thinc/util.py:588: in validate_fwd_input_output
ArgModel.update_forward_refs(**types.__dict__)
pydantic/v1/main.py:814: in update_forward_refs
update_model_forward_refs(cls, cls.__fields__.values(), cls.__config__.json_encoders, localns)
pydantic/v1/typing.py:559: in update_model_forward_refs
update_field_forward_refs(f, globalns=globalns, localns=localns)
pydantic/v1/typing.py:525: in update_field_forward_refs
field.type_ = evaluate_forwardref(field.type_, globalns, localns or None)
pydantic/v1/typing.py:68: in evaluate_forwardref
return cast(Any, type_)._evaluate(globalns, localns, recursive_guard=set())
typing.py:1081: in _evaluate
eval(self.__forward_code__, globalns, localns),
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
> ???
E NameError: name 'InT' is not defined
<string>:1: NameError
______________________________________ test_layers_from_config[premap_ids.v1-kwargs59-in_data59-out_data59] _______________________________________
name = 'premap_ids.v1', kwargs = {'column': 1, 'mapping_table': {}}, in_data = array([[1, 4],
[2, 5],
[3, 6]])
out_data = array([[1, 2, 3],
[4, 5, 6]], dtype=int32)
@pytest.mark.parametrize("name,kwargs,in_data,out_data", TEST_CASES)
def test_layers_from_config(name, kwargs, in_data, out_data):
cfg = {"@layers": name, **kwargs}
filled_cfg = registry.fill({"config": cfg})
assert srsly.is_json_serializable(filled_cfg)
model = registry.resolve({"config": cfg})["config"]
if "LSTM" in name:
model = with_padded(model)
valid = True
with data_validation(valid):
> model.initialize(in_data, out_data)
thinc/tests/layers/test_layers_api.py:153:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
thinc/model.py:316: in initialize
validate_fwd_input_output(self.name, self._func, X, Y)
thinc/util.py:588: in validate_fwd_input_output
ArgModel.update_forward_refs(**types.__dict__)
pydantic/v1/main.py:814: in update_forward_refs
update_model_forward_refs(cls, cls.__fields__.values(), cls.__config__.json_encoders, localns)
pydantic/v1/typing.py:559: in update_model_forward_refs
update_field_forward_refs(f, globalns=globalns, localns=localns)
pydantic/v1/typing.py:525: in update_field_forward_refs
field.type_ = evaluate_forwardref(field.type_, globalns, localns or None)
pydantic/v1/typing.py:68: in evaluate_forwardref
return cast(Any, type_)._evaluate(globalns, localns, recursive_guard=set())
typing.py:1081: in _evaluate
eval(self.__forward_code__, globalns, localns),
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
> ???
E NameError: name 'InT' is not defined
<string>:1: NameError
_______________________________________________________________ test_dropout[data2] _______________________________________________________________
data = Padded(data=array([[[0., 0., 0.],
[0., 0., 0.],
[0., 0., 0.]],
[[0., 0., 0.],
[0., 0.,...array([1., 2., 3.], dtype=float32), lengths=array([1, 2, 3, 4], dtype=int32), indices=array([1, 2, 3, 4], dtype=int32))
@pytest.mark.parametrize("data", [array2d, ragged, padded, [array2d, array2d]])
def test_dropout(data):
model = Dropout(0.2)
> model.initialize(data, data)
thinc/tests/layers/test_layers_api.py:181:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
thinc/model.py:316: in initialize
validate_fwd_input_output(self.name, self._func, X, Y)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
name = 'dropout', func = <function forward at 0x7bd4ac549d00>
X = Padded(data=array([[[0., 0., 0.],
[0., 0., 0.],
[0., 0., 0.]],
[[0., 0., 0.],
[0., 0.,...array([1., 2., 3.], dtype=float32), lengths=array([1, 2, 3, 4], dtype=int32), indices=array([1, 2, 3, 4], dtype=int32))
Y = Padded(data=array([[[0., 0., 0.],
[0., 0., 0.],
[0., 0., 0.]],
[[0., 0., 0.],
[0., 0.,...array([1., 2., 3.], dtype=float32), lengths=array([1, 2, 3, 4], dtype=int32), indices=array([1, 2, 3, 4], dtype=int32))
def validate_fwd_input_output(
name: str, func: Callable[[Any, Any, bool], Any], X: Any, Y: Any
) -> None:
"""Validate the input and output of a forward function against the type
annotations, if available. Used in Model.initialize with the input and
output samples as they pass through the network.
"""
sig = inspect.signature(func)
empty = inspect.Signature.empty
params = list(sig.parameters.values())
if len(params) != 3:
bad_params = f"{len(params)} ({', '.join([p.name for p in params])})"
err = f"Invalid forward function. Expected 3 arguments (model, X , is_train), got {bad_params}"
raise DataValidationError(name, X, Y, [{"msg": err}])
annot_x = params[1].annotation
annot_y = sig.return_annotation
sig_args: Dict[str, Any] = {"__config__": _ArgModelConfig}
args = {}
if X is not None and annot_x != empty:
if isinstance(X, list) and len(X) > 5:
X = X[:5]
sig_args["X"] = (annot_x, ...)
args["X"] = X
if Y is not None and annot_y != empty:
if isinstance(Y, list) and len(Y) > 5:
Y = Y[:5]
sig_args["Y"] = (annot_y, ...)
args["Y"] = (Y, lambda x: x)
ArgModel = create_model("ArgModel", **sig_args)
# Make sure the forward refs are resolved and the types used by them are
# available in the correct scope. See #494 for details.
ArgModel.update_forward_refs(**types.__dict__)
try:
ArgModel.parse_obj(args)
except ValidationError as e:
> raise DataValidationError(name, X, Y, e.errors()) from None
E thinc.util.DataValidationError:
E
E Data validation error in 'dropout'
E X: <class 'thinc.types.Padded'> Y: <class 'thinc.types.Padded'>
E
E X not a valid numpy or cupy array
E X not a valid numpy or cupy array
E X not a valid numpy or cupy array
E X not a valid numpy or cupy array
E X not a valid numpy or cupy array
E X not a valid numpy or cupy array
E X not a valid numpy or cupy array
E X not a valid numpy or cupy array
E X value is not a valid sequence
E X instance of Ragged, tuple or dict expected
E X -> size_at_t wrong array data type (expected int32/int64/uint32/uint64, got float32)
E Y -> 0 not a valid numpy or cupy array
E Y -> 0 not a valid numpy or cupy array
E Y -> 0 not a valid numpy or cupy array
E Y -> 0 not a valid numpy or cupy array
E Y -> 0 not a valid numpy or cupy array
E Y -> 0 not a valid numpy or cupy array
E Y -> 0 not a valid numpy or cupy array
E Y -> 0 not a valid numpy or cupy array
E Y -> 0 value is not a valid sequence
E Y -> 0 instance of Ragged, tuple or dict expected
E Y -> 0 -> size_at_t wrong array data type (expected int32/int64/uint32/uint64, got float32)
thinc/util.py:592: DataValidationError
______________________________________ test_layers_batching_all[premap_ids.v1-kwargs59-in_data59-out_data59] ______________________________________
name = 'premap_ids.v1', kwargs = {'column': 1, 'mapping_table': {}}, in_data = array([[1, 4],
[2, 5],
[3, 6]])
out_data = array([[1, 2, 3],
[4, 5, 6]], dtype=int32)
@pytest.mark.parametrize("name,kwargs,in_data,out_data", TEST_CASES)
def test_layers_batching_all(name, kwargs, in_data, out_data):
cfg = {"@layers": name, **kwargs}
model = registry.resolve({"config": cfg})["config"]
if "expand_window" in name:
return
if "LSTM" in name:
model = with_padded(model)
util_batch_unbatch_list(model, in_data, out_data)
else:
if isinstance(in_data, OPS.xp.ndarray) and in_data.ndim == 2:
if isinstance(out_data, OPS.xp.ndarray) and out_data.ndim == 2:
> util_batch_unbatch_array(model, in_data, out_data)
thinc/tests/layers/test_layers_api.py:200:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
thinc/tests/layers/test_layers_api.py:211: in util_batch_unbatch_array
model.initialize(in_data, out_data)
thinc/model.py:316: in initialize
validate_fwd_input_output(self.name, self._func, X, Y)
thinc/util.py:588: in validate_fwd_input_output
ArgModel.update_forward_refs(**types.__dict__)
pydantic/v1/main.py:814: in update_forward_refs
update_model_forward_refs(cls, cls.__fields__.values(), cls.__config__.json_encoders, localns)
pydantic/v1/typing.py:559: in update_model_forward_refs
update_field_forward_refs(f, globalns=globalns, localns=localns)
pydantic/v1/typing.py:525: in update_field_forward_refs
field.type_ = evaluate_forwardref(field.type_, globalns, localns or None)
pydantic/v1/typing.py:68: in evaluate_forwardref
return cast(Any, type_)._evaluate(globalns, localns, recursive_guard=set())
typing.py:1081: in _evaluate
eval(self.__forward_code__, globalns, localns),
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
> ???
E NameError: name 'InT' is not defined
<string>:1: NameError
================================================================ warnings summary =================================================================
../..thinc/tests/layers/test_mnist.py:81
thinc/tests/layers/test_mnist.py:81: PytestUnknownMarkWarning: Unknown pytest.mark.slow - is this a typo? You can register custom marks to avoid this warning - for details, see https://docs.pytest.org/en/stable/how-to/mark.html
@pytest.mark.slow
../..thinc/tests/regression/issue519/test_issue519.py:13
thinc/tests/regression/issue519/test_issue519.py:13: PytestUnknownMarkWarning: Unknown pytest.mark.slow - is this a typo? You can register custom marks to avoid this warning - for details, see https://docs.pytest.org/en/stable/how-to/mark.html
@pytest.mark.slow
tests/backends/test_ops.py: 80 warnings
thinc/tests/backends/test_ops.py:1541: DeprecationWarning: Conversion of an array with ndim > 0 to a scalar is deprecated, and will error in future. Ensure you extract a single element from your array before performing this operation. (Deprecated NumPy 1.25.)
assert ops.xp.isclose(x_torch.grad.item() * dY, float(dx_thinc), atol=1e-06)
tests/backends/test_ops.py: 360 warnings
thinc/tests/backends/test_ops.py:1549: DeprecationWarning: Conversion of an array with ndim > 0 to a scalar is deprecated, and will error in future. Ensure you extract a single element from your array before performing this operation. (Deprecated NumPy 1.25.)
x_torch.grad.item() * dY, float(backward(dY_thinc, X=x_thinc)), atol=1e-06
tests/backends/test_ops.py: 40 warnings
thinc/tests/backends/test_ops.py:1533: DeprecationWarning: Conversion of an array with ndim > 0 to a scalar is deprecated, and will error in future. Ensure you extract a single element from your array before performing this operation. (Deprecated NumPy 1.25.)
assert ops.xp.isclose(x_torch.grad.item() * dY, float(dx_thinc), atol=1e-06)
tests/layers/test_layers_api.py: 1746 warnings
tests/layers/test_lstm.py: 238 warnings
tests/layers/test_transforms.py: 296 warnings
tests/layers/test_with_transforms.py: 2508 warnings
tests/model/test_validation.py: 145 warnings
tests/test_config.py: 66 warnings
pydantic/v1/typing.py:68: DeprecationWarning: Failing to pass a value to the 'type_params' parameter of 'typing.ForwardRef._evaluate' is deprecated, as it leads to incorrect behaviour when calling typing.ForwardRef._evaluate on a stringified annotation that references a PEP 695 type parameter. It will be disallowed in Python 3.15.
return cast(Any, type_)._evaluate(globalns, localns, recursive_guard=set())
-- Docs: https://docs.pytest.org/en/stable/how-to/capture-warnings.html
============================================================= short test summary info =============================================================
FAILED tests/backends/test_ops.py::test_ops_consistency[NumpyOps] - AssertionError: alloc
FAILED tests/layers/test_layers_api.py::test_layers_from_config[SparseLinear.v1-kwargs55-in_data55-out_data55] - NameError: name 'InT' is not defined
FAILED tests/layers/test_layers_api.py::test_layers_from_config[SparseLinear.v2-kwargs56-in_data56-out_data56] - NameError: name 'InT' is not defined
FAILED tests/layers/test_layers_api.py::test_layers_from_config[premap_ids.v1-kwargs59-in_data59-out_data59] - NameError: name 'InT' is not defined
FAILED tests/layers/test_layers_api.py::test_dropout[data2] - thinc.util.DataValidationError:
FAILED tests/layers/test_layers_api.py::test_layers_batching_all[premap_ids.v1-kwargs59-in_data59-out_data59] - NameError: name 'InT' is not defined
=========================================== 6 failed, 1298 passed, 88 skipped, 5481 warnings in 22.47s ============================================
Thanks for attention on this. We've had a size restriction on PyPi that prevented releases on spaCy, and there's issues associated with Python 3.13 to do with the Pydantic usage for validation. I'm working on the update now.
We need to target the 8.3.x branch. That's the one spaCy uses.
I've been streaming some spaCy and ecosystem development to increase transparency, so you can see some of the issues around Pydantic in this stream: https://www.youtube.com/watch?v=TTEWWJ2PmZQ&list=PLBmcuObd5An5_iAxNYLJa_xWmNzsYce8c&index=1&t=2882s . I've had to work on a consulting project the last couple of weeks so I had to pause work on this, but I'm back on it now.
Guys any news on this? Lots of packages are depending on spaCy and it can't update to support for Py 3.13.
Not sure how the just-released spacy 3.8.7 works with python 3.13, given that it has a thinc>=8.3.4,<8.4.0 build requirement, and there's no 3.13 support for thinc yet... 🤔
PLEASE merge this PR so downstream dependencies like SpaCy (and my own projects) can finally use Python 3.13.
This PR is not really ready though. I verified that the test failures still happen and I do not have time to fix investigate them.
thinc v8.3.6 has been out for ~3 month with cython 3 & py313 support; the requirements file (on that branch) is not up to date though: https://github.com/explosion/thinc/blob/037c264eb7fc607387025f5dc6f68d738c972405/requirements.txt#L20
Interesting. Anyone knows, why this support is not in the master branch or the v9.x versions?
@J08nY The v9 branch is ahead of what spaCy is supporting, and the plan is actually to phase out Thinc in spaCy, so I haven't been keeping it updated. Basically the v8.3.x branch is the one that matters.
I see. So v8.3.x supports Python 3.13 and v9.x does not. And spaCy targets v8.3.x. So it may make sense to pick out the Python 3.13 support from the v8.3.x branch to main as well right? If that is possible. I will close this PR the, as it really does not do much and people should just use v8.3.x then.