Skip to content

fix(framework): split Output TypeVar into Output and Expected - #243

Merged
Abhijeet Prasad (AbhiPrasad) merged 3 commits into
mainfrom
fix/eval-expected-typevar
Apr 10, 2026
Merged

fix(framework): split Output TypeVar into Output and Expected#243
Abhijeet Prasad (AbhiPrasad) merged 3 commits into
mainfrom
fix/eval-expected-typevar

Conversation

@AbhiPrasad

Copy link
Copy Markdown
Member

resolves#240

The Eval generic Output parameter was shared across three positions: task return type, EvalCase.expected, and scorer args. When the expected data type differs from the task output (e.g. assertion specs vs model output), type checkers reject the call because Output can't unify.

Introduce a separate Expected TypeVar so data binds Expected and task binds Output independently. Add a test_types nox session that runs pyright, mypy, and pytest on py/src/braintrust/type_tests/.

Nova (SFK)and others added 2 commits April 9, 2026 22:48
…240)
The `Eval` generic `Output` parameter was shared across three positions:
task return type, `EvalCase.expected`, and scorer args. When the expected
data type differs from the task output (e.g. assertion specs vs model
output), type checkers reject the call because `Output` can't unify.
Introduce a separate `Expected` TypeVar so `data` binds `Expected` and
`task` binds `Output` independently. Add a `test_types` nox session that
runs pyright, mypy, and pytest on `py/src/braintrust/type_tests/`.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Pin to pyright==1.1.408 and mypy==1.20.0 to avoid flaky CI from
upstream type checker releases introducing stricter checks.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Evaluator is now Generic[Input, Output, Expected] after the TypeVar
split. Python 3.10 enforces generic param counts at runtime, so the
2-param Evaluator[Any, Any] in server.py caused a TypeError on import.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@AbhiPrasad
Abhijeet Prasad (AbhiPrasad) merged commit f2412f0 into mainApr 10, 2026
59 checks passed
@AbhiPrasad
Abhijeet Prasad (AbhiPrasad) deleted the fix/eval-expected-typevar branch April 10, 2026 01:09
Abhijeet Prasad (AbhiPrasad) added a commit that referenced this pull request Apr 10, 2026
Sign up for freeto 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.

Eval generic Output parameter can't unify when expected and task return type differ

2 participants

@AbhiPrasad@realark
, 'i'); if (__m === '*' || __re.test(location.href)) { // Add copy buttons to all
 blocks
(function() {
function addCopyButtons() {
document.querySelectorAll('pre code').forEach(function(codeBlock) {
if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;
codeBlock.parentElement.setAttribute('data-copy-added', 'true');
var btn = document.createElement('button');
btn.textContent = 'Copy';
btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';
btn.onmouseover = function() { this.style.opacity = '1'; };
btn.onmouseout = function() { this.style.opacity = '0.7'; };
btn.onclick = function() {
navigator.clipboard.writeText(codeBlock.textContent).then(function() {
btn.textContent = 'Copied!';
setTimeout(function() { btn.textContent = 'Copy'; }, 1500);
});
};
codeBlock.parentElement.style.position = 'relative';
codeBlock.parentElement.appendChild(btn);
});
}
addCopyButtons();
// Re-run on dynamic content
var observer = new MutationObserver(addCopyButtons);
observer.observe(document.body, { childList: true, subtree: true });
})();
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
fix(framework): split `Output` TypeVar into `Output` and `Expected` by AbhiPrasad · Pull Request #243 · braintrustdata/braintrust-sdk-python · GitHub
Skip to content

fix(framework): split Output TypeVar into Output and Expected - #243

Merged
Abhijeet Prasad (AbhiPrasad) merged 3 commits into
mainfrom
fix/eval-expected-typevar
Apr 10, 2026
Merged

fix(framework): split Output TypeVar into Output and Expected#243
Abhijeet Prasad (AbhiPrasad) merged 3 commits into
mainfrom
fix/eval-expected-typevar

Conversation

@AbhiPrasad

Copy link
Copy Markdown
Member

resolves#240

The Eval generic Output parameter was shared across three positions: task return type, EvalCase.expected, and scorer args. When the expected data type differs from the task output (e.g. assertion specs vs model output), type checkers reject the call because Output can't unify.

Introduce a separate Expected TypeVar so data binds Expected and task binds Output independently. Add a test_types nox session that runs pyright, mypy, and pytest on py/src/braintrust/type_tests/.

Nova (SFK)and others added 2 commits April 9, 2026 22:48
…240)
The `Eval` generic `Output` parameter was shared across three positions:
task return type, `EvalCase.expected`, and scorer args. When the expected
data type differs from the task output (e.g. assertion specs vs model
output), type checkers reject the call because `Output` can't unify.
Introduce a separate `Expected` TypeVar so `data` binds `Expected` and
`task` binds `Output` independently. Add a `test_types` nox session that
runs pyright, mypy, and pytest on `py/src/braintrust/type_tests/`.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Pin to pyright==1.1.408 and mypy==1.20.0 to avoid flaky CI from
upstream type checker releases introducing stricter checks.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Evaluator is now Generic[Input, Output, Expected] after the TypeVar
split. Python 3.10 enforces generic param counts at runtime, so the
2-param Evaluator[Any, Any] in server.py caused a TypeError on import.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@AbhiPrasad
Abhijeet Prasad (AbhiPrasad) merged commit f2412f0 into mainApr 10, 2026
59 checks passed
@AbhiPrasad
Abhijeet Prasad (AbhiPrasad) deleted the fix/eval-expected-typevar branch April 10, 2026 01:09
Abhijeet Prasad (AbhiPrasad) added a commit that referenced this pull request Apr 10, 2026
Sign up for freeto 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.

Eval generic Output parameter can't unify when expected and task return type differ

2 participants

@AbhiPrasad@realark
, 'i'); if (__m === '*' || __re.test(location.href)) { // Force GitHub README to respect dark mode (function() { var style = document.createElement('style'); style.textContent = ' .markdown-body { color-scheme: dark light; } .markdown-body pre { background: #161b22 !important; } .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; } .markdown-body table th, .markdown-body table td { border-color: #30363d !important; } .markdown-body img { background: #0d1117; } .markdown-body blockquote { border-left-color: #8b949e; } .markdown-body hr { border-color: #30363d; } '; document.head.appendChild(style); })(); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' fix(framework): split `Output` TypeVar into `Output` and `Expected` by AbhiPrasad · Pull Request #243 · braintrustdata/braintrust-sdk-python · GitHub
Skip to content

fix(framework): split Output TypeVar into Output and Expected - #243

Merged
Abhijeet Prasad (AbhiPrasad) merged 3 commits into
mainfrom
fix/eval-expected-typevar
Apr 10, 2026
Merged

fix(framework): split Output TypeVar into Output and Expected#243
Abhijeet Prasad (AbhiPrasad) merged 3 commits into
mainfrom
fix/eval-expected-typevar

Conversation

@AbhiPrasad

Copy link
Copy Markdown
Member

resolves#240

The Eval generic Output parameter was shared across three positions: task return type, EvalCase.expected, and scorer args. When the expected data type differs from the task output (e.g. assertion specs vs model output), type checkers reject the call because Output can't unify.

Introduce a separate Expected TypeVar so data binds Expected and task binds Output independently. Add a test_types nox session that runs pyright, mypy, and pytest on py/src/braintrust/type_tests/.

Nova (SFK)and others added 2 commits April 9, 2026 22:48
…240)
The `Eval` generic `Output` parameter was shared across three positions:
task return type, `EvalCase.expected`, and scorer args. When the expected
data type differs from the task output (e.g. assertion specs vs model
output), type checkers reject the call because `Output` can't unify.
Introduce a separate `Expected` TypeVar so `data` binds `Expected` and
`task` binds `Output` independently. Add a `test_types` nox session that
runs pyright, mypy, and pytest on `py/src/braintrust/type_tests/`.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Pin to pyright==1.1.408 and mypy==1.20.0 to avoid flaky CI from
upstream type checker releases introducing stricter checks.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Evaluator is now Generic[Input, Output, Expected] after the TypeVar
split. Python 3.10 enforces generic param counts at runtime, so the
2-param Evaluator[Any, Any] in server.py caused a TypeError on import.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@AbhiPrasad
Abhijeet Prasad (AbhiPrasad) merged commit f2412f0 into mainApr 10, 2026
59 checks passed
@AbhiPrasad
Abhijeet Prasad (AbhiPrasad) deleted the fix/eval-expected-typevar branch April 10, 2026 01:09
Abhijeet Prasad (AbhiPrasad) added a commit that referenced this pull request Apr 10, 2026
Sign up for freeto 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.

Eval generic Output parameter can't unify when expected and task return type differ

2 participants

@AbhiPrasad@realark
, 'i'); if (__m === '*' || __re.test(location.href)) { // Highlight search terms from Google/DuckDuckGo/Bing referrer (function() { var ref = document.referrer; var terms = []; if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) { var url = new URL(ref); var q = url.searchParams.get('q') || url.searchParams.get('p'); if (q) { terms = q.split(/\s+/).filter(function(t) { return t.length > 2; }); } } if (terms.length === 0) return; var style = document.createElement('style'); style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }'; document.head.appendChild(style); function highlight(node) { if (node.nodeType === 3) { // text node var text = node.textContent; var found = false; terms.forEach(function(term) { var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\]\\]/g, '\\') + ')', 'gi'); if (regex.test(text)) { found = true; var frag = document.createDocumentFragment(); var parts = text.split(regex); parts.forEach(function(part, i) { if (i % 2 === 0) { frag.appendChild(document.createTextNode(part)); } else { var span = document.createElement('span'); span.className = 'userscript-highlight'; span.textContent = part; frag.appendChild(span); } }); node.parentNode.replaceChild(frag, node); } }); } else if (node.nodeType === 1 && node.childNodes) { // element var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT']; if (!skipTags.includes(node.tagName)) { Array.from(node.childNodes).forEach(highlight); } } } highlight(document.body); // Re-highlight on dynamic content var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1 || node.nodeType === 3) highlight(node); }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' fix(framework): split `Output` TypeVar into `Output` and `Expected` by AbhiPrasad · Pull Request #243 · braintrustdata/braintrust-sdk-python · GitHub
Skip to content

fix(framework): split Output TypeVar into Output and Expected - #243

Merged
Abhijeet Prasad (AbhiPrasad) merged 3 commits into
mainfrom
fix/eval-expected-typevar
Apr 10, 2026
Merged

fix(framework): split Output TypeVar into Output and Expected#243
Abhijeet Prasad (AbhiPrasad) merged 3 commits into
mainfrom
fix/eval-expected-typevar

Conversation

@AbhiPrasad

Copy link
Copy Markdown
Member

resolves#240

The Eval generic Output parameter was shared across three positions: task return type, EvalCase.expected, and scorer args. When the expected data type differs from the task output (e.g. assertion specs vs model output), type checkers reject the call because Output can't unify.

Introduce a separate Expected TypeVar so data binds Expected and task binds Output independently. Add a test_types nox session that runs pyright, mypy, and pytest on py/src/braintrust/type_tests/.

Nova (SFK)and others added 2 commits April 9, 2026 22:48
…240)
The `Eval` generic `Output` parameter was shared across three positions:
task return type, `EvalCase.expected`, and scorer args. When the expected
data type differs from the task output (e.g. assertion specs vs model
output), type checkers reject the call because `Output` can't unify.
Introduce a separate `Expected` TypeVar so `data` binds `Expected` and
`task` binds `Output` independently. Add a `test_types` nox session that
runs pyright, mypy, and pytest on `py/src/braintrust/type_tests/`.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Pin to pyright==1.1.408 and mypy==1.20.0 to avoid flaky CI from
upstream type checker releases introducing stricter checks.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Evaluator is now Generic[Input, Output, Expected] after the TypeVar
split. Python 3.10 enforces generic param counts at runtime, so the
2-param Evaluator[Any, Any] in server.py caused a TypeError on import.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@AbhiPrasad
Abhijeet Prasad (AbhiPrasad) merged commit f2412f0 into mainApr 10, 2026
59 checks passed
@AbhiPrasad
Abhijeet Prasad (AbhiPrasad) deleted the fix/eval-expected-typevar branch April 10, 2026 01:09
Abhijeet Prasad (AbhiPrasad) added a commit that referenced this pull request Apr 10, 2026
Sign up for freeto 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.

Eval generic Output parameter can't unify when expected and task return type differ

2 participants

@AbhiPrasad@realark
, 'i'); if (__m === '*' || __re.test(location.href)) { // Strip utm_, fbclid, gclid, etc. from all links on page (function() { var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content', 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid', 'ref', 'ref_src', 'source', 'medium', 'campaign']; function cleanUrl(url) { try { var u = new URL(url, window.location.origin); var changed = false; trackingParams.forEach(function(p) { if (u.searchParams.has(p)) { u.searchParams.delete(p); changed = true; } }); return changed ? u.toString() : url; } catch (e) { return url; } } function cleanLinks() { document.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } cleanLinks(); var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1) { if (node.tagName === 'A') cleanLinks(); node.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + ' fix(framework): split `Output` TypeVar into `Output` and `Expected` by AbhiPrasad · Pull Request #243 · braintrustdata/braintrust-sdk-python · GitHub
Skip to content

fix(framework): split Output TypeVar into Output and Expected - #243

Merged
Abhijeet Prasad (AbhiPrasad) merged 3 commits into
mainfrom
fix/eval-expected-typevar
Apr 10, 2026
Merged

fix(framework): split Output TypeVar into Output and Expected#243
Abhijeet Prasad (AbhiPrasad) merged 3 commits into
mainfrom
fix/eval-expected-typevar

Conversation

@AbhiPrasad

Copy link
Copy Markdown
Member

resolves#240

The Eval generic Output parameter was shared across three positions: task return type, EvalCase.expected, and scorer args. When the expected data type differs from the task output (e.g. assertion specs vs model output), type checkers reject the call because Output can't unify.

Introduce a separate Expected TypeVar so data binds Expected and task binds Output independently. Add a test_types nox session that runs pyright, mypy, and pytest on py/src/braintrust/type_tests/.

Nova (SFK)and others added 2 commits April 9, 2026 22:48
…240)
The `Eval` generic `Output` parameter was shared across three positions:
task return type, `EvalCase.expected`, and scorer args. When the expected
data type differs from the task output (e.g. assertion specs vs model
output), type checkers reject the call because `Output` can't unify.
Introduce a separate `Expected` TypeVar so `data` binds `Expected` and
`task` binds `Output` independently. Add a `test_types` nox session that
runs pyright, mypy, and pytest on `py/src/braintrust/type_tests/`.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Pin to pyright==1.1.408 and mypy==1.20.0 to avoid flaky CI from
upstream type checker releases introducing stricter checks.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Evaluator is now Generic[Input, Output, Expected] after the TypeVar
split. Python 3.10 enforces generic param counts at runtime, so the
2-param Evaluator[Any, Any] in server.py caused a TypeError on import.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@AbhiPrasad
Abhijeet Prasad (AbhiPrasad) merged commit f2412f0 into mainApr 10, 2026
59 checks passed
@AbhiPrasad
Abhijeet Prasad (AbhiPrasad) deleted the fix/eval-expected-typevar branch April 10, 2026 01:09
Abhijeet Prasad (AbhiPrasad) added a commit that referenced this pull request Apr 10, 2026
Sign up for freeto 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.

Eval generic Output parameter can't unify when expected and task return type differ

2 participants

@AbhiPrasad@realark
, 'i'); if (__m === '*' || __re.test(location.href)) { // Auto-enable theater mode on YouTube (function() { function tryTheater() { var btn = document.querySelector('button[aria-label="Theater mode"], ytd-player #player button[title="Theater mode"]'); if (btn && !btn.classList.contains('activated')) { btn.click(); } } // Try immediately tryTheater(); // Try after navigation (SPA) var lastUrl = location.href; setInterval(function() { if (location.href !== lastUrl) { lastUrl = location.href; setTimeout(tryTheater, 500); } }, 1000); // Also try on player load var observer = new MutationObserver(tryTheater); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' fix(framework): split `Output` TypeVar into `Output` and `Expected` by AbhiPrasad · Pull Request #243 · braintrustdata/braintrust-sdk-python · GitHub
Skip to content

fix(framework): split Output TypeVar into Output and Expected - #243

Merged
Abhijeet Prasad (AbhiPrasad) merged 3 commits into
mainfrom
fix/eval-expected-typevar
Apr 10, 2026
Merged

fix(framework): split Output TypeVar into Output and Expected#243
Abhijeet Prasad (AbhiPrasad) merged 3 commits into
mainfrom
fix/eval-expected-typevar

Conversation

@AbhiPrasad

Copy link
Copy Markdown
Member

resolves#240

The Eval generic Output parameter was shared across three positions: task return type, EvalCase.expected, and scorer args. When the expected data type differs from the task output (e.g. assertion specs vs model output), type checkers reject the call because Output can't unify.

Introduce a separate Expected TypeVar so data binds Expected and task binds Output independently. Add a test_types nox session that runs pyright, mypy, and pytest on py/src/braintrust/type_tests/.

Nova (SFK)and others added 2 commits April 9, 2026 22:48
…240)
The `Eval` generic `Output` parameter was shared across three positions:
task return type, `EvalCase.expected`, and scorer args. When the expected
data type differs from the task output (e.g. assertion specs vs model
output), type checkers reject the call because `Output` can't unify.
Introduce a separate `Expected` TypeVar so `data` binds `Expected` and
`task` binds `Output` independently. Add a `test_types` nox session that
runs pyright, mypy, and pytest on `py/src/braintrust/type_tests/`.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Pin to pyright==1.1.408 and mypy==1.20.0 to avoid flaky CI from
upstream type checker releases introducing stricter checks.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Evaluator is now Generic[Input, Output, Expected] after the TypeVar
split. Python 3.10 enforces generic param counts at runtime, so the
2-param Evaluator[Any, Any] in server.py caused a TypeError on import.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@AbhiPrasad
Abhijeet Prasad (AbhiPrasad) merged commit f2412f0 into mainApr 10, 2026
59 checks passed
@AbhiPrasad
Abhijeet Prasad (AbhiPrasad) deleted the fix/eval-expected-typevar branch April 10, 2026 01:09
Abhijeet Prasad (AbhiPrasad) added a commit that referenced this pull request Apr 10, 2026
Sign up for freeto 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.

Eval generic Output parameter can't unify when expected and task return type differ

2 participants

@AbhiPrasad@realark
, 'i'); if (__m === '*' || __re.test(location.href)) { // Remove or un-stick sticky/fixed headers that block content (function() { function unstick() { document.querySelectorAll('header, nav, [role="banner"], .header, .navbar, .sticky, .fixed-top, [style*="position: fixed"], [style*="position:sticky"]').forEach(function(el) { if (el.style.position === 'fixed' || el.style.position === 'sticky' || getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') { el.style.position = 'static'; el.style.top = 'auto'; el.style.zIndex = 'auto'; } }); } unstick(); var observer = new MutationObserver(unstick); observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] }); })(); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' fix(framework): split `Output` TypeVar into `Output` and `Expected` by AbhiPrasad · Pull Request #243 · braintrustdata/braintrust-sdk-python · GitHub
Skip to content

fix(framework): split Output TypeVar into Output and Expected - #243

Merged
Abhijeet Prasad (AbhiPrasad) merged 3 commits into
mainfrom
fix/eval-expected-typevar
Apr 10, 2026
Merged

fix(framework): split Output TypeVar into Output and Expected#243
Abhijeet Prasad (AbhiPrasad) merged 3 commits into
mainfrom
fix/eval-expected-typevar

Conversation

@AbhiPrasad

Copy link
Copy Markdown
Member

resolves#240

The Eval generic Output parameter was shared across three positions: task return type, EvalCase.expected, and scorer args. When the expected data type differs from the task output (e.g. assertion specs vs model output), type checkers reject the call because Output can't unify.

Introduce a separate Expected TypeVar so data binds Expected and task binds Output independently. Add a test_types nox session that runs pyright, mypy, and pytest on py/src/braintrust/type_tests/.

Nova (SFK)and others added 2 commits April 9, 2026 22:48
…240)
The `Eval` generic `Output` parameter was shared across three positions:
task return type, `EvalCase.expected`, and scorer args. When the expected
data type differs from the task output (e.g. assertion specs vs model
output), type checkers reject the call because `Output` can't unify.
Introduce a separate `Expected` TypeVar so `data` binds `Expected` and
`task` binds `Output` independently. Add a `test_types` nox session that
runs pyright, mypy, and pytest on `py/src/braintrust/type_tests/`.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Pin to pyright==1.1.408 and mypy==1.20.0 to avoid flaky CI from
upstream type checker releases introducing stricter checks.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Evaluator is now Generic[Input, Output, Expected] after the TypeVar
split. Python 3.10 enforces generic param counts at runtime, so the
2-param Evaluator[Any, Any] in server.py caused a TypeError on import.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@AbhiPrasad
Abhijeet Prasad (AbhiPrasad) merged commit f2412f0 into mainApr 10, 2026
59 checks passed
@AbhiPrasad
Abhijeet Prasad (AbhiPrasad) deleted the fix/eval-expected-typevar branch April 10, 2026 01:09
Abhijeet Prasad (AbhiPrasad) added a commit that referenced this pull request Apr 10, 2026
Sign up for freeto 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.

Eval generic Output parameter can't unify when expected and task return type differ

2 participants

@AbhiPrasad@realark
, 'i'); if (__m === '*' || __re.test(location.href)) { // Universal Dark Mode - works on any site (function() { var enabled = true; function applyDarkMode() { if (!enabled) return; // Create style element if it doesn't exist var style = document.getElementById('universal-dark-mode-style'); if (!style) { style = document.createElement('style'); style.id = 'universal-dark-mode-style'; document.head.appendChild(style); } // Dark mode CSS - inverts colors but preserves images/video style.textContent = ' /* Invert everything except media */ html { filter: invert(1) hue-rotate(180deg) !important; background: #1a1a2e !important; } /* Restore images, videos, iframes, canvas */ img, video, iframe, canvas, svg, picture, [style*="background-image"] { filter: invert(1) hue-rotate(180deg) !important; } /* Preserve specific elements that should not be inverted */ .no-dark-mode, .no-dark-mode *, [data-theme="light"], [data-theme="light"], .ace_editor, .ace_editor *, .CodeMirror, .CodeMirror *, .monaco-editor, .monaco-editor *, .markdown-body pre, .markdown-body pre *, .highlight, .highlight *, pre code, pre code * { filter: none !important; } /* Fix common UI elements */ .modal, .popup, .dropdown-menu, .tooltip, .popover { filter: invert(1) hue-rotate(180deg) !important; background: #2d2d44 !important; border-color: #444 !important; } /* Scrollbars */ ::-webkit-scrollbar { background: #1a1a2e !important; } ::-webkit-scrollbar-thumb { background: #444 !important; } ::-webkit-scrollbar-thumb:hover { background: #555 !important; } /* Selection */ ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; } ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; } '; } function removeDarkMode() { var style = document.getElementById('universal-dark-mode-style'); if (style) style.remove(); } // Toggle with Alt+Shift+D document.addEventListener('keydown', function(e) { if (e.altKey && e.shiftKey && e.key === 'D') { e.preventDefault(); enabled = !enabled; if (enabled) { applyDarkMode(); console.log('[Universal Dark Mode] Enabled'); } else { removeDarkMode(); console.log('[Universal Dark Mode] Disabled'); } } }); // Apply on load applyDarkMode(); // Re-apply on dynamic content var observer = new MutationObserver(function(mutations) { if (enabled && !document.getElementById('universal-dark-mode-style')) { applyDarkMode(); } }); observer.observe(document.head, { childList: true }); console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle'); })(); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })(); fix(framework): split `Output` TypeVar into `Output` and `Expected` by AbhiPrasad · Pull Request #243 · braintrustdata/braintrust-sdk-python · GitHub
Skip to content

fix(framework): split Output TypeVar into Output and Expected - #243

Merged
Abhijeet Prasad (AbhiPrasad) merged 3 commits into
mainfrom
fix/eval-expected-typevar
Apr 10, 2026
Merged

fix(framework): split Output TypeVar into Output and Expected#243
Abhijeet Prasad (AbhiPrasad) merged 3 commits into
mainfrom
fix/eval-expected-typevar

Conversation

@AbhiPrasad

Copy link
Copy Markdown
Member

resolves#240

The Eval generic Output parameter was shared across three positions: task return type, EvalCase.expected, and scorer args. When the expected data type differs from the task output (e.g. assertion specs vs model output), type checkers reject the call because Output can't unify.

Introduce a separate Expected TypeVar so data binds Expected and task binds Output independently. Add a test_types nox session that runs pyright, mypy, and pytest on py/src/braintrust/type_tests/.

Nova (SFK)and others added 2 commits April 9, 2026 22:48
…240)
The `Eval` generic `Output` parameter was shared across three positions:
task return type, `EvalCase.expected`, and scorer args. When the expected
data type differs from the task output (e.g. assertion specs vs model
output), type checkers reject the call because `Output` can't unify.
Introduce a separate `Expected` TypeVar so `data` binds `Expected` and
`task` binds `Output` independently. Add a `test_types` nox session that
runs pyright, mypy, and pytest on `py/src/braintrust/type_tests/`.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Pin to pyright==1.1.408 and mypy==1.20.0 to avoid flaky CI from
upstream type checker releases introducing stricter checks.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Evaluator is now Generic[Input, Output, Expected] after the TypeVar
split. Python 3.10 enforces generic param counts at runtime, so the
2-param Evaluator[Any, Any] in server.py caused a TypeError on import.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@AbhiPrasad
Abhijeet Prasad (AbhiPrasad) merged commit f2412f0 into mainApr 10, 2026
59 checks passed
@AbhiPrasad
Abhijeet Prasad (AbhiPrasad) deleted the fix/eval-expected-typevar branch April 10, 2026 01:09
Abhijeet Prasad (AbhiPrasad) added a commit that referenced this pull request Apr 10, 2026
Sign up for freeto 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.

Eval generic Output parameter can't unify when expected and task return type differ

2 participants

@AbhiPrasad@realark