') + ')', '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('^' + ".*" + ', '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" + ', '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('^' + ".*" + ', '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); } })(); })(); feat(gazelle): Add type-checking only dependencies to pyi_deps by amartani · Pull Request #3014 · bazel-contrib/rules_python · GitHub
Skip to content

feat(gazelle): Add type-checking only dependencies to pyi_deps - #3014

Merged
dougthor42 merged 11 commits into
bazel-contrib:mainfrom
amartani:martani/gazelle-pyi-deps
Jun 26, 2025
Merged

feat(gazelle): Add type-checking only dependencies to pyi_deps#3014
dougthor42 merged 11 commits into
bazel-contrib:mainfrom
amartani:martani/gazelle-pyi-deps

Conversation

@amartani

@amartaniamartani commented Jun 20, 2025

Copy link
Copy Markdown
Contributor

#2538 added the attribute pyi_deps to python rules, intended to be used for dependencies that are only used for type-checking purposes. This PR adds a new directive, gazelle:python_generate_pyi_deps, which, when enabled:

  • When a dependency is added only to satisfy type-checking only imports (in a if TYPE_CHECKING: block), the dependency is added to pyi_deps instead of deps;
  • Third-party stub packages (eg. boto3-stubs) are now added to pyi_deps instead of deps.

@amartani
amartani marked this pull request as ready for review June 20, 2025 03:28

@dougthor42dougthor42 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks! This will be a really nice improvement.

Couple requests:

  1. Guard this behind a gazelle directive. Maybe # gazelle:python_generate_pyi_deps (default false for now).
    • Or python_generate_pyi_deps_attribute? python_use_pyi_deps_attribute?
  2. Add the directive to gazelle/README.md - the table of directives and a section for the directive.
  3. In the section for the directive, document that only two forms are supported: if typing.TYPE_CHECKING: and if TYPE_CHECKING:.
    For example, if someone does
    importtypingasfooiffoo.TYPE_CHECKING:
    ...
    or other odd stuff like that, then the imports won't be marked as pyi_deps.

Comment threadCHANGELOG.md Outdated
Comment threadgazelle/python/file_parser.go
Comment threadgazelle/python/target.go Outdated
Comment threadgazelle/python/testdata/add_type_stub_packages/BUILD.out
Comment threadgazelle/python/testdata/type_checking_imports/bar.py
Comment threadgazelle/python/testdata/type_checking_imports/BUILD.in
Comment threadCHANGELOG.md Outdated
Comment threadgazelle/python/file_parser.go
Comment threadgazelle/python/testdata/type_checking_imports/BUILD.in
@dougthor42
dougthor42 added this pull request to the merge queueJun 26, 2025
Merged via the queue into bazel-contrib:main with commit e5ef69bJun 26, 2025
github-merge-queueBot pushed a commit that referenced this pull request Jun 29, 2025
Fix an issue in #3014
where a dependency may end up being added in both `deps` and `pyi_deps`,
in cases where the regular and the type-checking import refer to
different python modules on the same `py_library` target. Other cases
are already deduplicated earlier on, but this case can only be
deduplicated in the resolve phase.
(No new changelog entry since this is a fix to an unreleased feature
that is already in the changelog)
github-merge-queueBot pushed a commit that referenced this pull request Jun 30, 2025
Fix an issue in #3014
where, when all type-checking dependencies are removed from a file, the
corresponding target's `pyi_deps` doesn't get cleaned up. I traced this
back to `ResolveAttrs`, though I'm not entirely sure of what other
behaviors this may trigger. (Currently, removing `deps` from
`ResolveAttrs` doesn't break any existing test case)
(No new changelog entry since this is a fix to an unreleased feature
that is already in the changelog)
amartani added a commit to benchling/rules_python that referenced this pull request Jul 8, 2025
…ntrib#3036)
Fix an issue in bazel-contrib#3014
where a dependency may end up being added in both `deps` and `pyi_deps`,
in cases where the regular and the type-checking import refer to
different python modules on the same `py_library` target. Other cases
are already deduplicated earlier on, but this case can only be
deduplicated in the resolve phase.
(No new changelog entry since this is a fix to an unreleased feature
that is already in the changelog)
amartani added a commit to benchling/rules_python that referenced this pull request Jul 8, 2025
Fix an issue in bazel-contrib#3014
where, when all type-checking dependencies are removed from a file, the
corresponding target's `pyi_deps` doesn't get cleaned up. I traced this
back to `ResolveAttrs`, though I'm not entirely sure of what other
behaviors this may trigger. (Currently, removing `deps` from
`ResolveAttrs` doesn't break any existing test case)
(No new changelog entry since this is a fix to an unreleased feature
that is already in the changelog)
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.

3 participants

@amartani@aignas@dougthor42