Add a pytest rules - #464

Closed
AutomatedTester wants to merge 1 commit into
bazel-contrib:mainfrom
AutomatedTester:pytest
Closed

Add a pytest rules#464
AutomatedTester wants to merge 1 commit into
bazel-contrib:mainfrom
AutomatedTester:pytest

Conversation

@AutomatedTester

Copy link
Copy Markdown
Contributor

PR Checklist

Please check if your PR fulfills the following requirements:

  • Does not include precompiled binaries, eg. .par files. See CONTRIBUTING.md for info
  • 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?

Issue Number: N/A

What is the new behavior?

Does this PR introduce a breaking change?

  • Yes
  • No

Other information

@thundergolferthundergolfer left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Thanks for kicking this off. Will be taking it for a spin in https://github.com/thundergolfer-playground/rules_python-pr-464

Comment threadpython/pytest.bzl
},
)

def pytest_test(name, srcs, deps = None, args = None, data = None, python_version = None, **kwargs):

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

py_pytest_test, like Dropbox uses? I like that it preserves the standard py_ prefix.

Comment threadexamples/pytest/BUILD
load("@pip//:requirements.bzl", "requirement")

TEST_DEPS = [
requirement("pluggy"),

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Where are these deps coming from? The relevant requirements.txt file is empty in the PR.

Comment threadpython/pytest.bzl
import sys
import pytest

args = ["-ra"] + %s + sys.argv[1:] + %s

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Was going to request --long-args for readability but seems it's just -r chars provided by pytest, lame.

Comment threadpython/suite.bzl

tests.append(test_name)

pytest_test(

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Don't think we should have the 'generic py_test_suite delegate to a pytest test implementation. I think everything using pytest (which is a third-party dep and not stock python) should include "pytest" in the rule name.

Comment threadpython/suite.bzl
)
native.test_suite(
name = name,
tests = tests,

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

If the tests attribute is unspecified or empty, the rule will default to including all test rules in the current BUILD file that are not tagged as manual. source

?? That's unexpected behaviour to me. I would have thought an empty list would do nothing or error. Do you have experience with _test_suite rules that wrap native.test_suite? Do rule authors keep this odd behaviour?

Comment threadpython/pytest.bzl
name = name,
python_version = python_version,
srcs = srcs + [runner_target],
deps = deps,

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Think that users of the any _pytest_test rule should get pytest as a provided dependency, like here: https://github.com/dropbox/dbx_build_tools/blob/fe5c9e668a9e6951970c0595089742d8a0247b8c/build_tools/py/py.bzl#L1011

Is there an problem with that approach I'm not seeing?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Only issue I can think of involves which version of pytest to use. Presumably users need to have it in their requirements.txt, or we inject a default version if not. We should definitely add requirement("pytest") to deps if it doesn't exist.

Other related issues include user provided plugin version eg. pytest_coverage which need to resolve with pytest, and how / when to add those deps to the py_pytest_test rule.

Comment threadpython/pytest.bzl
def pytest_test(name, srcs, deps = None, args = None, data = None, python_version = None, **kwargs):
runner_target = "%s-runner.py" % name

_pytest_runner(

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

What necessitates the creation of a separate executable? Can we just have a special py_test.main program? It looks like that's maybe what's happening as the py_test.main value is main = runner_target. The _pytest_runner target creates the runner file. But then why is the _pytest_runneritself executable?

@thundergolferthundergolfer mentioned this pull request May 12, 2021
@joshua-cannon-techlabs

Copy link
Copy Markdown

Firstly, I would absolutely love to see pytest support in the stock bazel rules.

However, one thing that worries me is capturing the invisible dependency between test files and conftest.py files. Pytest-the-framework will load those to find customizations and fixtures which tests use without a paper-trail. (See pytest's doc).

So if the user is specifying the test, someone (is it them or the framework?) should be declaring those dependencies (conftest.py all the way up). I would argue the framework should, as it's painfully easy to get wrong from the user's perspective.

The same goes for the test suit rule.

@hrfullerhrfuller left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I'd love to revive this PR. As a first pass we can't and shouldn't aim to support all the configurability of pytest, but we should let users passthrough pytest args to the stub script that invokes it.

Other things to consider are:

  • How to treat configuration files we find in the test sandbox, easiest thing at first would be to ignore custom configs.
  • we should amend the srcs of the underlying native.py_test to include a glob for
    **/conftest.py as someone mentioned in a comment.

Comment threadpython/pytest.bzl
expanded_args = [ctx.expand_location(arg, ctx.attr.data) for arg in ctx.attr.args]

runner = ctx.actions.declare_file(ctx.attr.name)
ctx.actions.write(

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This should be a template substitution action.

Comment threadpython/pytest.bzl
name = name,
python_version = python_version,
srcs = srcs + [runner_target],
deps = deps,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Only issue I can think of involves which version of pytest to use. Presumably users need to have it in their requirements.txt, or we inject a default version if not. We should definitely add requirement("pytest") to deps if it doesn't exist.

Other related issues include user provided plugin version eg. pytest_coverage which need to resolve with pytest, and how / when to add those deps to the py_pytest_test rule.

@aignas

Copy link
Copy Markdown
Collaborator

When someone comes back to this, consider adding extra arguments to change how pytest is changing the import path. I did some investigation as to why pytest tests where failing when I was using protobuf rules here: https://github.com/aignas/bazel_pytest_proto

@betaboon

betaboon commented May 21, 2022

Copy link
Copy Markdown
Contributor

@AutomatedTester are you planning/willing to pick this up again, or would you prefer someone else taking it over?

@everyone else in here: what would be a minimal setup of changes required here to get this merged?

i see the following todo-list:

  • address (all) the review-comments
  • clear up if we want to implicitly supply a pytest and if so how

i would argue we shouldn't aim for adressing all eventualities at first, otherwise this would never get in in any form.

just for clarification: i would be willing to take this over under the condition that there is a willingness for constructive cooperation and eventually compromise.

@AutomatedTester

Copy link
Copy Markdown
ContributorAuthor

@AutomatedTester are you planning/willing to pick this up again, or would you prefer someone else taking it over?

Happy for someone to take this over, I haven't had time to do it.

@thundergolfer

Copy link
Copy Markdown

Heads up that #723 may supersede this.

@github-actions

Copy link
Copy Markdown
Contributor

This Pull Request has been automatically marked as stale because it has not had any activity for 180 days. It will be closed if no further activity occurs in 30 days.
Collaborators can add an assignee to keep this open indefinitely. Thanks for your contributions to rules_python!

@github-actionsgithub-actionsBot added the Can Close? Will close in 30 days if there is no new activity label Dec 19, 2022
@github-actions

Copy link
Copy Markdown
Contributor

This PR was automatically closed because it went 30 days without a reply since it was labeled "Can Close?"

@alexeagle

Copy link
Copy Markdown
Contributor

Note, https://docs.aspect.build/rules/aspect_rules_py/docs/rules#py_pytest_main provides missing glue for pytest, thanks to @mattem and @f0rmiga

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Can Close?Will close in 30 days if there is no new activitycla: yes

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants

@AutomatedTester@joshua-cannon-techlabs@aignas@betaboon@thundergolfer@alexeagle@hrfuller
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n 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;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

Add a pytest rules - #464

Closed
AutomatedTester wants to merge 1 commit into
bazel-contrib:mainfrom
AutomatedTester:pytest
Closed

Add a pytest rules#464
AutomatedTester wants to merge 1 commit into
bazel-contrib:mainfrom
AutomatedTester:pytest

Conversation

@AutomatedTester

Copy link
Copy Markdown
Contributor

PR Checklist

Please check if your PR fulfills the following requirements:

  • Does not include precompiled binaries, eg. .par files. See CONTRIBUTING.md for info
  • 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?

Issue Number: N/A

What is the new behavior?

Does this PR introduce a breaking change?

  • Yes
  • No

Other information

@thundergolferthundergolfer left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Thanks for kicking this off. Will be taking it for a spin in https://github.com/thundergolfer-playground/rules_python-pr-464

Comment threadpython/pytest.bzl
},
)

def pytest_test(name, srcs, deps = None, args = None, data = None, python_version = None, **kwargs):

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

py_pytest_test, like Dropbox uses? I like that it preserves the standard py_ prefix.

Comment threadexamples/pytest/BUILD
load("@pip//:requirements.bzl", "requirement")

TEST_DEPS = [
requirement("pluggy"),

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Where are these deps coming from? The relevant requirements.txt file is empty in the PR.

Comment threadpython/pytest.bzl
import sys
import pytest

args = ["-ra"] + %s + sys.argv[1:] + %s

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Was going to request --long-args for readability but seems it's just -r chars provided by pytest, lame.

Comment threadpython/suite.bzl

tests.append(test_name)

pytest_test(

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Don't think we should have the 'generic py_test_suite delegate to a pytest test implementation. I think everything using pytest (which is a third-party dep and not stock python) should include "pytest" in the rule name.

Comment threadpython/suite.bzl
)
native.test_suite(
name = name,
tests = tests,

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

If the tests attribute is unspecified or empty, the rule will default to including all test rules in the current BUILD file that are not tagged as manual. source

?? That's unexpected behaviour to me. I would have thought an empty list would do nothing or error. Do you have experience with _test_suite rules that wrap native.test_suite? Do rule authors keep this odd behaviour?

Comment threadpython/pytest.bzl
name = name,
python_version = python_version,
srcs = srcs + [runner_target],
deps = deps,

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Think that users of the any _pytest_test rule should get pytest as a provided dependency, like here: https://github.com/dropbox/dbx_build_tools/blob/fe5c9e668a9e6951970c0595089742d8a0247b8c/build_tools/py/py.bzl#L1011

Is there an problem with that approach I'm not seeing?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Only issue I can think of involves which version of pytest to use. Presumably users need to have it in their requirements.txt, or we inject a default version if not. We should definitely add requirement("pytest") to deps if it doesn't exist.

Other related issues include user provided plugin version eg. pytest_coverage which need to resolve with pytest, and how / when to add those deps to the py_pytest_test rule.

Comment threadpython/pytest.bzl
def pytest_test(name, srcs, deps = None, args = None, data = None, python_version = None, **kwargs):
runner_target = "%s-runner.py" % name

_pytest_runner(

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

What necessitates the creation of a separate executable? Can we just have a special py_test.main program? It looks like that's maybe what's happening as the py_test.main value is main = runner_target. The _pytest_runner target creates the runner file. But then why is the _pytest_runneritself executable?

@thundergolferthundergolfer mentioned this pull request May 12, 2021
@joshua-cannon-techlabs

Copy link
Copy Markdown

Firstly, I would absolutely love to see pytest support in the stock bazel rules.

However, one thing that worries me is capturing the invisible dependency between test files and conftest.py files. Pytest-the-framework will load those to find customizations and fixtures which tests use without a paper-trail. (See pytest's doc).

So if the user is specifying the test, someone (is it them or the framework?) should be declaring those dependencies (conftest.py all the way up). I would argue the framework should, as it's painfully easy to get wrong from the user's perspective.

The same goes for the test suit rule.

@hrfullerhrfuller left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I'd love to revive this PR. As a first pass we can't and shouldn't aim to support all the configurability of pytest, but we should let users passthrough pytest args to the stub script that invokes it.

Other things to consider are:

  • How to treat configuration files we find in the test sandbox, easiest thing at first would be to ignore custom configs.
  • we should amend the srcs of the underlying native.py_test to include a glob for
    **/conftest.py as someone mentioned in a comment.

Comment threadpython/pytest.bzl
expanded_args = [ctx.expand_location(arg, ctx.attr.data) for arg in ctx.attr.args]

runner = ctx.actions.declare_file(ctx.attr.name)
ctx.actions.write(

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This should be a template substitution action.

Comment threadpython/pytest.bzl
name = name,
python_version = python_version,
srcs = srcs + [runner_target],
deps = deps,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Only issue I can think of involves which version of pytest to use. Presumably users need to have it in their requirements.txt, or we inject a default version if not. We should definitely add requirement("pytest") to deps if it doesn't exist.

Other related issues include user provided plugin version eg. pytest_coverage which need to resolve with pytest, and how / when to add those deps to the py_pytest_test rule.

@aignas

Copy link
Copy Markdown
Collaborator

When someone comes back to this, consider adding extra arguments to change how pytest is changing the import path. I did some investigation as to why pytest tests where failing when I was using protobuf rules here: https://github.com/aignas/bazel_pytest_proto

@betaboon

betaboon commented May 21, 2022

Copy link
Copy Markdown
Contributor

@AutomatedTester are you planning/willing to pick this up again, or would you prefer someone else taking it over?

@everyone else in here: what would be a minimal setup of changes required here to get this merged?

i see the following todo-list:

  • address (all) the review-comments
  • clear up if we want to implicitly supply a pytest and if so how

i would argue we shouldn't aim for adressing all eventualities at first, otherwise this would never get in in any form.

just for clarification: i would be willing to take this over under the condition that there is a willingness for constructive cooperation and eventually compromise.

@AutomatedTester

Copy link
Copy Markdown
ContributorAuthor

@AutomatedTester are you planning/willing to pick this up again, or would you prefer someone else taking it over?

Happy for someone to take this over, I haven't had time to do it.

@thundergolfer

Copy link
Copy Markdown

Heads up that #723 may supersede this.

@github-actions

Copy link
Copy Markdown
Contributor

This Pull Request has been automatically marked as stale because it has not had any activity for 180 days. It will be closed if no further activity occurs in 30 days.
Collaborators can add an assignee to keep this open indefinitely. Thanks for your contributions to rules_python!

@github-actionsgithub-actionsBot added the Can Close? Will close in 30 days if there is no new activity label Dec 19, 2022
@github-actions

Copy link
Copy Markdown
Contributor

This PR was automatically closed because it went 30 days without a reply since it was labeled "Can Close?"

@alexeagle

Copy link
Copy Markdown
Contributor

Note, https://docs.aspect.build/rules/aspect_rules_py/docs/rules#py_pytest_main provides missing glue for pytest, thanks to @mattem and @f0rmiga

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Can Close?Will close in 30 days if there is no new activitycla: yes

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants

@AutomatedTester@joshua-cannon-techlabs@aignas@betaboon@thundergolfer@alexeagle@hrfuller
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Add a pytest rules - #464

Closed
AutomatedTester wants to merge 1 commit into
bazel-contrib:mainfrom
AutomatedTester:pytest
Closed

Add a pytest rules#464
AutomatedTester wants to merge 1 commit into
bazel-contrib:mainfrom
AutomatedTester:pytest

Conversation

@AutomatedTester

Copy link
Copy Markdown
Contributor

PR Checklist

Please check if your PR fulfills the following requirements:

  • Does not include precompiled binaries, eg. .par files. See CONTRIBUTING.md for info
  • 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?

Issue Number: N/A

What is the new behavior?

Does this PR introduce a breaking change?

  • Yes
  • No

Other information

@thundergolferthundergolfer left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Thanks for kicking this off. Will be taking it for a spin in https://github.com/thundergolfer-playground/rules_python-pr-464

Comment threadpython/pytest.bzl
},
)

def pytest_test(name, srcs, deps = None, args = None, data = None, python_version = None, **kwargs):

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

py_pytest_test, like Dropbox uses? I like that it preserves the standard py_ prefix.

Comment threadexamples/pytest/BUILD
load("@pip//:requirements.bzl", "requirement")

TEST_DEPS = [
requirement("pluggy"),

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Where are these deps coming from? The relevant requirements.txt file is empty in the PR.

Comment threadpython/pytest.bzl
import sys
import pytest

args = ["-ra"] + %s + sys.argv[1:] + %s

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Was going to request --long-args for readability but seems it's just -r chars provided by pytest, lame.

Comment threadpython/suite.bzl

tests.append(test_name)

pytest_test(

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Don't think we should have the 'generic py_test_suite delegate to a pytest test implementation. I think everything using pytest (which is a third-party dep and not stock python) should include "pytest" in the rule name.

Comment threadpython/suite.bzl
)
native.test_suite(
name = name,
tests = tests,

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

If the tests attribute is unspecified or empty, the rule will default to including all test rules in the current BUILD file that are not tagged as manual. source

?? That's unexpected behaviour to me. I would have thought an empty list would do nothing or error. Do you have experience with _test_suite rules that wrap native.test_suite? Do rule authors keep this odd behaviour?

Comment threadpython/pytest.bzl
name = name,
python_version = python_version,
srcs = srcs + [runner_target],
deps = deps,

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Think that users of the any _pytest_test rule should get pytest as a provided dependency, like here: https://github.com/dropbox/dbx_build_tools/blob/fe5c9e668a9e6951970c0595089742d8a0247b8c/build_tools/py/py.bzl#L1011

Is there an problem with that approach I'm not seeing?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Only issue I can think of involves which version of pytest to use. Presumably users need to have it in their requirements.txt, or we inject a default version if not. We should definitely add requirement("pytest") to deps if it doesn't exist.

Other related issues include user provided plugin version eg. pytest_coverage which need to resolve with pytest, and how / when to add those deps to the py_pytest_test rule.

Comment threadpython/pytest.bzl
def pytest_test(name, srcs, deps = None, args = None, data = None, python_version = None, **kwargs):
runner_target = "%s-runner.py" % name

_pytest_runner(

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

What necessitates the creation of a separate executable? Can we just have a special py_test.main program? It looks like that's maybe what's happening as the py_test.main value is main = runner_target. The _pytest_runner target creates the runner file. But then why is the _pytest_runneritself executable?

@thundergolferthundergolfer mentioned this pull request May 12, 2021
@joshua-cannon-techlabs

Copy link
Copy Markdown

Firstly, I would absolutely love to see pytest support in the stock bazel rules.

However, one thing that worries me is capturing the invisible dependency between test files and conftest.py files. Pytest-the-framework will load those to find customizations and fixtures which tests use without a paper-trail. (See pytest's doc).

So if the user is specifying the test, someone (is it them or the framework?) should be declaring those dependencies (conftest.py all the way up). I would argue the framework should, as it's painfully easy to get wrong from the user's perspective.

The same goes for the test suit rule.

@hrfullerhrfuller left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I'd love to revive this PR. As a first pass we can't and shouldn't aim to support all the configurability of pytest, but we should let users passthrough pytest args to the stub script that invokes it.

Other things to consider are:

  • How to treat configuration files we find in the test sandbox, easiest thing at first would be to ignore custom configs.
  • we should amend the srcs of the underlying native.py_test to include a glob for
    **/conftest.py as someone mentioned in a comment.

Comment threadpython/pytest.bzl
expanded_args = [ctx.expand_location(arg, ctx.attr.data) for arg in ctx.attr.args]

runner = ctx.actions.declare_file(ctx.attr.name)
ctx.actions.write(

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This should be a template substitution action.

Comment threadpython/pytest.bzl
name = name,
python_version = python_version,
srcs = srcs + [runner_target],
deps = deps,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Only issue I can think of involves which version of pytest to use. Presumably users need to have it in their requirements.txt, or we inject a default version if not. We should definitely add requirement("pytest") to deps if it doesn't exist.

Other related issues include user provided plugin version eg. pytest_coverage which need to resolve with pytest, and how / when to add those deps to the py_pytest_test rule.

@aignas

Copy link
Copy Markdown
Collaborator

When someone comes back to this, consider adding extra arguments to change how pytest is changing the import path. I did some investigation as to why pytest tests where failing when I was using protobuf rules here: https://github.com/aignas/bazel_pytest_proto

@betaboon

betaboon commented May 21, 2022

Copy link
Copy Markdown
Contributor

@AutomatedTester are you planning/willing to pick this up again, or would you prefer someone else taking it over?

@everyone else in here: what would be a minimal setup of changes required here to get this merged?

i see the following todo-list:

  • address (all) the review-comments
  • clear up if we want to implicitly supply a pytest and if so how

i would argue we shouldn't aim for adressing all eventualities at first, otherwise this would never get in in any form.

just for clarification: i would be willing to take this over under the condition that there is a willingness for constructive cooperation and eventually compromise.

@AutomatedTester

Copy link
Copy Markdown
ContributorAuthor

@AutomatedTester are you planning/willing to pick this up again, or would you prefer someone else taking it over?

Happy for someone to take this over, I haven't had time to do it.

@thundergolfer

Copy link
Copy Markdown

Heads up that #723 may supersede this.

@github-actions

Copy link
Copy Markdown
Contributor

This Pull Request has been automatically marked as stale because it has not had any activity for 180 days. It will be closed if no further activity occurs in 30 days.
Collaborators can add an assignee to keep this open indefinitely. Thanks for your contributions to rules_python!

@github-actionsgithub-actionsBot added the Can Close? Will close in 30 days if there is no new activity label Dec 19, 2022
@github-actions

Copy link
Copy Markdown
Contributor

This PR was automatically closed because it went 30 days without a reply since it was labeled "Can Close?"

@alexeagle

Copy link
Copy Markdown
Contributor

Note, https://docs.aspect.build/rules/aspect_rules_py/docs/rules#py_pytest_main provides missing glue for pytest, thanks to @mattem and @f0rmiga

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Can Close?Will close in 30 days if there is no new activitycla: yes

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants

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

Add a pytest rules - #464

Closed
AutomatedTester wants to merge 1 commit into
bazel-contrib:mainfrom
AutomatedTester:pytest
Closed

Add a pytest rules#464
AutomatedTester wants to merge 1 commit into
bazel-contrib:mainfrom
AutomatedTester:pytest

Conversation

@AutomatedTester

Copy link
Copy Markdown
Contributor

PR Checklist

Please check if your PR fulfills the following requirements:

  • Does not include precompiled binaries, eg. .par files. See CONTRIBUTING.md for info
  • 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?

Issue Number: N/A

What is the new behavior?

Does this PR introduce a breaking change?

  • Yes
  • No

Other information

@thundergolferthundergolfer left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Thanks for kicking this off. Will be taking it for a spin in https://github.com/thundergolfer-playground/rules_python-pr-464

Comment threadpython/pytest.bzl
},
)

def pytest_test(name, srcs, deps = None, args = None, data = None, python_version = None, **kwargs):

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

py_pytest_test, like Dropbox uses? I like that it preserves the standard py_ prefix.

Comment threadexamples/pytest/BUILD
load("@pip//:requirements.bzl", "requirement")

TEST_DEPS = [
requirement("pluggy"),

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Where are these deps coming from? The relevant requirements.txt file is empty in the PR.

Comment threadpython/pytest.bzl
import sys
import pytest

args = ["-ra"] + %s + sys.argv[1:] + %s

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Was going to request --long-args for readability but seems it's just -r chars provided by pytest, lame.

Comment threadpython/suite.bzl

tests.append(test_name)

pytest_test(

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Don't think we should have the 'generic py_test_suite delegate to a pytest test implementation. I think everything using pytest (which is a third-party dep and not stock python) should include "pytest" in the rule name.

Comment threadpython/suite.bzl
)
native.test_suite(
name = name,
tests = tests,

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

If the tests attribute is unspecified or empty, the rule will default to including all test rules in the current BUILD file that are not tagged as manual. source

?? That's unexpected behaviour to me. I would have thought an empty list would do nothing or error. Do you have experience with _test_suite rules that wrap native.test_suite? Do rule authors keep this odd behaviour?

Comment threadpython/pytest.bzl
name = name,
python_version = python_version,
srcs = srcs + [runner_target],
deps = deps,

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Think that users of the any _pytest_test rule should get pytest as a provided dependency, like here: https://github.com/dropbox/dbx_build_tools/blob/fe5c9e668a9e6951970c0595089742d8a0247b8c/build_tools/py/py.bzl#L1011

Is there an problem with that approach I'm not seeing?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Only issue I can think of involves which version of pytest to use. Presumably users need to have it in their requirements.txt, or we inject a default version if not. We should definitely add requirement("pytest") to deps if it doesn't exist.

Other related issues include user provided plugin version eg. pytest_coverage which need to resolve with pytest, and how / when to add those deps to the py_pytest_test rule.

Comment threadpython/pytest.bzl
def pytest_test(name, srcs, deps = None, args = None, data = None, python_version = None, **kwargs):
runner_target = "%s-runner.py" % name

_pytest_runner(

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

What necessitates the creation of a separate executable? Can we just have a special py_test.main program? It looks like that's maybe what's happening as the py_test.main value is main = runner_target. The _pytest_runner target creates the runner file. But then why is the _pytest_runneritself executable?

@thundergolferthundergolfer mentioned this pull request May 12, 2021
@joshua-cannon-techlabs

Copy link
Copy Markdown

Firstly, I would absolutely love to see pytest support in the stock bazel rules.

However, one thing that worries me is capturing the invisible dependency between test files and conftest.py files. Pytest-the-framework will load those to find customizations and fixtures which tests use without a paper-trail. (See pytest's doc).

So if the user is specifying the test, someone (is it them or the framework?) should be declaring those dependencies (conftest.py all the way up). I would argue the framework should, as it's painfully easy to get wrong from the user's perspective.

The same goes for the test suit rule.

@hrfullerhrfuller left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I'd love to revive this PR. As a first pass we can't and shouldn't aim to support all the configurability of pytest, but we should let users passthrough pytest args to the stub script that invokes it.

Other things to consider are:

  • How to treat configuration files we find in the test sandbox, easiest thing at first would be to ignore custom configs.
  • we should amend the srcs of the underlying native.py_test to include a glob for
    **/conftest.py as someone mentioned in a comment.

Comment threadpython/pytest.bzl
expanded_args = [ctx.expand_location(arg, ctx.attr.data) for arg in ctx.attr.args]

runner = ctx.actions.declare_file(ctx.attr.name)
ctx.actions.write(

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This should be a template substitution action.

Comment threadpython/pytest.bzl
name = name,
python_version = python_version,
srcs = srcs + [runner_target],
deps = deps,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Only issue I can think of involves which version of pytest to use. Presumably users need to have it in their requirements.txt, or we inject a default version if not. We should definitely add requirement("pytest") to deps if it doesn't exist.

Other related issues include user provided plugin version eg. pytest_coverage which need to resolve with pytest, and how / when to add those deps to the py_pytest_test rule.

@aignas

Copy link
Copy Markdown
Collaborator

When someone comes back to this, consider adding extra arguments to change how pytest is changing the import path. I did some investigation as to why pytest tests where failing when I was using protobuf rules here: https://github.com/aignas/bazel_pytest_proto

@betaboon

betaboon commented May 21, 2022

Copy link
Copy Markdown
Contributor

@AutomatedTester are you planning/willing to pick this up again, or would you prefer someone else taking it over?

@everyone else in here: what would be a minimal setup of changes required here to get this merged?

i see the following todo-list:

  • address (all) the review-comments
  • clear up if we want to implicitly supply a pytest and if so how

i would argue we shouldn't aim for adressing all eventualities at first, otherwise this would never get in in any form.

just for clarification: i would be willing to take this over under the condition that there is a willingness for constructive cooperation and eventually compromise.

@AutomatedTester

Copy link
Copy Markdown
ContributorAuthor

@AutomatedTester are you planning/willing to pick this up again, or would you prefer someone else taking it over?

Happy for someone to take this over, I haven't had time to do it.

@thundergolfer

Copy link
Copy Markdown

Heads up that #723 may supersede this.

@github-actions

Copy link
Copy Markdown
Contributor

This Pull Request has been automatically marked as stale because it has not had any activity for 180 days. It will be closed if no further activity occurs in 30 days.
Collaborators can add an assignee to keep this open indefinitely. Thanks for your contributions to rules_python!

@github-actionsgithub-actionsBot added the Can Close? Will close in 30 days if there is no new activity label Dec 19, 2022
@github-actions

Copy link
Copy Markdown
Contributor

This PR was automatically closed because it went 30 days without a reply since it was labeled "Can Close?"

@alexeagle

Copy link
Copy Markdown
Contributor

Note, https://docs.aspect.build/rules/aspect_rules_py/docs/rules#py_pytest_main provides missing glue for pytest, thanks to @mattem and @f0rmiga

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Can Close?Will close in 30 days if there is no new activitycla: yes

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants

@AutomatedTester@joshua-cannon-techlabs@aignas@betaboon@thundergolfer@alexeagle@hrfuller
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

Add a pytest rules - #464

Closed
AutomatedTester wants to merge 1 commit into
bazel-contrib:mainfrom
AutomatedTester:pytest
Closed

Add a pytest rules#464
AutomatedTester wants to merge 1 commit into
bazel-contrib:mainfrom
AutomatedTester:pytest

Conversation

@AutomatedTester

Copy link
Copy Markdown
Contributor

PR Checklist

Please check if your PR fulfills the following requirements:

  • Does not include precompiled binaries, eg. .par files. See CONTRIBUTING.md for info
  • 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?

Issue Number: N/A

What is the new behavior?

Does this PR introduce a breaking change?

  • Yes
  • No

Other information

@thundergolferthundergolfer left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Thanks for kicking this off. Will be taking it for a spin in https://github.com/thundergolfer-playground/rules_python-pr-464

Comment threadpython/pytest.bzl
},
)

def pytest_test(name, srcs, deps = None, args = None, data = None, python_version = None, **kwargs):

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

py_pytest_test, like Dropbox uses? I like that it preserves the standard py_ prefix.

Comment threadexamples/pytest/BUILD
load("@pip//:requirements.bzl", "requirement")

TEST_DEPS = [
requirement("pluggy"),

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Where are these deps coming from? The relevant requirements.txt file is empty in the PR.

Comment threadpython/pytest.bzl
import sys
import pytest

args = ["-ra"] + %s + sys.argv[1:] + %s

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Was going to request --long-args for readability but seems it's just -r chars provided by pytest, lame.

Comment threadpython/suite.bzl

tests.append(test_name)

pytest_test(

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Don't think we should have the 'generic py_test_suite delegate to a pytest test implementation. I think everything using pytest (which is a third-party dep and not stock python) should include "pytest" in the rule name.

Comment threadpython/suite.bzl
)
native.test_suite(
name = name,
tests = tests,

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

If the tests attribute is unspecified or empty, the rule will default to including all test rules in the current BUILD file that are not tagged as manual. source

?? That's unexpected behaviour to me. I would have thought an empty list would do nothing or error. Do you have experience with _test_suite rules that wrap native.test_suite? Do rule authors keep this odd behaviour?

Comment threadpython/pytest.bzl
name = name,
python_version = python_version,
srcs = srcs + [runner_target],
deps = deps,

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Think that users of the any _pytest_test rule should get pytest as a provided dependency, like here: https://github.com/dropbox/dbx_build_tools/blob/fe5c9e668a9e6951970c0595089742d8a0247b8c/build_tools/py/py.bzl#L1011

Is there an problem with that approach I'm not seeing?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Only issue I can think of involves which version of pytest to use. Presumably users need to have it in their requirements.txt, or we inject a default version if not. We should definitely add requirement("pytest") to deps if it doesn't exist.

Other related issues include user provided plugin version eg. pytest_coverage which need to resolve with pytest, and how / when to add those deps to the py_pytest_test rule.

Comment threadpython/pytest.bzl
def pytest_test(name, srcs, deps = None, args = None, data = None, python_version = None, **kwargs):
runner_target = "%s-runner.py" % name

_pytest_runner(

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

What necessitates the creation of a separate executable? Can we just have a special py_test.main program? It looks like that's maybe what's happening as the py_test.main value is main = runner_target. The _pytest_runner target creates the runner file. But then why is the _pytest_runneritself executable?

@thundergolferthundergolfer mentioned this pull request May 12, 2021
@joshua-cannon-techlabs

Copy link
Copy Markdown

Firstly, I would absolutely love to see pytest support in the stock bazel rules.

However, one thing that worries me is capturing the invisible dependency between test files and conftest.py files. Pytest-the-framework will load those to find customizations and fixtures which tests use without a paper-trail. (See pytest's doc).

So if the user is specifying the test, someone (is it them or the framework?) should be declaring those dependencies (conftest.py all the way up). I would argue the framework should, as it's painfully easy to get wrong from the user's perspective.

The same goes for the test suit rule.

@hrfullerhrfuller left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I'd love to revive this PR. As a first pass we can't and shouldn't aim to support all the configurability of pytest, but we should let users passthrough pytest args to the stub script that invokes it.

Other things to consider are:

  • How to treat configuration files we find in the test sandbox, easiest thing at first would be to ignore custom configs.
  • we should amend the srcs of the underlying native.py_test to include a glob for
    **/conftest.py as someone mentioned in a comment.

Comment threadpython/pytest.bzl
expanded_args = [ctx.expand_location(arg, ctx.attr.data) for arg in ctx.attr.args]

runner = ctx.actions.declare_file(ctx.attr.name)
ctx.actions.write(

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This should be a template substitution action.

Comment threadpython/pytest.bzl
name = name,
python_version = python_version,
srcs = srcs + [runner_target],
deps = deps,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Only issue I can think of involves which version of pytest to use. Presumably users need to have it in their requirements.txt, or we inject a default version if not. We should definitely add requirement("pytest") to deps if it doesn't exist.

Other related issues include user provided plugin version eg. pytest_coverage which need to resolve with pytest, and how / when to add those deps to the py_pytest_test rule.

@aignas

Copy link
Copy Markdown
Collaborator

When someone comes back to this, consider adding extra arguments to change how pytest is changing the import path. I did some investigation as to why pytest tests where failing when I was using protobuf rules here: https://github.com/aignas/bazel_pytest_proto

@betaboon

betaboon commented May 21, 2022

Copy link
Copy Markdown
Contributor

@AutomatedTester are you planning/willing to pick this up again, or would you prefer someone else taking it over?

@everyone else in here: what would be a minimal setup of changes required here to get this merged?

i see the following todo-list:

  • address (all) the review-comments
  • clear up if we want to implicitly supply a pytest and if so how

i would argue we shouldn't aim for adressing all eventualities at first, otherwise this would never get in in any form.

just for clarification: i would be willing to take this over under the condition that there is a willingness for constructive cooperation and eventually compromise.

@AutomatedTester

Copy link
Copy Markdown
ContributorAuthor

@AutomatedTester are you planning/willing to pick this up again, or would you prefer someone else taking it over?

Happy for someone to take this over, I haven't had time to do it.

@thundergolfer

Copy link
Copy Markdown

Heads up that #723 may supersede this.

@github-actions

Copy link
Copy Markdown
Contributor

This Pull Request has been automatically marked as stale because it has not had any activity for 180 days. It will be closed if no further activity occurs in 30 days.
Collaborators can add an assignee to keep this open indefinitely. Thanks for your contributions to rules_python!

@github-actionsgithub-actionsBot added the Can Close? Will close in 30 days if there is no new activity label Dec 19, 2022
@github-actions

Copy link
Copy Markdown
Contributor

This PR was automatically closed because it went 30 days without a reply since it was labeled "Can Close?"

@alexeagle

Copy link
Copy Markdown
Contributor

Note, https://docs.aspect.build/rules/aspect_rules_py/docs/rules#py_pytest_main provides missing glue for pytest, thanks to @mattem and @f0rmiga

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Can Close?Will close in 30 days if there is no new activitycla: yes

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants

@AutomatedTester@joshua-cannon-techlabs@aignas@betaboon@thundergolfer@alexeagle@hrfuller
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Add a pytest rules - #464

Closed
AutomatedTester wants to merge 1 commit into
bazel-contrib:mainfrom
AutomatedTester:pytest
Closed

Add a pytest rules#464
AutomatedTester wants to merge 1 commit into
bazel-contrib:mainfrom
AutomatedTester:pytest

Conversation

@AutomatedTester

Copy link
Copy Markdown
Contributor

PR Checklist

Please check if your PR fulfills the following requirements:

  • Does not include precompiled binaries, eg. .par files. See CONTRIBUTING.md for info
  • 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?

Issue Number: N/A

What is the new behavior?

Does this PR introduce a breaking change?

  • Yes
  • No

Other information

@thundergolferthundergolfer left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Thanks for kicking this off. Will be taking it for a spin in https://github.com/thundergolfer-playground/rules_python-pr-464

Comment threadpython/pytest.bzl
},
)

def pytest_test(name, srcs, deps = None, args = None, data = None, python_version = None, **kwargs):

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

py_pytest_test, like Dropbox uses? I like that it preserves the standard py_ prefix.

Comment threadexamples/pytest/BUILD
load("@pip//:requirements.bzl", "requirement")

TEST_DEPS = [
requirement("pluggy"),

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Where are these deps coming from? The relevant requirements.txt file is empty in the PR.

Comment threadpython/pytest.bzl
import sys
import pytest

args = ["-ra"] + %s + sys.argv[1:] + %s

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Was going to request --long-args for readability but seems it's just -r chars provided by pytest, lame.

Comment threadpython/suite.bzl

tests.append(test_name)

pytest_test(

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Don't think we should have the 'generic py_test_suite delegate to a pytest test implementation. I think everything using pytest (which is a third-party dep and not stock python) should include "pytest" in the rule name.

Comment threadpython/suite.bzl
)
native.test_suite(
name = name,
tests = tests,

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

If the tests attribute is unspecified or empty, the rule will default to including all test rules in the current BUILD file that are not tagged as manual. source

?? That's unexpected behaviour to me. I would have thought an empty list would do nothing or error. Do you have experience with _test_suite rules that wrap native.test_suite? Do rule authors keep this odd behaviour?

Comment threadpython/pytest.bzl
name = name,
python_version = python_version,
srcs = srcs + [runner_target],
deps = deps,

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Think that users of the any _pytest_test rule should get pytest as a provided dependency, like here: https://github.com/dropbox/dbx_build_tools/blob/fe5c9e668a9e6951970c0595089742d8a0247b8c/build_tools/py/py.bzl#L1011

Is there an problem with that approach I'm not seeing?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Only issue I can think of involves which version of pytest to use. Presumably users need to have it in their requirements.txt, or we inject a default version if not. We should definitely add requirement("pytest") to deps if it doesn't exist.

Other related issues include user provided plugin version eg. pytest_coverage which need to resolve with pytest, and how / when to add those deps to the py_pytest_test rule.

Comment threadpython/pytest.bzl
def pytest_test(name, srcs, deps = None, args = None, data = None, python_version = None, **kwargs):
runner_target = "%s-runner.py" % name

_pytest_runner(

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

What necessitates the creation of a separate executable? Can we just have a special py_test.main program? It looks like that's maybe what's happening as the py_test.main value is main = runner_target. The _pytest_runner target creates the runner file. But then why is the _pytest_runneritself executable?

@thundergolferthundergolfer mentioned this pull request May 12, 2021
@joshua-cannon-techlabs

Copy link
Copy Markdown

Firstly, I would absolutely love to see pytest support in the stock bazel rules.

However, one thing that worries me is capturing the invisible dependency between test files and conftest.py files. Pytest-the-framework will load those to find customizations and fixtures which tests use without a paper-trail. (See pytest's doc).

So if the user is specifying the test, someone (is it them or the framework?) should be declaring those dependencies (conftest.py all the way up). I would argue the framework should, as it's painfully easy to get wrong from the user's perspective.

The same goes for the test suit rule.

@hrfullerhrfuller left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I'd love to revive this PR. As a first pass we can't and shouldn't aim to support all the configurability of pytest, but we should let users passthrough pytest args to the stub script that invokes it.

Other things to consider are:

  • How to treat configuration files we find in the test sandbox, easiest thing at first would be to ignore custom configs.
  • we should amend the srcs of the underlying native.py_test to include a glob for
    **/conftest.py as someone mentioned in a comment.

Comment threadpython/pytest.bzl
expanded_args = [ctx.expand_location(arg, ctx.attr.data) for arg in ctx.attr.args]

runner = ctx.actions.declare_file(ctx.attr.name)
ctx.actions.write(

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This should be a template substitution action.

Comment threadpython/pytest.bzl
name = name,
python_version = python_version,
srcs = srcs + [runner_target],
deps = deps,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Only issue I can think of involves which version of pytest to use. Presumably users need to have it in their requirements.txt, or we inject a default version if not. We should definitely add requirement("pytest") to deps if it doesn't exist.

Other related issues include user provided plugin version eg. pytest_coverage which need to resolve with pytest, and how / when to add those deps to the py_pytest_test rule.

@aignas

Copy link
Copy Markdown
Collaborator

When someone comes back to this, consider adding extra arguments to change how pytest is changing the import path. I did some investigation as to why pytest tests where failing when I was using protobuf rules here: https://github.com/aignas/bazel_pytest_proto

@betaboon

betaboon commented May 21, 2022

Copy link
Copy Markdown
Contributor

@AutomatedTester are you planning/willing to pick this up again, or would you prefer someone else taking it over?

@everyone else in here: what would be a minimal setup of changes required here to get this merged?

i see the following todo-list:

  • address (all) the review-comments
  • clear up if we want to implicitly supply a pytest and if so how

i would argue we shouldn't aim for adressing all eventualities at first, otherwise this would never get in in any form.

just for clarification: i would be willing to take this over under the condition that there is a willingness for constructive cooperation and eventually compromise.

@AutomatedTester

Copy link
Copy Markdown
ContributorAuthor

@AutomatedTester are you planning/willing to pick this up again, or would you prefer someone else taking it over?

Happy for someone to take this over, I haven't had time to do it.

@thundergolfer

Copy link
Copy Markdown

Heads up that #723 may supersede this.

@github-actions

Copy link
Copy Markdown
Contributor

This Pull Request has been automatically marked as stale because it has not had any activity for 180 days. It will be closed if no further activity occurs in 30 days.
Collaborators can add an assignee to keep this open indefinitely. Thanks for your contributions to rules_python!

@github-actionsgithub-actionsBot added the Can Close? Will close in 30 days if there is no new activity label Dec 19, 2022
@github-actions

Copy link
Copy Markdown
Contributor

This PR was automatically closed because it went 30 days without a reply since it was labeled "Can Close?"

@alexeagle

Copy link
Copy Markdown
Contributor

Note, https://docs.aspect.build/rules/aspect_rules_py/docs/rules#py_pytest_main provides missing glue for pytest, thanks to @mattem and @f0rmiga

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Can Close?Will close in 30 days if there is no new activitycla: yes

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants

@AutomatedTester@joshua-cannon-techlabs@aignas@betaboon@thundergolfer@alexeagle@hrfuller
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Add a pytest rules - #464

Closed
AutomatedTester wants to merge 1 commit into
bazel-contrib:mainfrom
AutomatedTester:pytest
Closed

Add a pytest rules#464
AutomatedTester wants to merge 1 commit into
bazel-contrib:mainfrom
AutomatedTester:pytest

Conversation

@AutomatedTester

Copy link
Copy Markdown
Contributor

PR Checklist

Please check if your PR fulfills the following requirements:

  • Does not include precompiled binaries, eg. .par files. See CONTRIBUTING.md for info
  • 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?

Issue Number: N/A

What is the new behavior?

Does this PR introduce a breaking change?

  • Yes
  • No

Other information

@thundergolferthundergolfer left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Thanks for kicking this off. Will be taking it for a spin in https://github.com/thundergolfer-playground/rules_python-pr-464

Comment threadpython/pytest.bzl
},
)

def pytest_test(name, srcs, deps = None, args = None, data = None, python_version = None, **kwargs):

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

py_pytest_test, like Dropbox uses? I like that it preserves the standard py_ prefix.

Comment threadexamples/pytest/BUILD
load("@pip//:requirements.bzl", "requirement")

TEST_DEPS = [
requirement("pluggy"),

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Where are these deps coming from? The relevant requirements.txt file is empty in the PR.

Comment threadpython/pytest.bzl
import sys
import pytest

args = ["-ra"] + %s + sys.argv[1:] + %s

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Was going to request --long-args for readability but seems it's just -r chars provided by pytest, lame.

Comment threadpython/suite.bzl

tests.append(test_name)

pytest_test(

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Don't think we should have the 'generic py_test_suite delegate to a pytest test implementation. I think everything using pytest (which is a third-party dep and not stock python) should include "pytest" in the rule name.

Comment threadpython/suite.bzl
)
native.test_suite(
name = name,
tests = tests,

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

If the tests attribute is unspecified or empty, the rule will default to including all test rules in the current BUILD file that are not tagged as manual. source

?? That's unexpected behaviour to me. I would have thought an empty list would do nothing or error. Do you have experience with _test_suite rules that wrap native.test_suite? Do rule authors keep this odd behaviour?

Comment threadpython/pytest.bzl
name = name,
python_version = python_version,
srcs = srcs + [runner_target],
deps = deps,

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Think that users of the any _pytest_test rule should get pytest as a provided dependency, like here: https://github.com/dropbox/dbx_build_tools/blob/fe5c9e668a9e6951970c0595089742d8a0247b8c/build_tools/py/py.bzl#L1011

Is there an problem with that approach I'm not seeing?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Only issue I can think of involves which version of pytest to use. Presumably users need to have it in their requirements.txt, or we inject a default version if not. We should definitely add requirement("pytest") to deps if it doesn't exist.

Other related issues include user provided plugin version eg. pytest_coverage which need to resolve with pytest, and how / when to add those deps to the py_pytest_test rule.

Comment threadpython/pytest.bzl
def pytest_test(name, srcs, deps = None, args = None, data = None, python_version = None, **kwargs):
runner_target = "%s-runner.py" % name

_pytest_runner(

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

What necessitates the creation of a separate executable? Can we just have a special py_test.main program? It looks like that's maybe what's happening as the py_test.main value is main = runner_target. The _pytest_runner target creates the runner file. But then why is the _pytest_runneritself executable?

@thundergolferthundergolfer mentioned this pull request May 12, 2021
@joshua-cannon-techlabs

Copy link
Copy Markdown

Firstly, I would absolutely love to see pytest support in the stock bazel rules.

However, one thing that worries me is capturing the invisible dependency between test files and conftest.py files. Pytest-the-framework will load those to find customizations and fixtures which tests use without a paper-trail. (See pytest's doc).

So if the user is specifying the test, someone (is it them or the framework?) should be declaring those dependencies (conftest.py all the way up). I would argue the framework should, as it's painfully easy to get wrong from the user's perspective.

The same goes for the test suit rule.

@hrfullerhrfuller left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I'd love to revive this PR. As a first pass we can't and shouldn't aim to support all the configurability of pytest, but we should let users passthrough pytest args to the stub script that invokes it.

Other things to consider are:

  • How to treat configuration files we find in the test sandbox, easiest thing at first would be to ignore custom configs.
  • we should amend the srcs of the underlying native.py_test to include a glob for
    **/conftest.py as someone mentioned in a comment.

Comment threadpython/pytest.bzl
expanded_args = [ctx.expand_location(arg, ctx.attr.data) for arg in ctx.attr.args]

runner = ctx.actions.declare_file(ctx.attr.name)
ctx.actions.write(

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This should be a template substitution action.

Comment threadpython/pytest.bzl
name = name,
python_version = python_version,
srcs = srcs + [runner_target],
deps = deps,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Only issue I can think of involves which version of pytest to use. Presumably users need to have it in their requirements.txt, or we inject a default version if not. We should definitely add requirement("pytest") to deps if it doesn't exist.

Other related issues include user provided plugin version eg. pytest_coverage which need to resolve with pytest, and how / when to add those deps to the py_pytest_test rule.

@aignas

Copy link
Copy Markdown
Collaborator

When someone comes back to this, consider adding extra arguments to change how pytest is changing the import path. I did some investigation as to why pytest tests where failing when I was using protobuf rules here: https://github.com/aignas/bazel_pytest_proto

@betaboon

betaboon commented May 21, 2022

Copy link
Copy Markdown
Contributor

@AutomatedTester are you planning/willing to pick this up again, or would you prefer someone else taking it over?

@everyone else in here: what would be a minimal setup of changes required here to get this merged?

i see the following todo-list:

  • address (all) the review-comments
  • clear up if we want to implicitly supply a pytest and if so how

i would argue we shouldn't aim for adressing all eventualities at first, otherwise this would never get in in any form.

just for clarification: i would be willing to take this over under the condition that there is a willingness for constructive cooperation and eventually compromise.

@AutomatedTester

Copy link
Copy Markdown
ContributorAuthor

@AutomatedTester are you planning/willing to pick this up again, or would you prefer someone else taking it over?

Happy for someone to take this over, I haven't had time to do it.

@thundergolfer

Copy link
Copy Markdown

Heads up that #723 may supersede this.

@github-actions

Copy link
Copy Markdown
Contributor

This Pull Request has been automatically marked as stale because it has not had any activity for 180 days. It will be closed if no further activity occurs in 30 days.
Collaborators can add an assignee to keep this open indefinitely. Thanks for your contributions to rules_python!

@github-actionsgithub-actionsBot added the Can Close? Will close in 30 days if there is no new activity label Dec 19, 2022
@github-actions

Copy link
Copy Markdown
Contributor

This PR was automatically closed because it went 30 days without a reply since it was labeled "Can Close?"

@alexeagle

Copy link
Copy Markdown
Contributor

Note, https://docs.aspect.build/rules/aspect_rules_py/docs/rules#py_pytest_main provides missing glue for pytest, thanks to @mattem and @f0rmiga

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Can Close?Will close in 30 days if there is no new activitycla: yes

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants

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

Add a pytest rules - #464

Closed
AutomatedTester wants to merge 1 commit into
bazel-contrib:mainfrom
AutomatedTester:pytest
Closed

Add a pytest rules#464
AutomatedTester wants to merge 1 commit into
bazel-contrib:mainfrom
AutomatedTester:pytest

Conversation

@AutomatedTester

Copy link
Copy Markdown
Contributor

PR Checklist

Please check if your PR fulfills the following requirements:

  • Does not include precompiled binaries, eg. .par files. See CONTRIBUTING.md for info
  • 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?

Issue Number: N/A

What is the new behavior?

Does this PR introduce a breaking change?

  • Yes
  • No

Other information

@thundergolferthundergolfer left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Thanks for kicking this off. Will be taking it for a spin in https://github.com/thundergolfer-playground/rules_python-pr-464

Comment threadpython/pytest.bzl
},
)

def pytest_test(name, srcs, deps = None, args = None, data = None, python_version = None, **kwargs):

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

py_pytest_test, like Dropbox uses? I like that it preserves the standard py_ prefix.

Comment threadexamples/pytest/BUILD
load("@pip//:requirements.bzl", "requirement")

TEST_DEPS = [
requirement("pluggy"),

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Where are these deps coming from? The relevant requirements.txt file is empty in the PR.

Comment threadpython/pytest.bzl
import sys
import pytest

args = ["-ra"] + %s + sys.argv[1:] + %s

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Was going to request --long-args for readability but seems it's just -r chars provided by pytest, lame.

Comment threadpython/suite.bzl

tests.append(test_name)

pytest_test(

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Don't think we should have the 'generic py_test_suite delegate to a pytest test implementation. I think everything using pytest (which is a third-party dep and not stock python) should include "pytest" in the rule name.

Comment threadpython/suite.bzl
)
native.test_suite(
name = name,
tests = tests,

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

If the tests attribute is unspecified or empty, the rule will default to including all test rules in the current BUILD file that are not tagged as manual. source

?? That's unexpected behaviour to me. I would have thought an empty list would do nothing or error. Do you have experience with _test_suite rules that wrap native.test_suite? Do rule authors keep this odd behaviour?

Comment threadpython/pytest.bzl
name = name,
python_version = python_version,
srcs = srcs + [runner_target],
deps = deps,

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Think that users of the any _pytest_test rule should get pytest as a provided dependency, like here: https://github.com/dropbox/dbx_build_tools/blob/fe5c9e668a9e6951970c0595089742d8a0247b8c/build_tools/py/py.bzl#L1011

Is there an problem with that approach I'm not seeing?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Only issue I can think of involves which version of pytest to use. Presumably users need to have it in their requirements.txt, or we inject a default version if not. We should definitely add requirement("pytest") to deps if it doesn't exist.

Other related issues include user provided plugin version eg. pytest_coverage which need to resolve with pytest, and how / when to add those deps to the py_pytest_test rule.

Comment threadpython/pytest.bzl
def pytest_test(name, srcs, deps = None, args = None, data = None, python_version = None, **kwargs):
runner_target = "%s-runner.py" % name

_pytest_runner(

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

What necessitates the creation of a separate executable? Can we just have a special py_test.main program? It looks like that's maybe what's happening as the py_test.main value is main = runner_target. The _pytest_runner target creates the runner file. But then why is the _pytest_runneritself executable?

@thundergolferthundergolfer mentioned this pull request May 12, 2021
@joshua-cannon-techlabs

Copy link
Copy Markdown

Firstly, I would absolutely love to see pytest support in the stock bazel rules.

However, one thing that worries me is capturing the invisible dependency between test files and conftest.py files. Pytest-the-framework will load those to find customizations and fixtures which tests use without a paper-trail. (See pytest's doc).

So if the user is specifying the test, someone (is it them or the framework?) should be declaring those dependencies (conftest.py all the way up). I would argue the framework should, as it's painfully easy to get wrong from the user's perspective.

The same goes for the test suit rule.

@hrfullerhrfuller left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I'd love to revive this PR. As a first pass we can't and shouldn't aim to support all the configurability of pytest, but we should let users passthrough pytest args to the stub script that invokes it.

Other things to consider are:

  • How to treat configuration files we find in the test sandbox, easiest thing at first would be to ignore custom configs.
  • we should amend the srcs of the underlying native.py_test to include a glob for
    **/conftest.py as someone mentioned in a comment.

Comment threadpython/pytest.bzl
expanded_args = [ctx.expand_location(arg, ctx.attr.data) for arg in ctx.attr.args]

runner = ctx.actions.declare_file(ctx.attr.name)
ctx.actions.write(

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This should be a template substitution action.

Comment threadpython/pytest.bzl
name = name,
python_version = python_version,
srcs = srcs + [runner_target],
deps = deps,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Only issue I can think of involves which version of pytest to use. Presumably users need to have it in their requirements.txt, or we inject a default version if not. We should definitely add requirement("pytest") to deps if it doesn't exist.

Other related issues include user provided plugin version eg. pytest_coverage which need to resolve with pytest, and how / when to add those deps to the py_pytest_test rule.

@aignas

Copy link
Copy Markdown
Collaborator

When someone comes back to this, consider adding extra arguments to change how pytest is changing the import path. I did some investigation as to why pytest tests where failing when I was using protobuf rules here: https://github.com/aignas/bazel_pytest_proto

@betaboon

betaboon commented May 21, 2022

Copy link
Copy Markdown
Contributor

@AutomatedTester are you planning/willing to pick this up again, or would you prefer someone else taking it over?

@everyone else in here: what would be a minimal setup of changes required here to get this merged?

i see the following todo-list:

  • address (all) the review-comments
  • clear up if we want to implicitly supply a pytest and if so how

i would argue we shouldn't aim for adressing all eventualities at first, otherwise this would never get in in any form.

just for clarification: i would be willing to take this over under the condition that there is a willingness for constructive cooperation and eventually compromise.

@AutomatedTester

Copy link
Copy Markdown
ContributorAuthor

@AutomatedTester are you planning/willing to pick this up again, or would you prefer someone else taking it over?

Happy for someone to take this over, I haven't had time to do it.

@thundergolfer

Copy link
Copy Markdown

Heads up that #723 may supersede this.

@github-actions

Copy link
Copy Markdown
Contributor

This Pull Request has been automatically marked as stale because it has not had any activity for 180 days. It will be closed if no further activity occurs in 30 days.
Collaborators can add an assignee to keep this open indefinitely. Thanks for your contributions to rules_python!

@github-actionsgithub-actionsBot added the Can Close? Will close in 30 days if there is no new activity label Dec 19, 2022
@github-actions

Copy link
Copy Markdown
Contributor

This PR was automatically closed because it went 30 days without a reply since it was labeled "Can Close?"

@alexeagle

Copy link
Copy Markdown
Contributor

Note, https://docs.aspect.build/rules/aspect_rules_py/docs/rules#py_pytest_main provides missing glue for pytest, thanks to @mattem and @f0rmiga

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Can Close?Will close in 30 days if there is no new activitycla: yes

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants

@AutomatedTester@joshua-cannon-techlabs@aignas@betaboon@thundergolfer@alexeagle@hrfuller