Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: tox-dev/pyproject-api
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: 1.5.2
Choose a base ref
...
head repository: tox-dev/pyproject-api
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 1.5.3
Choose a head ref
  • 4 commits
  • 6 files changed
  • 3 contributors

Commits on Jun 19, 2023

  1. [pre-commit.ci] pre-commit autoupdate (#83)

    Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
    pre-commit-ci[bot] authored Jun 19, 2023
    Copy the full SHA
    be06973 View commit details

Commits on Jun 26, 2023

  1. [pre-commit.ci] pre-commit autoupdate (#84)

    Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
    pre-commit-ci[bot] authored Jun 26, 2023
    Copy the full SHA
    5b984f6 View commit details

Commits on Jun 27, 2023

  1. Bump pypa/gh-action-pypi-publish from 1.8.6 to 1.8.7 (#85)

    Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
    dependabot[bot] authored Jun 27, 2023
    Copy the full SHA
    5cc7a99 View commit details

Commits on Jul 6, 2023

  1. Copy the full SHA
    fadd91b View commit details
Showing with 71 additions and 35 deletions.
  1. +1 −1 .github/workflows/release.yml
  2. +3 −3 .pre-commit-config.yaml
  3. +22 −22 pyproject.toml
  4. +8 −7 src/pyproject_api/_backend.py
  5. +1 −1 src/pyproject_api/_backend.pyi
  6. +36 −1 tests/test_backend.py
2 changes: 1 addition & 1 deletion .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -24,4 +24,4 @@ jobs:
- name: Build package
run: pyproject-build -s -w . -o dist
- name: Publish to PyPI
uses: pypa/gh-action-pypi-publish@v1.8.6
uses: pypa/gh-action-pypi-publish@v1.8.7
6 changes: 3 additions & 3 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -5,7 +5,7 @@ repos:
- id: end-of-file-fixer
- id: trailing-whitespace
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: "v0.0.272"
rev: "v0.0.275"
hooks:
- id: ruff
exclude: src/pyproject_api/_backend.py
@@ -15,12 +15,12 @@ repos:
hooks:
- id: black
- repo: https://github.com/tox-dev/tox-ini-fmt
rev: "1.3.0"
rev: "1.3.1"
hooks:
- id: tox-ini-fmt
args: ["-p", "fix"]
- repo: https://github.com/tox-dev/pyproject-fmt
rev: "0.11.2"
rev: "0.12.1"
hooks:
- id: pyproject-fmt
additional_dependencies: ["tox>=4.6"]
44 changes: 22 additions & 22 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -71,28 +71,6 @@ version.source = "vcs"
[tool.black]
line-length = 120

[tool.coverage]
html.show_contexts = true
html.skip_covered = false
paths.source = [
"src",
".tox*/*/lib/python*/site-packages",
".tox*/pypy*/site-packages",
".tox*\\*\\Lib\\site-packages",
"*/src",
"*\\src",
]
report.fail_under = 98
report.omit = []
run.parallel = true
run.plugins = ["covdefaults"]

[tool.mypy]
python_version = "3.11"
show_error_codes = true
strict = true
overrides = [{ module = ["virtualenv.*"], ignore_missing_imports = true }]

[tool.ruff]
select = ["ALL"]
line-length = 120
@@ -116,3 +94,25 @@ ignore = [
"S603", # `subprocess` call: check for execution of untrusted input
"PLR2004", # Magic value used in comparison, consider replacing with a constant variable
]

[tool.coverage]
html.show_contexts = true
html.skip_covered = false
paths.source = [
"src",
".tox*/*/lib/python*/site-packages",
".tox*/pypy*/site-packages",
".tox*\\*\\Lib\\site-packages",
"*/src",
"*\\src",
]
report.fail_under = 98
report.omit = []
run.parallel = true
run.plugins = ["covdefaults"]

[tool.mypy]
python_version = "3.11"
show_error_codes = true
strict = true
overrides = [{ module = ["virtualenv.*"], ignore_missing_imports = true }]
15 changes: 8 additions & 7 deletions src/pyproject_api/_backend.py
Original file line number Diff line number Diff line change
@@ -112,17 +112,18 @@ def run(argv):
return 0


def read_line():
def read_line(fd=0):
# for some reason input() seems to break (hangs forever) so instead we read byte by byte the unbuffered stream
content = bytearray()
while True:
try:
char = os.read(0, 1)
except EOFError: # pragma: no cover # when the stdout is closed without exit
break # pragma: no cover
if char == b"\n": # pragma: no cover
char = os.read(fd, 1)
if not char:
if not content:
raise EOFError("EOF without reading anything") # we didn't get a line at all, let the caller know
break
if char == b"\n":
break
if char != b"\r": # pragma: win32 cover
if char != b"\r":
content += char
return content

2 changes: 1 addition & 1 deletion src/pyproject_api/_backend.pyi
Original file line number Diff line number Diff line change
@@ -12,5 +12,5 @@ class BackendProxy:
def _optional_commands(self) -> dict[str, bool]: ...

def run(argv: Sequence[str]) -> int: ...
def read_line() -> bytearray: ...
def read_line(fd: int = 0) -> bytearray: ...
def flush() -> None: ...
37 changes: 36 additions & 1 deletion tests/test_backend.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
from __future__ import annotations

import json
import os
from typing import TYPE_CHECKING, Any

import pytest

from pyproject_api._backend import BackendProxy, run
from pyproject_api._backend import BackendProxy, read_line, run

if TYPE_CHECKING:
from pathlib import Path
@@ -127,3 +128,37 @@ def fake_backend(name: str, *args: Any, **kwargs: Any) -> Any: # noqa: ARG001
assert "Backend: run command dummy_command_b with args {'baz': 'qux'}" in captured.out
assert "Backend: run command dummy_command_c with args {'win': 'wow'}" in captured.out
assert "SystemExit: 2" in captured.err


def test_read_line_success() -> None:
r, w = os.pipe()
try:
line_in = b"this is a line\r\n"
os.write(w, line_in)
line_out = read_line(fd=r)
assert line_out == bytearray(b"this is a line")
finally:
os.close(r)
os.close(w)


def test_read_line_eof_before_newline() -> None:
r, w = os.pipe()
try:
line_in = b"this is a line"
os.write(w, line_in)
os.close(w)
line_out = read_line(fd=r)
assert line_out == bytearray(b"this is a line")
finally:
os.close(r)


def test_read_line_eof_at_the_beginning() -> None:
r, w = os.pipe()
try:
os.close(w)
with pytest.raises(EOFError):
read_line(fd=r)
finally:
os.close(r)