Skip to content

Fix Invoke-WebRequest IDictionary cast error - #292

Closed
l3tchupkt wants to merge 1 commit into
python:mainfrom
l3tchupkt:main
Closed

Fix Invoke-WebRequest IDictionary cast error#292
l3tchupkt wants to merge 1 commit into
python:mainfrom
l3tchupkt:main

Conversation

@l3tchupkt

Copy link
Copy Markdown
Contributor

Description

This PR addresses a critical failure in the PowerShell-based download fallback and restores compatibility for systems running Python versions earlier than 3.11.

1. PowerShell Header Binding Fix (src/manage/urlutils.py)

  • Root Cause: In Windows PowerShell 5.1, the -Headers parameter for Invoke-WebRequest strictly requires a System.Collections.IDictionary (Hashtable). When headers are passed from Python as JSON and parsed via ConvertFrom-Json, PowerShell returns a PSCustomObject, which fails the type-binding check.
  • Fix: The PowerShell script has been updated to manually coerce the PSCustomObject into a true Hashtable (@ {}) by iterating over its properties. This ensures the download fallback remains robust across all Windows installations.

2. Python 3.10 os.path.splitroot Fallback (src/manage/pathutils.py)

  • Root Cause: The current pathutils.py reimplementation relied on os.path.splitroot, a function only introduced in Python 3.11. This caused immediate crashes on older stable runtimes like Python 3.10.
  • Fix: Implemented a _splitroot helper function that uses ntpath.splitdrive as a fallback when os.path.splitroot is unavailable. This maintains the project's goal of high performance with minimal imports while ensuring broad version compatibility.

3. Verification Summary

  • PowerShell Tests: Verified that test_powershell_urlretrieve, test_powershell_urlopen, and test_powershell_urlretrieve_auth all pass on a Windows 10/11 environment running Python 3.10 and PowerShell 5.1.
  • Regression Testing: Confirmed that the fix does not interfere with the primary urllib or winhttp download paths.

@zooba

Copy link
Copy Markdown
Member

In Windows PowerShell 5.1, the -Headers parameter for Invoke-WebRequest strictly requires a System.Collections.IDictionary (Hashtable).

This is worth fixing.

Python 3.10 os.path.splitroot Fallback

This is not relevant. PyManager is released as an app, not a library, and only needs to be compatible with the version of Python that it carries with it. That's never going to be 3.10, so we can ignore fallbacks.

In general, try and keep separate fixes in separate PRs (and feel free to create issues first if there are any questions about applicability). We can't merge this until the unnecessary changes are removed.

Comment threadsrc/manage/urlutils.py
@l3tchupkt

l3tchupkt commented Mar 30, 2026 via email

Copy link
Copy Markdown
ContributorAuthor

@zooba

Copy link
Copy Markdown
Member

I needed the relevant part of this fix to unblock other work, so I recreated a new PR #297 with just the bit we're taking. Hopefully the co-authored-by label will work properly to send credit your way - definitely not trying to steal your work, just can't do anything else without this fix.

@zoobazooba closed this Mar 31, 2026
zooba added a commit that referenced this pull request Mar 31, 2026
Originally fixed in #292
Co-authored-by: badassletchu@gmail.com
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.

2 participants

@l3tchupkt@zooba
, '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 Invoke-WebRequest IDictionary cast error by l3tchupkt · Pull Request #292 · python/pymanager · GitHub
Skip to content

Fix Invoke-WebRequest IDictionary cast error - #292

Closed
l3tchupkt wants to merge 1 commit into
python:mainfrom
l3tchupkt:main
Closed

Fix Invoke-WebRequest IDictionary cast error#292
l3tchupkt wants to merge 1 commit into
python:mainfrom
l3tchupkt:main

Conversation

@l3tchupkt

Copy link
Copy Markdown
Contributor

Description

This PR addresses a critical failure in the PowerShell-based download fallback and restores compatibility for systems running Python versions earlier than 3.11.

1. PowerShell Header Binding Fix (src/manage/urlutils.py)

  • Root Cause: In Windows PowerShell 5.1, the -Headers parameter for Invoke-WebRequest strictly requires a System.Collections.IDictionary (Hashtable). When headers are passed from Python as JSON and parsed via ConvertFrom-Json, PowerShell returns a PSCustomObject, which fails the type-binding check.
  • Fix: The PowerShell script has been updated to manually coerce the PSCustomObject into a true Hashtable (@ {}) by iterating over its properties. This ensures the download fallback remains robust across all Windows installations.

2. Python 3.10 os.path.splitroot Fallback (src/manage/pathutils.py)

  • Root Cause: The current pathutils.py reimplementation relied on os.path.splitroot, a function only introduced in Python 3.11. This caused immediate crashes on older stable runtimes like Python 3.10.
  • Fix: Implemented a _splitroot helper function that uses ntpath.splitdrive as a fallback when os.path.splitroot is unavailable. This maintains the project's goal of high performance with minimal imports while ensuring broad version compatibility.

3. Verification Summary

  • PowerShell Tests: Verified that test_powershell_urlretrieve, test_powershell_urlopen, and test_powershell_urlretrieve_auth all pass on a Windows 10/11 environment running Python 3.10 and PowerShell 5.1.
  • Regression Testing: Confirmed that the fix does not interfere with the primary urllib or winhttp download paths.

@zooba

Copy link
Copy Markdown
Member

In Windows PowerShell 5.1, the -Headers parameter for Invoke-WebRequest strictly requires a System.Collections.IDictionary (Hashtable).

This is worth fixing.

Python 3.10 os.path.splitroot Fallback

This is not relevant. PyManager is released as an app, not a library, and only needs to be compatible with the version of Python that it carries with it. That's never going to be 3.10, so we can ignore fallbacks.

In general, try and keep separate fixes in separate PRs (and feel free to create issues first if there are any questions about applicability). We can't merge this until the unnecessary changes are removed.

Comment threadsrc/manage/urlutils.py
@l3tchupkt

l3tchupkt commented Mar 30, 2026 via email

Copy link
Copy Markdown
ContributorAuthor

@zooba

Copy link
Copy Markdown
Member

I needed the relevant part of this fix to unblock other work, so I recreated a new PR #297 with just the bit we're taking. Hopefully the co-authored-by label will work properly to send credit your way - definitely not trying to steal your work, just can't do anything else without this fix.

@zoobazooba closed this Mar 31, 2026
zooba added a commit that referenced this pull request Mar 31, 2026
Originally fixed in #292
Co-authored-by: badassletchu@gmail.com
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.

2 participants

@l3tchupkt@zooba
, '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 Invoke-WebRequest IDictionary cast error by l3tchupkt · Pull Request #292 · python/pymanager · GitHub
Skip to content

Fix Invoke-WebRequest IDictionary cast error - #292

Closed
l3tchupkt wants to merge 1 commit into
python:mainfrom
l3tchupkt:main
Closed

Fix Invoke-WebRequest IDictionary cast error#292
l3tchupkt wants to merge 1 commit into
python:mainfrom
l3tchupkt:main

Conversation

@l3tchupkt

Copy link
Copy Markdown
Contributor

Description

This PR addresses a critical failure in the PowerShell-based download fallback and restores compatibility for systems running Python versions earlier than 3.11.

1. PowerShell Header Binding Fix (src/manage/urlutils.py)

  • Root Cause: In Windows PowerShell 5.1, the -Headers parameter for Invoke-WebRequest strictly requires a System.Collections.IDictionary (Hashtable). When headers are passed from Python as JSON and parsed via ConvertFrom-Json, PowerShell returns a PSCustomObject, which fails the type-binding check.
  • Fix: The PowerShell script has been updated to manually coerce the PSCustomObject into a true Hashtable (@ {}) by iterating over its properties. This ensures the download fallback remains robust across all Windows installations.

2. Python 3.10 os.path.splitroot Fallback (src/manage/pathutils.py)

  • Root Cause: The current pathutils.py reimplementation relied on os.path.splitroot, a function only introduced in Python 3.11. This caused immediate crashes on older stable runtimes like Python 3.10.
  • Fix: Implemented a _splitroot helper function that uses ntpath.splitdrive as a fallback when os.path.splitroot is unavailable. This maintains the project's goal of high performance with minimal imports while ensuring broad version compatibility.

3. Verification Summary

  • PowerShell Tests: Verified that test_powershell_urlretrieve, test_powershell_urlopen, and test_powershell_urlretrieve_auth all pass on a Windows 10/11 environment running Python 3.10 and PowerShell 5.1.
  • Regression Testing: Confirmed that the fix does not interfere with the primary urllib or winhttp download paths.

@zooba

Copy link
Copy Markdown
Member

In Windows PowerShell 5.1, the -Headers parameter for Invoke-WebRequest strictly requires a System.Collections.IDictionary (Hashtable).

This is worth fixing.

Python 3.10 os.path.splitroot Fallback

This is not relevant. PyManager is released as an app, not a library, and only needs to be compatible with the version of Python that it carries with it. That's never going to be 3.10, so we can ignore fallbacks.

In general, try and keep separate fixes in separate PRs (and feel free to create issues first if there are any questions about applicability). We can't merge this until the unnecessary changes are removed.

Comment threadsrc/manage/urlutils.py
@l3tchupkt

l3tchupkt commented Mar 30, 2026 via email

Copy link
Copy Markdown
ContributorAuthor

@zooba

Copy link
Copy Markdown
Member

I needed the relevant part of this fix to unblock other work, so I recreated a new PR #297 with just the bit we're taking. Hopefully the co-authored-by label will work properly to send credit your way - definitely not trying to steal your work, just can't do anything else without this fix.

@zoobazooba closed this Mar 31, 2026
zooba added a commit that referenced this pull request Mar 31, 2026
Originally fixed in #292
Co-authored-by: badassletchu@gmail.com
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.

2 participants

@l3tchupkt@zooba
, '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 Invoke-WebRequest IDictionary cast error by l3tchupkt · Pull Request #292 · python/pymanager · GitHub
Skip to content

Fix Invoke-WebRequest IDictionary cast error - #292

Closed
l3tchupkt wants to merge 1 commit into
python:mainfrom
l3tchupkt:main
Closed

Fix Invoke-WebRequest IDictionary cast error#292
l3tchupkt wants to merge 1 commit into
python:mainfrom
l3tchupkt:main

Conversation

@l3tchupkt

Copy link
Copy Markdown
Contributor

Description

This PR addresses a critical failure in the PowerShell-based download fallback and restores compatibility for systems running Python versions earlier than 3.11.

1. PowerShell Header Binding Fix (src/manage/urlutils.py)

  • Root Cause: In Windows PowerShell 5.1, the -Headers parameter for Invoke-WebRequest strictly requires a System.Collections.IDictionary (Hashtable). When headers are passed from Python as JSON and parsed via ConvertFrom-Json, PowerShell returns a PSCustomObject, which fails the type-binding check.
  • Fix: The PowerShell script has been updated to manually coerce the PSCustomObject into a true Hashtable (@ {}) by iterating over its properties. This ensures the download fallback remains robust across all Windows installations.

2. Python 3.10 os.path.splitroot Fallback (src/manage/pathutils.py)

  • Root Cause: The current pathutils.py reimplementation relied on os.path.splitroot, a function only introduced in Python 3.11. This caused immediate crashes on older stable runtimes like Python 3.10.
  • Fix: Implemented a _splitroot helper function that uses ntpath.splitdrive as a fallback when os.path.splitroot is unavailable. This maintains the project's goal of high performance with minimal imports while ensuring broad version compatibility.

3. Verification Summary

  • PowerShell Tests: Verified that test_powershell_urlretrieve, test_powershell_urlopen, and test_powershell_urlretrieve_auth all pass on a Windows 10/11 environment running Python 3.10 and PowerShell 5.1.
  • Regression Testing: Confirmed that the fix does not interfere with the primary urllib or winhttp download paths.

@zooba

Copy link
Copy Markdown
Member

In Windows PowerShell 5.1, the -Headers parameter for Invoke-WebRequest strictly requires a System.Collections.IDictionary (Hashtable).

This is worth fixing.

Python 3.10 os.path.splitroot Fallback

This is not relevant. PyManager is released as an app, not a library, and only needs to be compatible with the version of Python that it carries with it. That's never going to be 3.10, so we can ignore fallbacks.

In general, try and keep separate fixes in separate PRs (and feel free to create issues first if there are any questions about applicability). We can't merge this until the unnecessary changes are removed.

Comment threadsrc/manage/urlutils.py
@l3tchupkt

l3tchupkt commented Mar 30, 2026 via email

Copy link
Copy Markdown
ContributorAuthor

@zooba

Copy link
Copy Markdown
Member

I needed the relevant part of this fix to unblock other work, so I recreated a new PR #297 with just the bit we're taking. Hopefully the co-authored-by label will work properly to send credit your way - definitely not trying to steal your work, just can't do anything else without this fix.

@zoobazooba closed this Mar 31, 2026
zooba added a commit that referenced this pull request Mar 31, 2026
Originally fixed in #292
Co-authored-by: badassletchu@gmail.com
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.

2 participants

@l3tchupkt@zooba
, '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 Invoke-WebRequest IDictionary cast error by l3tchupkt · Pull Request #292 · python/pymanager · GitHub
Skip to content

Fix Invoke-WebRequest IDictionary cast error - #292

Closed
l3tchupkt wants to merge 1 commit into
python:mainfrom
l3tchupkt:main
Closed

Fix Invoke-WebRequest IDictionary cast error#292
l3tchupkt wants to merge 1 commit into
python:mainfrom
l3tchupkt:main

Conversation

@l3tchupkt

Copy link
Copy Markdown
Contributor

Description

This PR addresses a critical failure in the PowerShell-based download fallback and restores compatibility for systems running Python versions earlier than 3.11.

1. PowerShell Header Binding Fix (src/manage/urlutils.py)

  • Root Cause: In Windows PowerShell 5.1, the -Headers parameter for Invoke-WebRequest strictly requires a System.Collections.IDictionary (Hashtable). When headers are passed from Python as JSON and parsed via ConvertFrom-Json, PowerShell returns a PSCustomObject, which fails the type-binding check.
  • Fix: The PowerShell script has been updated to manually coerce the PSCustomObject into a true Hashtable (@ {}) by iterating over its properties. This ensures the download fallback remains robust across all Windows installations.

2. Python 3.10 os.path.splitroot Fallback (src/manage/pathutils.py)

  • Root Cause: The current pathutils.py reimplementation relied on os.path.splitroot, a function only introduced in Python 3.11. This caused immediate crashes on older stable runtimes like Python 3.10.
  • Fix: Implemented a _splitroot helper function that uses ntpath.splitdrive as a fallback when os.path.splitroot is unavailable. This maintains the project's goal of high performance with minimal imports while ensuring broad version compatibility.

3. Verification Summary

  • PowerShell Tests: Verified that test_powershell_urlretrieve, test_powershell_urlopen, and test_powershell_urlretrieve_auth all pass on a Windows 10/11 environment running Python 3.10 and PowerShell 5.1.
  • Regression Testing: Confirmed that the fix does not interfere with the primary urllib or winhttp download paths.

@zooba

Copy link
Copy Markdown
Member

In Windows PowerShell 5.1, the -Headers parameter for Invoke-WebRequest strictly requires a System.Collections.IDictionary (Hashtable).

This is worth fixing.

Python 3.10 os.path.splitroot Fallback

This is not relevant. PyManager is released as an app, not a library, and only needs to be compatible with the version of Python that it carries with it. That's never going to be 3.10, so we can ignore fallbacks.

In general, try and keep separate fixes in separate PRs (and feel free to create issues first if there are any questions about applicability). We can't merge this until the unnecessary changes are removed.

Comment threadsrc/manage/urlutils.py
@l3tchupkt

l3tchupkt commented Mar 30, 2026 via email

Copy link
Copy Markdown
ContributorAuthor

@zooba

Copy link
Copy Markdown
Member

I needed the relevant part of this fix to unblock other work, so I recreated a new PR #297 with just the bit we're taking. Hopefully the co-authored-by label will work properly to send credit your way - definitely not trying to steal your work, just can't do anything else without this fix.

@zoobazooba closed this Mar 31, 2026
zooba added a commit that referenced this pull request Mar 31, 2026
Originally fixed in #292
Co-authored-by: badassletchu@gmail.com
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.

2 participants

@l3tchupkt@zooba
, '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 Invoke-WebRequest IDictionary cast error by l3tchupkt · Pull Request #292 · python/pymanager · GitHub
Skip to content

Fix Invoke-WebRequest IDictionary cast error - #292

Closed
l3tchupkt wants to merge 1 commit into
python:mainfrom
l3tchupkt:main
Closed

Fix Invoke-WebRequest IDictionary cast error#292
l3tchupkt wants to merge 1 commit into
python:mainfrom
l3tchupkt:main

Conversation

@l3tchupkt

Copy link
Copy Markdown
Contributor

Description

This PR addresses a critical failure in the PowerShell-based download fallback and restores compatibility for systems running Python versions earlier than 3.11.

1. PowerShell Header Binding Fix (src/manage/urlutils.py)

  • Root Cause: In Windows PowerShell 5.1, the -Headers parameter for Invoke-WebRequest strictly requires a System.Collections.IDictionary (Hashtable). When headers are passed from Python as JSON and parsed via ConvertFrom-Json, PowerShell returns a PSCustomObject, which fails the type-binding check.
  • Fix: The PowerShell script has been updated to manually coerce the PSCustomObject into a true Hashtable (@ {}) by iterating over its properties. This ensures the download fallback remains robust across all Windows installations.

2. Python 3.10 os.path.splitroot Fallback (src/manage/pathutils.py)

  • Root Cause: The current pathutils.py reimplementation relied on os.path.splitroot, a function only introduced in Python 3.11. This caused immediate crashes on older stable runtimes like Python 3.10.
  • Fix: Implemented a _splitroot helper function that uses ntpath.splitdrive as a fallback when os.path.splitroot is unavailable. This maintains the project's goal of high performance with minimal imports while ensuring broad version compatibility.

3. Verification Summary

  • PowerShell Tests: Verified that test_powershell_urlretrieve, test_powershell_urlopen, and test_powershell_urlretrieve_auth all pass on a Windows 10/11 environment running Python 3.10 and PowerShell 5.1.
  • Regression Testing: Confirmed that the fix does not interfere with the primary urllib or winhttp download paths.

@zooba

Copy link
Copy Markdown
Member

In Windows PowerShell 5.1, the -Headers parameter for Invoke-WebRequest strictly requires a System.Collections.IDictionary (Hashtable).

This is worth fixing.

Python 3.10 os.path.splitroot Fallback

This is not relevant. PyManager is released as an app, not a library, and only needs to be compatible with the version of Python that it carries with it. That's never going to be 3.10, so we can ignore fallbacks.

In general, try and keep separate fixes in separate PRs (and feel free to create issues first if there are any questions about applicability). We can't merge this until the unnecessary changes are removed.

Comment threadsrc/manage/urlutils.py
@l3tchupkt

l3tchupkt commented Mar 30, 2026 via email

Copy link
Copy Markdown
ContributorAuthor

@zooba

Copy link
Copy Markdown
Member

I needed the relevant part of this fix to unblock other work, so I recreated a new PR #297 with just the bit we're taking. Hopefully the co-authored-by label will work properly to send credit your way - definitely not trying to steal your work, just can't do anything else without this fix.

@zoobazooba closed this Mar 31, 2026
zooba added a commit that referenced this pull request Mar 31, 2026
Originally fixed in #292
Co-authored-by: badassletchu@gmail.com
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.

2 participants

@l3tchupkt@zooba
, '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 Invoke-WebRequest IDictionary cast error by l3tchupkt · Pull Request #292 · python/pymanager · GitHub
Skip to content

Fix Invoke-WebRequest IDictionary cast error - #292

Closed
l3tchupkt wants to merge 1 commit into
python:mainfrom
l3tchupkt:main
Closed

Fix Invoke-WebRequest IDictionary cast error#292
l3tchupkt wants to merge 1 commit into
python:mainfrom
l3tchupkt:main

Conversation

@l3tchupkt

Copy link
Copy Markdown
Contributor

Description

This PR addresses a critical failure in the PowerShell-based download fallback and restores compatibility for systems running Python versions earlier than 3.11.

1. PowerShell Header Binding Fix (src/manage/urlutils.py)

  • Root Cause: In Windows PowerShell 5.1, the -Headers parameter for Invoke-WebRequest strictly requires a System.Collections.IDictionary (Hashtable). When headers are passed from Python as JSON and parsed via ConvertFrom-Json, PowerShell returns a PSCustomObject, which fails the type-binding check.
  • Fix: The PowerShell script has been updated to manually coerce the PSCustomObject into a true Hashtable (@ {}) by iterating over its properties. This ensures the download fallback remains robust across all Windows installations.

2. Python 3.10 os.path.splitroot Fallback (src/manage/pathutils.py)

  • Root Cause: The current pathutils.py reimplementation relied on os.path.splitroot, a function only introduced in Python 3.11. This caused immediate crashes on older stable runtimes like Python 3.10.
  • Fix: Implemented a _splitroot helper function that uses ntpath.splitdrive as a fallback when os.path.splitroot is unavailable. This maintains the project's goal of high performance with minimal imports while ensuring broad version compatibility.

3. Verification Summary

  • PowerShell Tests: Verified that test_powershell_urlretrieve, test_powershell_urlopen, and test_powershell_urlretrieve_auth all pass on a Windows 10/11 environment running Python 3.10 and PowerShell 5.1.
  • Regression Testing: Confirmed that the fix does not interfere with the primary urllib or winhttp download paths.

@zooba

Copy link
Copy Markdown
Member

In Windows PowerShell 5.1, the -Headers parameter for Invoke-WebRequest strictly requires a System.Collections.IDictionary (Hashtable).

This is worth fixing.

Python 3.10 os.path.splitroot Fallback

This is not relevant. PyManager is released as an app, not a library, and only needs to be compatible with the version of Python that it carries with it. That's never going to be 3.10, so we can ignore fallbacks.

In general, try and keep separate fixes in separate PRs (and feel free to create issues first if there are any questions about applicability). We can't merge this until the unnecessary changes are removed.

Comment threadsrc/manage/urlutils.py
@l3tchupkt

l3tchupkt commented Mar 30, 2026 via email

Copy link
Copy Markdown
ContributorAuthor

@zooba

Copy link
Copy Markdown
Member

I needed the relevant part of this fix to unblock other work, so I recreated a new PR #297 with just the bit we're taking. Hopefully the co-authored-by label will work properly to send credit your way - definitely not trying to steal your work, just can't do anything else without this fix.

@zoobazooba closed this Mar 31, 2026
zooba added a commit that referenced this pull request Mar 31, 2026
Originally fixed in #292
Co-authored-by: badassletchu@gmail.com
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.

2 participants

@l3tchupkt@zooba
, '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 Invoke-WebRequest IDictionary cast error by l3tchupkt · Pull Request #292 · python/pymanager · GitHub
Skip to content

Fix Invoke-WebRequest IDictionary cast error - #292

Closed
l3tchupkt wants to merge 1 commit into
python:mainfrom
l3tchupkt:main
Closed

Fix Invoke-WebRequest IDictionary cast error#292
l3tchupkt wants to merge 1 commit into
python:mainfrom
l3tchupkt:main

Conversation

@l3tchupkt

Copy link
Copy Markdown
Contributor

Description

This PR addresses a critical failure in the PowerShell-based download fallback and restores compatibility for systems running Python versions earlier than 3.11.

1. PowerShell Header Binding Fix (src/manage/urlutils.py)

  • Root Cause: In Windows PowerShell 5.1, the -Headers parameter for Invoke-WebRequest strictly requires a System.Collections.IDictionary (Hashtable). When headers are passed from Python as JSON and parsed via ConvertFrom-Json, PowerShell returns a PSCustomObject, which fails the type-binding check.
  • Fix: The PowerShell script has been updated to manually coerce the PSCustomObject into a true Hashtable (@ {}) by iterating over its properties. This ensures the download fallback remains robust across all Windows installations.

2. Python 3.10 os.path.splitroot Fallback (src/manage/pathutils.py)

  • Root Cause: The current pathutils.py reimplementation relied on os.path.splitroot, a function only introduced in Python 3.11. This caused immediate crashes on older stable runtimes like Python 3.10.
  • Fix: Implemented a _splitroot helper function that uses ntpath.splitdrive as a fallback when os.path.splitroot is unavailable. This maintains the project's goal of high performance with minimal imports while ensuring broad version compatibility.

3. Verification Summary

  • PowerShell Tests: Verified that test_powershell_urlretrieve, test_powershell_urlopen, and test_powershell_urlretrieve_auth all pass on a Windows 10/11 environment running Python 3.10 and PowerShell 5.1.
  • Regression Testing: Confirmed that the fix does not interfere with the primary urllib or winhttp download paths.

@zooba

Copy link
Copy Markdown
Member

In Windows PowerShell 5.1, the -Headers parameter for Invoke-WebRequest strictly requires a System.Collections.IDictionary (Hashtable).

This is worth fixing.

Python 3.10 os.path.splitroot Fallback

This is not relevant. PyManager is released as an app, not a library, and only needs to be compatible with the version of Python that it carries with it. That's never going to be 3.10, so we can ignore fallbacks.

In general, try and keep separate fixes in separate PRs (and feel free to create issues first if there are any questions about applicability). We can't merge this until the unnecessary changes are removed.

Comment threadsrc/manage/urlutils.py
@l3tchupkt

l3tchupkt commented Mar 30, 2026 via email

Copy link
Copy Markdown
ContributorAuthor

@zooba

Copy link
Copy Markdown
Member

I needed the relevant part of this fix to unblock other work, so I recreated a new PR #297 with just the bit we're taking. Hopefully the co-authored-by label will work properly to send credit your way - definitely not trying to steal your work, just can't do anything else without this fix.

@zoobazooba closed this Mar 31, 2026
zooba added a commit that referenced this pull request Mar 31, 2026
Originally fixed in #292
Co-authored-by: badassletchu@gmail.com
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.

2 participants

@l3tchupkt@zooba