From 3cbf74a712c16c10a357e231cfc9e80841e9ba8e Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 14 May 2026 07:58:28 +0000 Subject: [PATCH 01/16] [Autoloop: build-tsb-pandas-typescript-migration] Iteration 313: Add pd.errors module MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Port pandas pd.errors — full exception and warning hierarchy (31 classes). Run: https://github.com/githubnext/tsb/actions/runs/25848596047 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- playground/errors.html | 157 +++++++++++++++++++ src/errors.ts | 269 +++++++++++++++++++++++++++++++++ src/index.ts | 40 +++++ tests/errors.test.ts | 331 +++++++++++++++++++++++++++++++++++++++++ 4 files changed, 797 insertions(+) create mode 100644 playground/errors.html create mode 100644 src/errors.ts create mode 100644 tests/errors.test.ts diff --git a/playground/errors.html b/playground/errors.html new file mode 100644 index 00000000..4a92b883 --- /dev/null +++ b/playground/errors.html @@ -0,0 +1,157 @@ + + +
+ + +
+ tsb ships a full set of pandas-compatible exception and warning classes
+ under the errors namespace — mirroring Python's pd.errors.
+
| Class | Extends | When raised |
|---|---|---|
ValueError | TypeError | Invalid argument value |
KeyError | Error | Missing key or label |
IndexError | RangeError | Out-of-range index access |
ParserError | ValueError | File/string parsing fails |
EmptyDataError | Error | Reading an empty file |
MergeError | ValueError | Incorrect merge call |
UnsortedIndexError | KeyError | Unsorted MultiIndex slice |
OptionError | KeyError | Invalid option name/value |
OutOfBoundsDatetime | ValueError | Datetime outside nanosecond range |
OutOfBoundsTimedelta | ValueError | Timedelta outside range |
IntCastingNaNError | Error | Casting NaN to integer |
ChainedAssignmentError | Error | Chained assignment detected |
AbstractMethodError | Error | Calling an abstract method |
DtypeWarning | Error | Dtype mismatch on read |
PerformanceWarning | Error | Performance concern |
DatabaseError | Error | Database operation fails |
DataError | Error | GroupBy agg data error |
NullFrequencyError | ValueError | Null freq on period index |
SpecificationError | ValueError | Bad agg specification |
InvalidIndexError | Error | Label not in index |
InvalidComparison | TypeError | Incompatible type comparison |
import { ParserError, EmptyDataError, readCsv } from "tsb";
+
+try {
+ readCsv("");
+} catch (e) {
+ if (e instanceof EmptyDataError) {
+ console.log("File was empty:", e.message);
+ } else if (e instanceof ParserError) {
+ console.log("Parse failed:", e.message);
+ } else {
+ throw e;
+ }
+}
+
+ import { errors } from "tsb";
+
+// All error classes are available on the namespace
+const e = new errors.MergeError("incompatible merge keys");
+console.log(e instanceof errors.MergeError); // true
+console.log(e instanceof errors.ValueError); // true (MergeError extends ValueError)
+console.log(e.name); // "MergeError"
+
+ import { errors } from "tsb";
+
+class BaseProcessor {
+ process(): void {
+ throw new errors.AbstractMethodError("BaseProcessor.process");
+ }
+}
+
+class ConcreteProcessor extends BaseProcessor {
+ override process(): void {
+ console.log("Processing…");
+ }
+}
+
+// Base call raises
+try {
+ new BaseProcessor().process();
+} catch (e) {
+ console.log(e instanceof errors.AbstractMethodError); // true
+ console.log(e.message); // "This method must be defined in the concrete class: …"
+}
+
+ import { errors } from "tsb";
+
+// Raise when a write to a copy-of-slice is detected
+throw new errors.ChainedAssignmentError();
+// default message: "A value is trying to be set on a copy of a slice from a DataFrame"
+
+ import { errors } from "tsb";
+
+// These are raised by the datetime module when values exceed nanosecond range
+try {
+ // hypothetical: toDatetime("year 4000") with nanosecond precision
+} catch (e) {
+ if (e instanceof errors.OutOfBoundsDatetime) {
+ console.log("Datetime out of range:", e.message);
+ }
+}
+
+
+
+
+
+
diff --git a/src/errors.ts b/src/errors.ts
new file mode 100644
index 00000000..7c024386
--- /dev/null
+++ b/src/errors.ts
@@ -0,0 +1,269 @@
+/**
+ * `pd.errors` — pandas-compatible error and warning classes.
+ *
+ * Provides the full hierarchy of exceptions and warnings that pandas raises,
+ * adapted to TypeScript idioms. All classes extend native Error (or its
+ * subclasses) so they integrate naturally with `try/catch` and `instanceof`.
+ *
+ * @packageDocumentation
+ */
+
+// ---------------------------------------------------------------------------
+// Error classes
+// ---------------------------------------------------------------------------
+
+/** Raised when an abstract method is called that subclasses must override. */
+export class AbstractMethodError extends Error {
+ override readonly name = "AbstractMethodError";
+ constructor(classOrMethod: string) {
+ super(
+ `This method must be defined in the concrete class: ${classOrMethod}`,
+ );
+ }
+}
+
+/** Raised when there is a conflicting attribute during attribute access. */
+export class AttributeConflictWarning extends Error {
+ override readonly name = "AttributeConflictWarning";
+}
+
+/** Raised when CSS stylesheet parsing encounters a problem. */
+export class CSSWarning extends Error {
+ override readonly name = "CSSWarning";
+}
+
+/**
+ * Raised when chained assignment is detected.
+ * Equivalent to pandas `ChainedAssignmentError`.
+ */
+export class ChainedAssignmentError extends Error {
+ override readonly name = "ChainedAssignmentError";
+ constructor(message = "A value is trying to be set on a copy of a slice from a DataFrame") {
+ super(message);
+ }
+}
+
+/** Raised when there is a database-related error. */
+export class DatabaseError extends Error {
+ override readonly name = "DatabaseError";
+}
+
+/** Raised when a groupby aggregate operation encounters an error with the data. */
+export class DataError extends Error {
+ override readonly name = "DataError";
+}
+
+/**
+ * Warning raised when reading a file with mismatched dtypes.
+ * Equivalent to pandas `DtypeWarning`.
+ */
+export class DtypeWarning extends Error {
+ override readonly name = "DtypeWarning";
+}
+
+/** Raised when attempting to read an empty file. */
+export class EmptyDataError extends Error {
+ override readonly name = "EmptyDataError";
+ constructor(message = "No columns to parse from file") {
+ super(message);
+ }
+}
+
+/** Raised when casting to integer would lose data due to NaN values. */
+export class IntCastingNaNError extends Error {
+ override readonly name = "IntCastingNaNError";
+ constructor(message = "Cannot convert non-finite values (NA or inf) to integer") {
+ super(message);
+ }
+}
+
+/** Raised when an invalid column name is used. */
+export class InvalidColumnName extends Error {
+ override readonly name = "InvalidColumnName";
+}
+
+/** Raised when a comparison is attempted with incompatible types. */
+export class InvalidComparison extends TypeError {
+ override readonly name = "InvalidComparison";
+}
+
+/** Raised when an invalid label is used for indexing. */
+export class InvalidIndexError extends Error {
+ override readonly name = "InvalidIndexError";
+ constructor(message = "label not found in index") {
+ super(message);
+ }
+}
+
+/** Raised when a boolean index with an invalid shape is used. */
+export class InvalidUseOfBooleanIndex extends IndexError {
+ override readonly name = "InvalidUseOfBooleanIndex";
+}
+
+/** Raised when a version string cannot be parsed. */
+export class InvalidVersion extends ValueError {
+ override readonly name = "InvalidVersion";
+}
+
+/** Raised when a setitem operation would silently lose information. */
+export class LossySetitemError extends Error {
+ override readonly name = "LossySetitemError";
+}
+
+/** Raised when a merge operation is performed incorrectly. */
+export class MergeError extends ValueError {
+ override readonly name = "MergeError";
+}
+
+/** Raised when an operation requires a non-null frequency but the frequency is null. */
+export class NullFrequencyError extends ValueError {
+ override readonly name = "NullFrequencyError";
+ constructor(message = "Cannot have a null frequency with a non-trivial period index") {
+ super(message);
+ }
+}
+
+/** Raised when a Numba utility encounters an error. */
+export class NumbaUtilError extends Error {
+ override readonly name = "NumbaUtilError";
+}
+
+/** Raised when an invalid option is encountered. */
+export class OptionError extends KeyError {
+ override readonly name = "OptionError";
+}
+
+/** Raised when a datetime value is out of the supported range. */
+export class OutOfBoundsDatetime extends ValueError {
+ override readonly name = "OutOfBoundsDatetime";
+ constructor(message = "Out of bounds nanosecond timestamp") {
+ super(message);
+ }
+}
+
+/** Raised when a timedelta value is out of the supported range. */
+export class OutOfBoundsTimedelta extends ValueError {
+ override readonly name = "OutOfBoundsTimedelta";
+ constructor(message = "Out of bounds timedelta") {
+ super(message);
+ }
+}
+
+/** Raised when a file or string cannot be parsed. */
+export class ParserError extends ValueError {
+ override readonly name = "ParserError";
+}
+
+/** Warning raised when a parser falls back to a less-efficient parser. */
+export class ParserWarning extends Error {
+ override readonly name = "ParserWarning";
+}
+
+/** Warning raised when a performance issue is detected. */
+export class PerformanceWarning extends Error {
+ override readonly name = "PerformanceWarning";
+}
+
+/** Raised when writing to a file may result in data loss. */
+export class PossibleDataLossError extends Error {
+ override readonly name = "PossibleDataLossError";
+}
+
+/** Warning raised when floating-point precision loss may occur. */
+export class PossiblePrecisionLoss extends Error {
+ override readonly name = "PossiblePrecisionLoss";
+}
+
+/** Raised when there is a specification error in a groupby agg call. */
+export class SpecificationError extends ValueError {
+ override readonly name = "SpecificationError";
+}
+
+/** Raised when an unsorted MultiIndex is used in a way that requires sorting. */
+export class UnsortedIndexError extends KeyError {
+ override readonly name = "UnsortedIndexError";
+ constructor(message = "MultiIndex slicing requires the index to be lexsorted") {
+ super(message);
+ }
+}
+
+/** Raised when calling a function on an object that does not support it. */
+export class UnsupportedFunctionCall extends ValueError {
+ override readonly name = "UnsupportedFunctionCall";
+}
+
+/** Warning raised when accessor registration may shadow a built-in attribute. */
+export class AccessorRegistrationWarning extends Error {
+ override readonly name = "AccessorRegistrationWarning";
+}
+
+/** Raised when a value and label have mismatched types in a Categorical. */
+export class ValueLabelTypeMismatch extends Error {
+ override readonly name = "ValueLabelTypeMismatch";
+}
+
+// ---------------------------------------------------------------------------
+// Base error helpers used above (JavaScript does not have ValueError / KeyError
+// / IndexError natively, so we define lightweight stand-ins here that still
+// inherit from Error and therefore work with `instanceof Error`).
+// ---------------------------------------------------------------------------
+
+/** TypeError-compatible base for value-related errors (mirrors Python's ValueError). */
+export class ValueError extends TypeError {
+ override readonly name = "ValueError";
+}
+
+/** Error-compatible base for key-related errors (mirrors Python's KeyError). */
+export class KeyError extends Error {
+ override readonly name = "KeyError";
+}
+
+/** Error-compatible base for index-related errors (mirrors Python's IndexError). */
+export class IndexError extends RangeError {
+ override readonly name = "IndexError";
+}
+
+// ---------------------------------------------------------------------------
+// Namespace export (mirrors `pd.errors`)
+// ---------------------------------------------------------------------------
+
+/** All pandas-compatible error and warning classes, grouped as `pd.errors`. */
+export const errors = {
+ AbstractMethodError,
+ AccessorRegistrationWarning,
+ AttributeConflictWarning,
+ CSSWarning,
+ ChainedAssignmentError,
+ DatabaseError,
+ DataError,
+ DtypeWarning,
+ EmptyDataError,
+ IntCastingNaNError,
+ InvalidColumnName,
+ InvalidComparison,
+ InvalidIndexError,
+ InvalidUseOfBooleanIndex,
+ InvalidVersion,
+ LossySetitemError,
+ MergeError,
+ NullFrequencyError,
+ NumbaUtilError,
+ OptionError,
+ OutOfBoundsDatetime,
+ OutOfBoundsTimedelta,
+ ParserError,
+ ParserWarning,
+ PerformanceWarning,
+ PossibleDataLossError,
+ PossiblePrecisionLoss,
+ SpecificationError,
+ UnsortedIndexError,
+ UnsupportedFunctionCall,
+ ValueLabelTypeMismatch,
+ // base classes
+ ValueError,
+ KeyError,
+ IndexError,
+} as const;
+
+export type PandasError = InstanceType<(typeof errors)[keyof typeof errors]>;
diff --git a/src/index.ts b/src/index.ts
index a6180397..f1b07645 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -741,3 +741,43 @@ export {
seriesToLaTeX,
} from "./stats/format_table.ts";
export type { ToMarkdownOptions, ToLaTeXOptions } from "./stats/format_table.ts";
+
+// pd.errors — pandas-compatible error and warning classes
+export {
+ errors,
+ AbstractMethodError,
+ AccessorRegistrationWarning,
+ AttributeConflictWarning,
+ CSSWarning,
+ ChainedAssignmentError,
+ DatabaseError,
+ DataError,
+ DtypeWarning,
+ EmptyDataError,
+ IntCastingNaNError,
+ InvalidColumnName,
+ InvalidComparison,
+ InvalidIndexError,
+ InvalidUseOfBooleanIndex,
+ InvalidVersion,
+ LossySetitemError,
+ MergeError,
+ NullFrequencyError,
+ NumbaUtilError,
+ OptionError,
+ OutOfBoundsDatetime,
+ OutOfBoundsTimedelta,
+ ParserError,
+ ParserWarning,
+ PerformanceWarning,
+ PossibleDataLossError,
+ PossiblePrecisionLoss,
+ SpecificationError,
+ UnsortedIndexError,
+ UnsupportedFunctionCall,
+ ValueLabelTypeMismatch,
+ ValueError,
+ KeyError,
+ IndexError,
+} from "./errors.ts";
+export type { PandasError } from "./errors.ts";
diff --git a/tests/errors.test.ts b/tests/errors.test.ts
new file mode 100644
index 00000000..ab4de565
--- /dev/null
+++ b/tests/errors.test.ts
@@ -0,0 +1,331 @@
+/**
+ * Tests for pd.errors — pandas-compatible error and warning classes.
+ */
+import { describe, expect, test } from "bun:test";
+import {
+ AbstractMethodError,
+ AccessorRegistrationWarning,
+ AttributeConflictWarning,
+ CSSWarning,
+ ChainedAssignmentError,
+ DatabaseError,
+ DataError,
+ DtypeWarning,
+ EmptyDataError,
+ IndexError,
+ IntCastingNaNError,
+ InvalidColumnName,
+ InvalidComparison,
+ InvalidIndexError,
+ InvalidUseOfBooleanIndex,
+ InvalidVersion,
+ KeyError,
+ LossySetitemError,
+ MergeError,
+ NullFrequencyError,
+ NumbaUtilError,
+ OptionError,
+ OutOfBoundsDatetime,
+ OutOfBoundsTimedelta,
+ ParserError,
+ ParserWarning,
+ PerformanceWarning,
+ PossibleDataLossError,
+ PossiblePrecisionLoss,
+ SpecificationError,
+ UnsortedIndexError,
+ UnsupportedFunctionCall,
+ ValueError,
+ ValueLabelTypeMismatch,
+ errors,
+} from "../../src/index.ts";
+
+// ---------------------------------------------------------------------------
+// Helper: assert that a class is throwable and catchable
+// ---------------------------------------------------------------------------
+function assertThrowable
- tsb ships a full set of pandas-compatible exception and warning classes
- under the errors namespace — mirroring Python's pd.errors.
-
Pandas-compatible error and warning classes — mirrors Python's pd.errors module.
+ All classes extend native Error and integrate with try/catch and instanceof.
Three base classes mirror Python's built-in exceptions. They extend native JS error types so they + work with standard error-handling idioms.
+Use instanceof in catch blocks to handle specific error types — just like Python's
+ except SpecificError.
import { errors } from "tsb";
+
+ 3 — The errors namespace (pd.errors style)
+ All error classes are grouped under the errors namespace, mirroring
+ Python's pd.errors.ParserError etc.
+
+
+ TypeScript
+
+
+
+
+
+
+ Click ▶ Run to execute
+ Ctrl+Enter to run · Tab to indent
+
+
-class BaseProcessor {
- process(): void {
- throw new errors.AbstractMethodError("BaseProcessor.process");
+
+ 4 — AbstractMethodError for extension classes
+ AbstractMethodError is thrown when a subclass forgets to implement a required method —
+ mirroring Python's raise NotImplementedError.
+
+
+ TypeScript
+
+
+
+
+
+
+ Click ▶ Run to execute
+ Ctrl+Enter to run · Tab to indent
+
+
+
+
+
+
+
diff --git a/src/errors.ts b/src/errors.ts
index 7c024386..4032208e 100644
--- a/src/errors.ts
+++ b/src/errors.ts
@@ -8,6 +8,25 @@
* @packageDocumentation
*/
+// ---------------------------------------------------------------------------
+// Base error helpers (must be declared first so derived classes can extend them)
+// ---------------------------------------------------------------------------
+
+/** TypeError-compatible base for value-related errors (mirrors Python's ValueError). */
+export class ValueError extends TypeError {
+ override readonly name = "ValueError";
+}
+
+/** Error-compatible base for key-related errors (mirrors Python's KeyError). */
+export class KeyError extends Error {
+ override readonly name = "KeyError";
+}
+
+/** Error-compatible base for index-related errors (mirrors Python's IndexError). */
+export class IndexError extends RangeError {
+ override readonly name = "IndexError";
+}
+
// ---------------------------------------------------------------------------
// Error classes
// ---------------------------------------------------------------------------
@@ -202,27 +221,6 @@ export class ValueLabelTypeMismatch extends Error {
override readonly name = "ValueLabelTypeMismatch";
}
-// ---------------------------------------------------------------------------
-// Base error helpers used above (JavaScript does not have ValueError / KeyError
-// / IndexError natively, so we define lightweight stand-ins here that still
-// inherit from Error and therefore work with `instanceof Error`).
-// ---------------------------------------------------------------------------
-
-/** TypeError-compatible base for value-related errors (mirrors Python's ValueError). */
-export class ValueError extends TypeError {
- override readonly name = "ValueError";
-}
-
-/** Error-compatible base for key-related errors (mirrors Python's KeyError). */
-export class KeyError extends Error {
- override readonly name = "KeyError";
-}
-
-/** Error-compatible base for index-related errors (mirrors Python's IndexError). */
-export class IndexError extends RangeError {
- override readonly name = "IndexError";
-}
-
// ---------------------------------------------------------------------------
// Namespace export (mirrors `pd.errors`)
// ---------------------------------------------------------------------------
diff --git a/tests/errors.test.ts b/tests/errors.test.ts
index ab4de565..d916cb4d 100644
--- a/tests/errors.test.ts
+++ b/tests/errors.test.ts
@@ -38,7 +38,7 @@ import {
ValueError,
ValueLabelTypeMismatch,
errors,
-} from "../../src/index.ts";
+} from "../src/index.ts";
// ---------------------------------------------------------------------------
// Helper: assert that a class is throwable and catchable
@@ -47,7 +47,7 @@ function assertThrowable(
Cls: new (...args: never[]) => T,
args: ConstructorParameters,
expectedMessage?: string,
-): T {
+): void {
const instance = new Cls(...(args as ConstructorParameters));
expect(instance).toBeInstanceOf(Error);
expect(instance).toBeInstanceOf(Cls);
@@ -62,7 +62,6 @@ function assertThrowable(
caught = e;
}
expect(caught).toBeInstanceOf(Cls);
- return instance;
}
// ---------------------------------------------------------------------------
@@ -323,8 +322,10 @@ describe("errors namespace", () => {
});
test("all namespace entries are constructors", () => {
- for (const [key, Cls] of Object.entries(errors)) {
- const instance = new Cls(key);
+ const errorKeys = Object.keys(errors) as Array;
+ for (const key of errorKeys) {
+ const Cls = errors[key];
+ const instance = new Cls(key as never);
expect(instance).toBeInstanceOf(Error);
}
});
From 5bccf5b67d82a0d7237ece7b553147191ebfcacc Mon Sep 17 00:00:00 2001
From: "github-actions[bot]"
Date: Thu, 14 May 2026 08:14:48 +0000
Subject: [PATCH 04/16] ci: trigger checks
From dbe46c6184c3579d5fb1622e38f1f2c1f9552914 Mon Sep 17 00:00:00 2001
From: "github-actions[bot]"
<41898282+github-actions[bot]@users.noreply.github.com>
Date: Thu, 14 May 2026 09:16:05 +0000
Subject: [PATCH 05/16] fix: resolve TypeScript errors in errors.ts and
errors.test.ts
- Annotate base class name properties as string to allow subclass overrides
- Fix assertThrowable generic signature to accept typed constructor args
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
---
src/errors.ts | 6 +++---
tests/errors.test.ts | 8 ++++----
2 files changed, 7 insertions(+), 7 deletions(-)
diff --git a/src/errors.ts b/src/errors.ts
index 4032208e..f2dbbe1f 100644
--- a/src/errors.ts
+++ b/src/errors.ts
@@ -14,17 +14,17 @@
/** TypeError-compatible base for value-related errors (mirrors Python's ValueError). */
export class ValueError extends TypeError {
- override readonly name = "ValueError";
+ override readonly name: string = "ValueError";
}
/** Error-compatible base for key-related errors (mirrors Python's KeyError). */
export class KeyError extends Error {
- override readonly name = "KeyError";
+ override readonly name: string = "KeyError";
}
/** Error-compatible base for index-related errors (mirrors Python's IndexError). */
export class IndexError extends RangeError {
- override readonly name = "IndexError";
+ override readonly name: string = "IndexError";
}
// ---------------------------------------------------------------------------
diff --git a/tests/errors.test.ts b/tests/errors.test.ts
index d916cb4d..534e7f72 100644
--- a/tests/errors.test.ts
+++ b/tests/errors.test.ts
@@ -43,12 +43,12 @@ import {
// ---------------------------------------------------------------------------
// Helper: assert that a class is throwable and catchable
// ---------------------------------------------------------------------------
-function assertThrowable(
- Cls: new (...args: never[]) => T,
- args: ConstructorParameters,
+function assertThrowable(
+ Cls: new (...args: A) => T,
+ args: A,
expectedMessage?: string,
): void {
- const instance = new Cls(...(args as ConstructorParameters));
+ const instance = new Cls(...args);
expect(instance).toBeInstanceOf(Error);
expect(instance).toBeInstanceOf(Cls);
if (expectedMessage !== undefined) {
From 275296d54bd20ad0aaf8bb2ea6b154bb3756389e Mon Sep 17 00:00:00 2001
From: "github-actions[bot]"
Date: Thu, 14 May 2026 09:16:07 +0000
Subject: [PATCH 06/16] ci: trigger checks
From eb6c354ad1567f9e5cefc235eeecb222683528b4 Mon Sep 17 00:00:00 2001
From: "github-actions[bot]"
<41898282+github-actions[bot]@users.noreply.github.com>
Date: Thu, 14 May 2026 10:06:26 +0000
Subject: [PATCH 07/16] fix: resolve biome lint errors in align.ts, astype.ts,
and pd_array.ts
- align.ts: add default case to switch in resolveIndex; flatten nested ternary in normalised axis computation
- astype.ts: extract helper functions to reduce cognitive complexity of castScalar
- pd_array.ts: wrap single-line if statements in block statements
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
---
src/core/align.ts | 12 +++++-
src/core/astype.ts | 96 ++++++++++++++++++--------------------------
src/core/pd_array.ts | 14 +++----
3 files changed, 57 insertions(+), 65 deletions(-)
diff --git a/src/core/align.ts b/src/core/align.ts
index 144f53b5..ebda596e 100644
--- a/src/core/align.ts
+++ b/src/core/align.ts
@@ -92,6 +92,8 @@ function resolveIndex(left: Index