Repository navigation
Conversation
eriknw
marked this pull request as ready for review
August 4, 2026 16:07
eriknw
force-pushed
the
26-constructor-and-error-clarity
branch
2 times, most recently
from
August 5, 2026 00:06
fae7148 to
f010e36
Compare
eriknw
force-pushed
the
26-constructor-and-error-clarity
branch
from
August 5, 2026 03:18
f010e36 to
9302620
Compare
eriknw
force-pushed
the
26-constructor-and-error-clarity
branch
from
August 5, 2026 17:44
9302620 to
0984c49
Compare
eriknw
force-pushed
the
26-constructor-and-error-clarity
branch
from
August 5, 2026 18:03
0984c49 to
c1e43bc
Compare
eriknw
force-pushed
the
26-constructor-and-error-clarity
branch
from
August 5, 2026 18:05
c1e43bc to
4b45803
Compare
eriknw
force-pushed
the
26-constructor-and-error-clarity
branch
from
August 6, 2026 07:59
4b45803 to
50975fa
Compare
eriknw
force-pushed
the
26-constructor-and-error-clarity
branch
from
August 6, 2026 15:39
50975fa to
c2ff5cb
Compare
eriknw
force-pushed
the
26-constructor-and-error-clarity
branch
from
August 6, 2026 15:41
c2ff5cb to
7856374
Compare
eriknw
force-pushed
the
26-constructor-and-error-clarity
branch
from
August 6, 2026 20:36
7856374 to
1cb3383
Compare
eriknw
force-pushed
the
26-constructor-and-error-clarity
branch
from
August 6, 2026 20:42
1cb3383 to
8093367
Compare
eriknw
force-pushed
the
26-constructor-and-error-clarity
branch
from
August 7, 2026 02:48
8093367 to
ad024db
Compare
eriknw
force-pushed
the
26-constructor-and-error-clarity
branch
from
August 7, 2026 05:09
ad024db to
951c957
Compare
eriknw
force-pushed
the
26-constructor-and-error-clarity
branch
from
August 26, 2026 17:30
951c957 to
5fb20ec
Compare
eriknw
force-pushed
the
26-constructor-and-error-clarity
branch
from
September 18, 2026 03:09
5fb20ec to
859eb27
Compare
eriknw
force-pushed
the
26-constructor-and-error-clarity
branch
from
September 26, 2026 05:23
1f46c54 to
df3cf26
Compare
eriknw
force-pushed
the
26-constructor-and-error-clarity
branch
2 times, most recently
from
September 27, 2026 15:40
6ad4bba to
9858c2e
Compare
eriknw
force-pushed
the
26-constructor-and-error-clarity
branch
4 times, most recently
from
October 3, 2026 04:57
d9a364f to
fa92588
Compare
eriknw
force-pushed
the
26-constructor-and-error-clarity
branch
2 times, most recently
from
October 4, 2026 06:21
495cab1 to
909ea50
Compare
eriknw
force-pushed
the
26-constructor-and-error-clarity
branch
from
October 8, 2026 21:40
909ea50 to
b27b567
Compare
eriknw
force-pushed
the
26-constructor-and-error-clarity
branch
from
October 9, 2026 03:06
b27b567 to
b80a2b6
Compare
eriknw
force-pushed
the
26-constructor-and-error-clarity
branch
2 times, most recently
from
October 14, 2026 18:45
55f53f7 to
c23afb7
Compare
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## 52-scalar-infix-literal-operand #606 +/- ##
===================================================================
+ Coverage 98.65% 99.12% +0.46%
===================================================================
Files 105 105
Lines 29678 29828 +150
Branches 3472 3483 +11
===================================================================
+ Hits 29280 29567 +287
+ Misses 259 175 -84
+ Partials 139 86 -53 🚀 New features to boost your workflow:
|
Vector([1, 2, 3]) previously failed with "Unknown dtype: [1, 2, 3] of type <class 'list'>". The constructors take a dtype first, so passing data is a common newcomer mistake; now list/tuple/ndarray first arguments that fail dtype lookup raise a TypeError pointing to from_coo/from_dense. Valid list/tuple dtype specs (structured and subarray dtypes) still work: the hint only engages after lookup_dtype has rejected the argument. Other bad dtypes keep the original ValueError.
A Vector mask on a full-Matrix operation (ewise, extract, .new) leaked a raw cffi error, "initializer for ctype 'struct GB_Matrix_opaque'", which says nothing about masks. The Vector-output direction was already guarded; _check_mask now guards the Matrix-output direction the same way and reports "Mask object must be type Matrix; got ...". The check is gated behind a strict_kind flag rather than applied everywhere, because assignment is a genuine exception: a Vector mask on a Matrix row/column assign is valid, and Matrix.__setitem__ validates it separately. So strict_kind is False for __setitem__ updates and True for .new() and other full-tensor operations.
Two common misuses failed with a bare "no attribute" message that gave no
direction:
A.new() is the expression resolver, not an instance method
A.transpose() transpose is the .T property, not a method
A __getattr__ on BaseType supplies the hint on the attribute miss. It
raises AttributeError, exactly as before, so hasattr() and getattr() with a
default keep answering the way they did and duck-typing probes are
unaffected; only the message changes. Names with no hint keep the plain
message.
.new and .transpose ride in one commit because they are one mechanism: a
single __getattr__ consulting a single hint table. Splitting them would mean
adding the same function twice.
__getattr__ fires only on a genuine attribute miss, since slots and methods
resolve first, so the attribute hot path is untouched.
There is deliberately no class-level hint (Matrix.new): that needs a
metaclass, and both candidates break something real. A plain type
metaclass makes mixing Matrix into any abc-based class die with
"metaclass conflict", and an ABCMeta-derived one leaks register,
__abstractmethods__ and _abc_impl into dir(Matrix), which the
expression-surface guard rightly reports as drift. Class-level misuse
keeps Python's default AttributeError, and test_abc_mixin_subclass pins
the abc composition.
test_abc_mixin_subclass checked only issubclass, so the subclass's __len__ never ran. Make an instance and check that it is a Sized whose len is its nvals, 0 and then 2 after two stores (a __len__ that returned a constant would fail): the subclass must work as a Matrix and as the abc, not just be declared.
Behavior fix; main has it. The repr's info row picks the storage format with get_format(matrix) for a Matrix and from matrix._matrix for a TransposedMatrix, and it chose with type(matrix) is Matrix. Any subclass of Matrix took the TransposedMatrix branch, so on the suitesparse backend repr() and _repr_html_() raised AttributeError: 'Sub' object has no attribute '_matrix', for a plain subclass as for one with an abc mixin, and so did the reprs of its masks (A.S, ~A.V). Choose with _is_transposed, which Matrix and TransposedMatrix both define. The test checks that the repr and HTML repr of a subclass and of its structural and complemented value masks are a Matrix's but for the type's name, and that its .T is a TransposedMatrix whose reprs match a Matrix's .T; it fails before this with the AttributeError.
Behavior fix; main has it. check_status takes an error's text from GrB_<type name>_error, with the type's own name, and a subclass of Matrix or Vector has no such function. Any failing call on one, for example on a subclass instance whose data was exported with give_ownership=True, raised the right exception with check_status's fallback text, "Unable to get the error string for type SubMatrix. This is most likely a bug in graphblas. Please report this as an issue". A class without an error function of its own now uses that of the nearest base class in its MRO that has one. Only classes in graphblas.core count, which is where all eleven such types are: a user's mixin may share a GraphBLAS type's name, and listed first (a class Context mixed into a Vector) it would hand GxB_Context_error a GrB_Vector, which cffi rejects with a raw TypeError. A class with an error function of its own keeps it, and TransposedMatrix, which does not derive from Matrix, keeps the fallback. Two of graphblas's own classes change besides subclasses, for the better: BuiltinDescriptor and GlobalContext now get their C types' error text (Descriptor, Context) instead of the fallback. The test makes a failing call on a given-away subclass of Matrix, of Vector, and of Vector with such a Context mixin listed first, and checks the text is the base class's; it fails before this with the fallback text, and the mixin case with the TypeError without the graphblas.core filter.
Behavior fix; main has it. A TransposedMatrix shares Matrix.wait and Matrix._nvals, so when one of those calls failed, check_status was handed the TransposedMatrix and looked for GrB_TransposedMatrix_error, which GraphBLAS does not have. On a Matrix whose data was exported with give_ownership=True, A.T.wait() and repr(A.T) raised NullPointer with check_status's fallback text, "Unable to get the error string for type TransposedMatrix. This is most likely a bug in graphblas. Please report this as an issue", the same kind of message the previous commit fixed for subclasses. TransposedMatrix now gives its Matrix as _exc_arg, which check_status already uses in place of the object it is handed (as for _MatrixArray), so the error and its text are the Matrix's. The test checks that both calls raise NullPointer with A.wait()'s text; it fails before this with the fallback text.
With a TransposedMatrix now reporting against its Matrix, every object a failing call can hand check_status is a Matrix, Vector, Scalar, Descriptor or Context, or a subclass of one, so _error_type_name always finds a base with an error function. A graphblas.core class without one is passed over only for BuiltinDescriptor and GlobalContext, whose calls cannot fail: the global context engages and disengages any number of times, and builtin descriptors are never freed. Mark the skip and the no-match return "defensive", and say why in a comment.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Three error-message improvements for common misuses; no behavior change on
valid inputs.
Vector([1, 2, 3])nowraises a TypeError pointing at from_coo/from_dense instead of
"Unknown dtype: [1, 2, 3]". The hint engages only after lookup_dtype has
rejected the argument, so valid list/tuple dtype specs (structured and
subarray dtypes) still work.
full-Matrix operation now reports "Mask object must be type Matrix;
got ..." instead of leaking a raw cffi struct error. Assignment is exempt
via a strict_kind flag, because a Vector mask on a Matrix row/column
assign is valid and setitem validates it separately.
.newand.transposeaccessed as attributes (54c1701): aBaseType.getattr hint table points A.new() at << / .new-on-expressions
and A.transpose() at the .T property. It still raises AttributeError, so
hasattr/getattr probes are unaffected, and getattr fires only on a
genuine miss, so the attribute hot path is untouched.
Added in the 2026-10-20 coverage round
Three bug fixes in how a Matrix or Vector subclass, or a transposed matrix,
shows itself and reports errors (all on main too):
repr()and_repr_html_()of any Matrix subclass raised AttributeError onthe suitesparse backend: the info table sent every class other than Matrix
itself down the TransposedMatrix path. They now show the matrix.
exception with the fallback text "Unable to get the error string for type
SubMatrix. ... Please report this as an issue". The error
text is now found through the class hierarchy (graphblas classes only).
BuiltinDescriptor and GlobalContext now get the Descriptor and Context text.
A.T.wait(),repr(A.T)) raised theright exception with the fallback text "Unable to get the error string for
type TransposedMatrix. ...". Errors on
A.Tare now reported againstA,with GraphBLAS's text.
Stack created with GitHub Stacks CLI • Give Feedback 💬