Pewarta Proxy

📋 Server Request & Proxy Logs

Loading active proxy settings...
Developed by Khairul Adha (adhexa.id)
Mengambil log server...

⚙️ Pengaturan Proxy Target

Skip to content

Raise clearer errors for constructor, mask, and attribute misuse - #606

Open
eriknw wants to merge 8 commits into
52-scalar-infix-literal-operandfrom
26-constructor-and-error-clarity
Open

eriknw wants to merge 8 commits into
52-scalar-infix-literal-operandfrom
26-constructor-and-error-clarity

Conversation

@eriknw

@eriknw eriknw commented Aug 4, 2026 •

Copy link
Copy Markdown
Member

Three error-message improvements for common misuses; no behavior change on
valid inputs.

  • Data passed to a constructor (5205629): Vector([1, 2, 3]) now
    raises 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.
  • Wrong-kind mask on a Matrix operation (713223a): a Vector mask on a
    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.
  • .new and .transpose accessed as attributes (54c1701): a
    BaseType.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 on
    the suitesparse backend: the info table sent every class other than Matrix
    itself down the TransposedMatrix path. They now show the matrix.
  • A failing GraphBLAS call on a Matrix or Vector subclass raised the right
    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 failing call on a transposed matrix (A.T.wait(), repr(A.T)) raised the
    right exception with the fallback text "Unable to get the error string for
    type TransposedMatrix. ...". Errors on A.T are now reported against A,
    with GraphBLAS's text.

Stack created with GitHub Stacks CLI • Give Feedback 💬

@eriknw eriknw changed the title 26 constructor and error clarity Raise clearer errors for constructor, mask, and attribute misuse Aug 4, 2026
@eriknw
eriknw marked this pull request as ready for review August 4, 2026 16:07
@eriknw
eriknw force-pushed the 26-constructor-and-error-clarity branch 2 times, most recently from fae7148 to f010e36 Compare August 5, 2026 00:06
@eriknw
eriknw force-pushed the 26-constructor-and-error-clarity branch from f010e36 to 9302620 Compare August 5, 2026 03:18
@eriknw
eriknw force-pushed the 26-constructor-and-error-clarity branch from 9302620 to 0984c49 Compare August 5, 2026 17:44
@eriknw
eriknw force-pushed the 26-constructor-and-error-clarity branch from 0984c49 to c1e43bc Compare August 5, 2026 18:03
@eriknw
eriknw force-pushed the 26-constructor-and-error-clarity branch from c1e43bc to 4b45803 Compare August 5, 2026 18:05
@eriknw
eriknw force-pushed the 26-constructor-and-error-clarity branch from 4b45803 to 50975fa Compare August 6, 2026 07:59
@eriknw
eriknw force-pushed the 26-constructor-and-error-clarity branch from 50975fa to c2ff5cb Compare August 6, 2026 15:39
@eriknw
eriknw force-pushed the 26-constructor-and-error-clarity branch from c2ff5cb to 7856374 Compare August 6, 2026 15:41
@eriknw
eriknw force-pushed the 26-constructor-and-error-clarity branch from 7856374 to 1cb3383 Compare August 6, 2026 20:36
@eriknw
eriknw force-pushed the 26-constructor-and-error-clarity branch from 1cb3383 to 8093367 Compare August 6, 2026 20:42
@eriknw
eriknw force-pushed the 26-constructor-and-error-clarity branch from 8093367 to ad024db Compare August 7, 2026 02:48
@eriknw
eriknw force-pushed the 26-constructor-and-error-clarity branch from ad024db to 951c957 Compare August 7, 2026 05:09
@eriknw
eriknw force-pushed the 26-constructor-and-error-clarity branch from 951c957 to 5fb20ec Compare August 26, 2026 17:30
@eriknw
eriknw force-pushed the 26-constructor-and-error-clarity branch from 5fb20ec to 859eb27 Compare September 18, 2026 03:09
@eriknw
eriknw force-pushed the 26-constructor-and-error-clarity branch from 1f46c54 to df3cf26 Compare September 26, 2026 05:23
@eriknw
eriknw force-pushed the 26-constructor-and-error-clarity branch 2 times, most recently from 6ad4bba to 9858c2e Compare September 27, 2026 15:40
@eriknw
eriknw force-pushed the 26-constructor-and-error-clarity branch 4 times, most recently from d9a364f to fa92588 Compare October 3, 2026 04:57
@eriknw
eriknw force-pushed the 26-constructor-and-error-clarity branch 2 times, most recently from 495cab1 to 909ea50 Compare October 4, 2026 06:21
@eriknw
eriknw removed this pull request from stack #634 October 8, 2026 21:02
@eriknw
eriknw force-pushed the 26-constructor-and-error-clarity branch from 909ea50 to b27b567 Compare October 8, 2026 21:40
@eriknw
eriknw added this pull request to stack #635 October 8, 2026 21:46
@eriknw
eriknw force-pushed the 26-constructor-and-error-clarity branch from b27b567 to b80a2b6 Compare October 9, 2026 03:06
@eriknw
eriknw force-pushed the 26-constructor-and-error-clarity branch 2 times, most recently from 55f53f7 to c23afb7 Compare October 14, 2026 18:45
@eriknw
eriknw removed this pull request from stack #635 October 19, 2026 07:45
@codecov

codecov Bot commented Oct 19, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 99.12%. Comparing base (ce63433) to head (cff5c94).

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:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

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.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant