Skip to content

Commit

Permalink
Merge pull request #745 from amoffat/develop
Browse files Browse the repository at this point in the history
Release 2.2.0
  • Loading branch information
amoffat authored Jan 9, 2025
2 parents 4c34340 + ca44695 commit be9f8ea
Show file tree
Hide file tree
Showing 6 changed files with 55 additions and 29 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ jobs:
strategy:
matrix:
os: [ubuntu-latest]
python-version: ["3.8", "3.9", "3.10", "3.11"]
python-version: ["3.8", "3.9", "3.10", "3.11", "3.12"]
use-select: [0, 1]
lang: [C, en_US.UTF-8]

Expand Down
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
# Changelog

## 2.2.0 - 1/9/25

- `return_cmd` with `await` now works correctly [#743](https://github.com/amoffat/sh/issues/743)
- Formal support for Python 3.12

## 2.1.0 - 10/8/24

- Add contrib command `sh.contrib.bash` [#736](https://github.com/amoffat/sh/pull/736)
Expand Down
2 changes: 1 addition & 1 deletion README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@

|
sh is a full-fledged subprocess replacement for Python 3.8 - 3.11, and PyPy
sh is a full-fledged subprocess replacement for Python 3.8 - 3.12, and PyPy
that allows you to call *any* program as if it were a function:

.. code:: python
Expand Down
4 changes: 2 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
[tool.poetry]
name = "sh"
version = "2.1.0"
version = "2.2.0"
description = "Python subprocess replacement"
authors = ["Andrew Moffat <[email protected]>"]
readme = "README.rst"
maintainers = [
"Andrew Moffat <[email protected]>",
"Erik Cederstrand <[email protected]>"
"Erik Cederstrand <[email protected]>",
]
homepage = "https://sh.readthedocs.io/"
repository = "https://github.com/amoffat/sh"
Expand Down
29 changes: 17 additions & 12 deletions sh.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,19 @@
from collections import deque
from collections.abc import Mapping

import platform
from importlib import metadata

try:
__version__ = metadata.version("sh")
except metadata.PackageNotFoundError: # pragma: no cover
__version__ = "unknown"

if "windows" in platform.system().lower(): # pragma: no cover
raise ImportError(
f"sh {__version__} is currently only supported on Linux and macOS."
)

import errno
import fcntl
import gc
Expand All @@ -35,7 +48,6 @@
import inspect
import logging
import os
import platform
import pty
import pwd
import re
Expand All @@ -55,7 +67,6 @@
from asyncio import Queue as AQueue
from contextlib import contextmanager
from functools import partial
from importlib import metadata
from io import BytesIO, StringIO, UnsupportedOperation
from io import open as fdopen
from locale import getpreferredencoding
Expand All @@ -64,17 +75,8 @@
from types import GeneratorType, ModuleType
from typing import Any, Dict, Type, Union

try:
__version__ = metadata.version("sh")
except metadata.PackageNotFoundError: # pragma: no cover
__version__ = "unknown"
__project_url__ = "https://github.com/amoffat/sh"

if "windows" in platform.system().lower(): # pragma: no cover
raise ImportError(
f"sh {__version__} is currently only supported on Linux and macOS."
)

TEE_STDOUT = {True, "out", 1}
TEE_STDERR = {"err", 2}

Expand Down Expand Up @@ -887,7 +889,10 @@ def __next__(self):
def __await__(self):
async def wait_for_completion():
await self.aio_output_complete.wait()
return str(self)
if self.call_args["return_cmd"]:
return self
else:
return str(self)

return wait_for_completion().__await__()

Expand Down
42 changes: 29 additions & 13 deletions tests/sh_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -1707,7 +1707,6 @@ def test_async(self):
)

alternating = []
q = AQueue()

async def producer(q):
alternating.append(1)
Expand All @@ -1722,19 +1721,20 @@ async def consumer(q):
self.assertEqual(msg, "hello")
alternating.append(2)

loop = asyncio.get_event_loop()
fut = asyncio.gather(producer(q), consumer(q))
loop.run_until_complete(fut)
async def main():
q = AQueue()
await asyncio.gather(producer(q), consumer(q))

asyncio.run(main())
self.assertListEqual(alternating, [1, 2, 1, 2])

def test_async_exc(self):
py = create_tmp_test("""exit(34)""")

async def producer():
await python(py.name, _async=True)
await python(py.name, _async=True, _return_cmd=False)

loop = asyncio.get_event_loop()
self.assertRaises(sh.ErrorReturnCode_34, loop.run_until_complete, producer())
self.assertRaises(sh.ErrorReturnCode_34, asyncio.run, producer())

def test_async_iter(self):
py = create_tmp_test(
Expand All @@ -1743,7 +1743,6 @@ def test_async_iter(self):
print(i)
"""
)
q = AQueue()

# this list will prove that our coroutines are yielding to eachother as each
# line is produced
Expand All @@ -1763,9 +1762,11 @@ async def consumer(q):
return
alternating.append(2)

loop = asyncio.get_event_loop()
res = asyncio.gather(producer(q), consumer(q))
loop.run_until_complete(res)
async def main():
q = AQueue()
await asyncio.gather(producer(q), consumer(q))

asyncio.run(main())
self.assertListEqual(alternating, [1, 2, 1, 2, 1, 2, 1, 2, 1, 2])

def test_async_iter_exc(self):
Expand All @@ -1783,8 +1784,23 @@ async def producer():
async for line in python(py.name, _async=True):
lines.append(int(line.strip()))

loop = asyncio.get_event_loop()
self.assertRaises(sh.ErrorReturnCode_34, loop.run_until_complete, producer())
self.assertRaises(sh.ErrorReturnCode_34, asyncio.run, producer())

def test_async_return_cmd(self):
py = create_tmp_test(
"""
import sys
sys.exit(0)
"""
)

async def main():
result = await python(py.name, _async=True, _return_cmd=True)
self.assertIsInstance(result, sh.RunningCommand)
result_str = await python(py.name, _async=True, _return_cmd=False)
self.assertIsInstance(result_str, str)

asyncio.run(main())

def test_handle_both_out_and_err(self):
py = create_tmp_test(
Expand Down

0 comments on commit be9f8ea

Please sign in to comment.