') + ')', '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); } })(); })(); generate py_test without __test__ by linzhp · Pull Request #999 · bazel-contrib/rules_python · GitHub
Skip to content

generate py_test without __test__ - #999

Merged
f0rmiga merged 1 commit into
bazel-contrib:mainfrom
linzhp:py_test
Jan 23, 2023
Merged

generate py_test without __test__#999
f0rmiga merged 1 commit into
bazel-contrib:mainfrom
linzhp:py_test

Conversation

@linzhp

Copy link
Copy Markdown
Contributor

PR Checklist

Please check if your PR fulfills the following requirements:

  • Tests for the changes have been added (for bug fixes / features)
  • Docs have been added / updated (for bug fixes / features)

PR Type

What kind of change does this PR introduce?

  • Bugfix
  • Feature (please, look at the "Scope of the project" section in the README.md file)
  • Code style update (formatting, local variables)
  • Refactoring (no functional changes, no api changes)
  • Build related changes
  • CI related changes
  • Documentation content changes
  • Other... Please describe:

What is the current behavior?

The Gazelle extension requires the existence of __test__.py or a target named __test__ to generate py_test targets. Otherwise, all _test.py and test_*.py will be included into py_library.

Issue Number: #714

What is the new behavior?

__test__.py is not part of official Python specification. In fact, it is rarely used in existing open source Python projects. A more common scenario is to have _test.py or test_*.py files, each with something like:

if __name__ == '__main__':
unittest.main()

This PR creates a py_test target per test Python file when neither __test__.py or a target named __test__ exists.

Does this PR introduce a breaking change?

  • Yes
  • No

Other information

@linzhp
linzhp requested a review from f0rmiga as a code ownerJanuary 20, 2023 18:32

@f0rmigaf0rmiga left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I know at least a few repositories that this will be a breaking change. I've seen files using these patterns to contain test utilities and be reused by multiple tests. Ideally, those should be renamed to adhere to better practices. Having said that, we will need warning notes on the next release. cc @groodt@rickeylev

@f0rmiga
f0rmiga merged commit 0943375 into bazel-contrib:mainJan 23, 2023
@linzhp
linzhp deleted the py_test branch January 23, 2023 22:43
f0rmiga pushed a commit that referenced this pull request Apr 8, 2023
Since #999, gazelle can
generate multiple `py_test` rules in a single package (when it finds
multiple `*_test.py` or `test_*.py` files and no `__test__.py` file). In
this case, adding new test files to a package with pre-existing
`py_test` rules is not handled properly due to the `MatchAny` property
on the `py_test` kind - it will match the existing `py_test` rule and
edit it instead of adding a new test rule. This PR disables the matching
so that new `py_test` rules are properly generated.
github-merge-queueBot pushed a commit that referenced this pull request Jul 1, 2025
…les (#2998)
Remove entry point file requirements when generating rules. Enable
python rule generation as long as there are .py source files under the
directory so all new packages will have python rules generated in the
package.
The extension used to require entrypoints for generation but:
- entry point for tests (i.e., `__test__.py` ) is no longer required
after #999 and
#2044
- entry point for binaries (i.e., `__main__.py` ) is no longer required
after #1584
The entry point for libraries (`__init__.py` ) shouldn't be required
either, especially for Python 3.3 and after when namespace packages are
supported.
---------
Co-authored-by: yushan <yushan@uber.com>
Co-authored-by: Douglas Thor <dougthor42@users.noreply.github.com>
amartani pushed a commit to benchling/rules_python that referenced this pull request Jul 8, 2025
…les (bazel-contrib#2998)
Remove entry point file requirements when generating rules. Enable
python rule generation as long as there are .py source files under the
directory so all new packages will have python rules generated in the
package.
The extension used to require entrypoints for generation but:
- entry point for tests (i.e., `__test__.py` ) is no longer required
after bazel-contrib#999 and
bazel-contrib#2044
- entry point for binaries (i.e., `__main__.py` ) is no longer required
after bazel-contrib#1584
The entry point for libraries (`__init__.py` ) shouldn't be required
either, especially for Python 3.3 and after when namespace packages are
supported.
---------
Co-authored-by: yushan <yushan@uber.com>
Co-authored-by: Douglas Thor <dougthor42@users.noreply.github.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

@linzhp@f0rmiga