Skip to content

Commit 5f8e714

Browse files
committed
various cleanup, adding type annotations, setting up travis CI
1 parent dd25812 commit 5f8e714

12 files changed

+233
-103
lines changed

.circleci/config.yml

-14
This file was deleted.

.prospector.yaml

+69
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
strictness: veryhigh
2+
doc-warnings: true
3+
member-warnings: false
4+
test-warnings: false
5+
6+
ignore-patterns:
7+
- (^|/)\..+
8+
9+
pylint:
10+
disable:
11+
- anomalous-backslash-in-string
12+
- import-error
13+
- broad-except
14+
- protected-access
15+
- unsupported-membership-test
16+
- wrong-import-order
17+
18+
options:
19+
max-args: 14
20+
max-locals: 100
21+
max-returns: 10
22+
max-branches: 30
23+
max-statements: 180
24+
max-parents: 10
25+
max-attributes: 12
26+
min-public-methods: 0
27+
max-public-methods: 20
28+
max-module-lines: 2000
29+
max-line-length: 100
30+
31+
mccabe:
32+
options:
33+
max-complexity: 22
34+
35+
pep8:
36+
disable:
37+
- N802
38+
- N807
39+
- W503
40+
options:
41+
max-line-length: 100
42+
single-line-if-stmt: n
43+
44+
vulture:
45+
run: false
46+
47+
pyroma:
48+
run: false
49+
disable:
50+
- PYR19
51+
- PYR16
52+
53+
pep257:
54+
disable:
55+
- D000
56+
- D100
57+
- D104
58+
- D107
59+
- D200
60+
- D202
61+
- D203
62+
- D205
63+
- D212
64+
- D204
65+
- D300
66+
- D400
67+
- D401
68+
- D404
69+
- D403

.travis.yml

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
dist: xenial
2+
sudo: false
3+
language: python
4+
matrix:
5+
include:
6+
- python: 3.6
7+
env: TOXENV=py36
8+
- python: 3.7
9+
env: TOXENV=py37
10+
install:
11+
- pip install tox pipenv
12+
- pipenv install
13+
script: tox
14+
deploy:
15+
provider: pypi
16+
user: jacobi
17+
skip_existing: true
18+
on:
19+
branch: master
20+
tags: true
21+
password:
22+
secure: Ykd2RDetnQmlZpXMm3YuaXWbtt5TbuJYcOsppQsmvr2RD59jYjTaoaoQ97TXJCw2luR949JioFG48j+mD3nUQ/heooJrvQLa1Kmf6CNSAd6TM1cy1+pWwx8Wj4KqktCp3tEg+7hcjVh5wUQo6br4zfjKhl8jVwWEqH6DU4evsoeR74sEH/1GVpcDDWglEKxOi90FhcE1iiEqOMPXM/VF5CXpYhxgOzYDY49NRqVQMUnoBsXmSFdOHVNtE/+6mdu/G3mYheKRxq9yXhP6WOYDWKjzT8E4Rf+/AChjSNEkFkBvptODHRJ+2eG+UzNvsMpFgq++Om/7KCTzgYg24OQuj2f/S2QqANWmHQEY+MK/40XczD8eoxaRcZCtG1Q5pFPAQdbNWCQ3ilfQnbdvF5YwtM7vn8QzU9AjTgWYC/GHh84NLrZOx5GG7fO5YsuKJQrXCLVtxYmhJdkL3mQTnVrg287ZUPppBYe5eq6sO1cntcdUlz3CKmsy1JngdoBGARKJYs2gkoy7DcHkTwIT64iffvzfuvOZQIxjrJ+byW2dOB9iDL+XdafNko97BHuCowIqySDq8dAeqBUTB88YcRnn4BnVlZ2c+E0VZAOzzIzJ0Uu3ualAltviuaQNSqHEZPihMicRmHB/yjdJUGAWpLHgMp1aF/fVRi5Aoh7BR4M6VpQ=

Dockerfile

-15
This file was deleted.

README.md

-20
This file was deleted.

README.rst

+44
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
bash.py
2+
=======
3+
4+
.. image:: https://travis-ci.org/jpetrucciani/bash.py.svg?branch=master
5+
:target: https://travis-ci.org/jpetrucciani/bash.py
6+
7+
8+
.. image:: https://badge.fury.io/py/bash.py.svg
9+
:target: https://badge.fury.io/py/bash.py
10+
:alt: PyPI version
11+
12+
13+
.. image:: https://img.shields.io/badge/code%20style-black-000000.svg
14+
:target: https://github.com/ambv/black
15+
:alt: Code style: black
16+
17+
18+
.. image:: https://img.shields.io/badge/python-3.6+-blue.svg
19+
:target: https://www.python.org/downloads/release/python-360/
20+
:alt: Python 3.6+ supported
21+
22+
23+
An inline Bash script runner, for Python.
24+
-----------------------------------------
25+
26+
Example Usage
27+
~~~~~~~~~~~~~
28+
29+
.. code:: pycon
30+
31+
>>> import bash
32+
33+
>>> bash.run("echo hi")
34+
<BashProcess pid=24108 return_code=0>
35+
36+
>>> _.output
37+
'hi\n'
38+
39+
Installation
40+
~~~~~~~~~~~~
41+
42+
.. code:: shell
43+
44+
$ pipenv install bash.py

bash.py

+47-15
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,12 @@
1-
import os
1+
"""
2+
bash.py module
3+
"""
4+
import delegator
25
import re
6+
import time
7+
import json as json_lib
38
from shlex import quote as shlex_quote
49

5-
import delegator
610

711
DELEGATOR_MINIMUM_TIMEOUT = 60 * 60 * 60 * 8
812
WHICH_BASH = "bash"
@@ -15,7 +19,10 @@
1519

1620

1721
class BashProcess:
18-
def __init__(self, args, parent, blocking=True):
22+
"""bash process object"""
23+
24+
def __init__(self, args, parent: "Bash", blocking: bool = True) -> None:
25+
"""constructor"""
1926
# Environ inherents from parent.
2027

2128
# Remember passed-in arguments.
@@ -24,29 +31,55 @@ def __init__(self, args, parent, blocking=True):
2431

2532
# Run the subprocess.
2633
args = " ".join(args)
34+
self.start_time = time.time()
2735
self.sub = delegator.run(
2836
f"{self.parent.path} {args}", env=self.parent.environ, block=blocking
2937
)
38+
if blocking:
39+
self.elapsed_time = time.time() - self.start_time
3040

3141
@property
32-
def output(self):
42+
def output(self) -> str:
43+
"""stdout of the running process"""
3344
return str(self.sub.out)
3445

3546
@property
36-
def ok(self):
47+
def err(self) -> str:
48+
"""stderr of the running process"""
49+
return str(self.sub.err)
50+
51+
@property
52+
def json(self) -> dict:
53+
"""stdout of the running process, converted to a dict if it's json"""
54+
return json_lib.loads(str(self.sub.out))
55+
56+
@property
57+
def ok(self) -> bool:
58+
"""if the process exited with a 0 exit code"""
3759
return self.sub.ok
3860

39-
def return_code(self):
61+
@property
62+
def return_code(self) -> int:
63+
"""the exit code of the process"""
4064
return self.sub.return_code
4165

42-
def __repr__(self):
66+
@property
67+
def pid(self) -> int:
68+
"""the process id"""
69+
return self.sub.pid
70+
71+
def __repr__(self) -> str:
72+
"""string representation of the bash process"""
4373
return (
4474
f"<BashProcess pid={self.sub.pid!r} return_code={self.sub.return_code!r}>"
4575
)
4676

4777

4878
class Bash:
79+
"""an instance of bash"""
80+
4981
def __init__(self, *, path=WHICH_BASH, environ=None, interactive=False):
82+
"""constructor"""
5083
self.path = path
5184
self.interactive = interactive
5285
self.environ = environ or {}
@@ -57,22 +90,21 @@ def __init__(self, *, path=WHICH_BASH, environ=None, interactive=False):
5790
self.about = ver_proc.output
5891

5992
@property
60-
def version(self):
93+
def version(self) -> str:
6194
"""Returns the version number of the Bash-interpreter."""
62-
m = re.search(r"\bversion\s+(.+)\b", self.about)
95+
matches = re.search(r"\bversion\s+(.+)\b", self.about)
6396
# ...GNU Bash, version 4.4.19(1)-release ... --> 4.4.19(1)-release
64-
if m:
65-
return m.group(1)
97+
return matches.group(1) if matches else "version_unknown"
6698

67-
def _exec(self, *args):
99+
def _exec(self, *args) -> BashProcess:
100+
"""execute the bash process as a child of this process"""
68101
return BashProcess(parent=self, args=args)
69102

70-
def command(self, script):
71-
103+
def command(self, script: str) -> BashProcess:
104+
"""form up the command with shlex and execute"""
72105
return self._exec(f"-c {shlex_quote(script)}")
73106

74107

75108
def run(script=None, **kwargs):
76109
"""Runs the given bash script."""
77-
# Run the script.
78110
return Bash(**kwargs).command(script)

docker-compose.yml

-5
This file was deleted.

setup.cfg

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
[mypy]
2+
python_version = 3.6
3+
disallow_untyped_defs = True
4+
ignore_missing_imports = True
5+
warn_unused_ignores = True
6+
7+
8+
[flake8]
9+
ignore = N802,N807,W503
10+
max-line-length = 100
11+
max-complexity = 30

0 commit comments

Comments
 (0)