Skip to content

Commit

Permalink
Merge pull request #16 from makermelissa/main
Browse files Browse the repository at this point in the history
Fixed an issue with run_command() sometimes locking up
  • Loading branch information
makermelissa committed Nov 11, 2022
2 parents c658112 + 7c8bedc commit 0a235e3
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 90 deletions.
54 changes: 8 additions & 46 deletions .pylintrc
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,11 @@
# run arbitrary code
extension-pkg-whitelist=

# Add files or directories to the blacklist. They should be base names, not
# Add files or directories to the ignore-list. They should be base names, not
# paths.
ignore=CVS

# Add files or directories matching the regex patterns to the blacklist. The
# Add files or directories matching the regex patterns to the ignore-list. The
# regex matches against base names, not paths.
ignore-patterns=

Expand All @@ -22,12 +22,11 @@ ignore-patterns=
#init-hook=

# Use multiple processes to speed up Pylint.
# jobs=1
jobs=2
jobs=1

# List of plugins (as comma separated values of python modules names) to load,
# usually to register additional checkers.
load-plugins=
load-plugins=pylint.extensions.no_self_use

# Pickle collected data for later comparisons.
persistent=yes
Expand Down Expand Up @@ -55,8 +54,8 @@ confidence=
# --enable=similarities". If you want to run only the classes checker, but have
# no Warning level messages displayed, use"--disable=all --enable=classes
# --disable=W"
# disable=import-error,print-statement,parameter-unpacking,unpacking-in-except,old-raise-syntax,backtick,long-suffix,old-ne-operator,old-octal-literal,import-star-module-level,raw-checker-failed,bad-inline-option,locally-disabled,locally-enabled,file-ignored,suppressed-message,useless-suppression,deprecated-pragma,apply-builtin,basestring-builtin,buffer-builtin,cmp-builtin,coerce-builtin,execfile-builtin,file-builtin,long-builtin,raw_input-builtin,reduce-builtin,standarderror-builtin,unicode-builtin,xrange-builtin,coerce-method,delslice-method,getslice-method,setslice-method,no-absolute-import,old-division,dict-iter-method,dict-view-method,next-method-called,metaclass-assignment,indexing-exception,raising-string,reload-builtin,oct-method,hex-method,nonzero-method,cmp-method,input-builtin,round-builtin,intern-builtin,unichr-builtin,map-builtin-not-iterating,zip-builtin-not-iterating,range-builtin-not-iterating,filter-builtin-not-iterating,using-cmp-argument,eq-without-hash,div-method,idiv-method,rdiv-method,exception-message-attribute,invalid-str-codec,sys-max-int,bad-python3-import,deprecated-string-function,deprecated-str-translate-call
disable=print-statement,parameter-unpacking,unpacking-in-except,old-raise-syntax,backtick,long-suffix,old-ne-operator,old-octal-literal,import-star-module-level,raw-checker-failed,bad-inline-option,locally-disabled,locally-enabled,file-ignored,suppressed-message,useless-suppression,deprecated-pragma,apply-builtin,basestring-builtin,buffer-builtin,cmp-builtin,coerce-builtin,execfile-builtin,file-builtin,long-builtin,raw_input-builtin,reduce-builtin,standarderror-builtin,unicode-builtin,xrange-builtin,coerce-method,delslice-method,getslice-method,setslice-method,no-absolute-import,old-division,dict-iter-method,dict-view-method,next-method-called,metaclass-assignment,indexing-exception,raising-string,reload-builtin,oct-method,hex-method,nonzero-method,cmp-method,input-builtin,round-builtin,intern-builtin,unichr-builtin,map-builtin-not-iterating,zip-builtin-not-iterating,range-builtin-not-iterating,filter-builtin-not-iterating,using-cmp-argument,eq-without-hash,div-method,idiv-method,rdiv-method,exception-message-attribute,invalid-str-codec,sys-max-int,bad-python3-import,deprecated-string-function,deprecated-str-translate-call,import-error,bad-continuation
# disable=import-error,raw-checker-failed,bad-inline-option,locally-disabled,file-ignored,suppressed-message,useless-suppression,deprecated-pragma,deprecated-str-translate-call
disable=raw-checker-failed,bad-inline-option,locally-disabled,file-ignored,suppressed-message,useless-suppression,deprecated-pragma,import-error,pointless-string-statement,unspecified-encoding

# Enable the message, report, category or checker with the given id(s). You can
# either give multiple identifier separated by comma (,) or put this option
Expand Down Expand Up @@ -226,12 +225,6 @@ max-line-length=100
# Maximum number of lines in a module
max-module-lines=1000

# List of optional constructs for which whitespace checking is disabled. `dict-
# separator` is used to allow tabulation in dicts, etc.: {1 : 1,\n222: 2}.
# `trailing-comma` allows a space between comma and closing bracket: (a, ).
# `empty-line` allows space-only lines.
no-space-check=trailing-comma,dict-separator

# Allow the body of a class to be on the same line as the declaration if body
# contains single statement.
single-line-class-stmt=no
Expand All @@ -250,56 +243,37 @@ ignore-comments=yes
ignore-docstrings=yes

# Ignore imports when computing similarities.
ignore-imports=no
ignore-imports=yes

# Minimum lines number of a similarity.
min-similarity-lines=4
min-similarity-lines=12


[BASIC]

# Naming hint for argument names
argument-name-hint=(([a-z][a-z0-9_]{2,30})|(_[a-z0-9_]*))$

# Regular expression matching correct argument names
argument-rgx=(([a-z][a-z0-9_]{2,30})|(_[a-z0-9_]*))$

# Naming hint for attribute names
attr-name-hint=(([a-z][a-z0-9_]{2,30})|(_[a-z0-9_]*))$

# Regular expression matching correct attribute names
attr-rgx=(([a-z][a-z0-9_]{2,30})|(_[a-z0-9_]*))$

# Bad variable names which should always be refused, separated by a comma
bad-names=foo,bar,baz,toto,tutu,tata

# Naming hint for class attribute names
class-attribute-name-hint=([A-Za-z_][A-Za-z0-9_]{2,30}|(__.*__))$

# Regular expression matching correct class attribute names
class-attribute-rgx=([A-Za-z_][A-Za-z0-9_]{2,30}|(__.*__))$

# Naming hint for class names
# class-name-hint=[A-Z_][a-zA-Z0-9]+$
class-name-hint=[A-Z_][a-zA-Z0-9_]+$

# Regular expression matching correct class names
# class-rgx=[A-Z_][a-zA-Z0-9]+$
class-rgx=[A-Z_][a-zA-Z0-9_]+$

# Naming hint for constant names
const-name-hint=(([A-Z_][A-Z0-9_]*)|(__.*__))$

# Regular expression matching correct constant names
const-rgx=(([A-Z_][A-Z0-9_]*)|(__.*__))$

# Minimum line length for functions/classes that require docstrings, shorter
# ones are exempt.
docstring-min-length=-1

# Naming hint for function names
function-name-hint=(([a-z][a-z0-9_]{2,30})|(_[a-z0-9_]*))$

# Regular expression matching correct function names
function-rgx=(([a-z][a-z0-9_]{2,30})|(_[a-z0-9_]*))$

Expand All @@ -310,21 +284,12 @@ good-names=r,g,b,w,i,j,k,n,x,y,z,ex,ok,Run,_
# Include a hint for the correct naming format with invalid-name
include-naming-hint=no

# Naming hint for inline iteration names
inlinevar-name-hint=[A-Za-z_][A-Za-z0-9_]*$

# Regular expression matching correct inline iteration names
inlinevar-rgx=[A-Za-z_][A-Za-z0-9_]*$

# Naming hint for method names
method-name-hint=(([a-z][a-z0-9_]{2,30})|(_[a-z0-9_]*))$

# Regular expression matching correct method names
method-rgx=(([a-z][a-z0-9_]{2,30})|(_[a-z0-9_]*))$

# Naming hint for module names
module-name-hint=(([a-z_][a-z0-9_]*)|([A-Z][a-zA-Z0-9]+))$

# Regular expression matching correct module names
module-rgx=(([a-z_][a-z0-9_]*)|([A-Z][a-zA-Z0-9]+))$

Expand All @@ -340,9 +305,6 @@ no-docstring-rgx=^_
# to this list to register other decorators that produce valid properties.
property-classes=abc.abstractproperty

# Naming hint for variable names
variable-name-hint=(([a-z][a-z0-9_]{2,30})|(_[a-z0-9_]*))$

# Regular expression matching correct variable names
variable-rgx=(([a-z][a-z0-9_]{2,30})|(_[a-z0-9_]*))$

Expand Down
91 changes: 47 additions & 44 deletions adafruit_shell.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
import os
import shutil
import subprocess
import fcntl
import platform
import fileinput
import re
Expand Down Expand Up @@ -67,75 +68,77 @@ def run_command(self, cmd, suppress_message=False, return_output=False):
"""
Run a shell command and show the output as it runs
"""
original_stdout = sys.stdout
original_stderr = sys.stderr
try:
# pylint: disable=consider-using-with
proc = subprocess.Popen(
cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE
)
# pylint: enable=consider-using-with
full_output = ""
while True:
output = proc.stdout.readline()
err = proc.stderr.read()
if err and not suppress_message:
self.error(err.decode("utf-8", errors="ignore"))
if len(output) == 0 and proc.poll() is not None:
break
if output:
decoded_output = output.decode("utf-8", errors="ignore").strip()
if not suppress_message:
self.info(decoded_output)
full_output += decoded_output
except Exception: # pylint: disable=broad-except
pass
finally:
sys.stdout = original_stdout
sys.stderr = original_stderr
if return_output:
return full_output
r = proc.poll()
if r == 0:

def read_stream(output):
file_descriptor = output.fileno()
file_flags = fcntl.fcntl(file_descriptor, fcntl.F_GETFL)
fcntl.fcntl(file_descriptor, fcntl.F_SETFL, file_flags | os.O_NONBLOCK)
try:
return output.read()
except TypeError:
return ""

full_output = ""
with subprocess.Popen(
cmd,
shell=True,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
universal_newlines=True,
) as proc:
while proc.poll() is None:
err = read_stream(proc.stderr)
if err != "" and not suppress_message:
self.error(err.strip(), end="\n\r")
output = read_stream(proc.stdout)
if output != "" and not suppress_message:
self.info(output.strip(), end="\n\r")
full_output += output
return_code = proc.poll()
proc.stdout.close()
proc.stderr.close()
if return_output:
return full_output
if return_code:
return False
return True
return False

def info(self, message):
def info(self, message, **kwargs):
"""
Display a message with the group in green
"""
if self._group is not None:
print(colored.green(self._group) + " " + message)
print(colored.green(self._group) + " " + message, **kwargs)
else:
print(message)
print(message, **kwargs)

def warn(self, message):
def warn(self, message, **kwargs):
"""
Display a message with the group in yellow
"""
if self._group is not None:
print(colored.yellow(self._group) + " " + message)
print(colored.yellow(self._group) + " " + message, **kwargs)
else:
print(message)
print(message, **kwargs)

def bail(self, message=None):
def bail(self, message=None, **kwargs):
"""
Exit and display an error message if given
"""
if message is None:
self.error("Exiting due to error")
self.error("Exiting due to error", **kwargs)
else:
self.error(f"Exiting due to error: {message}")
self.error(f"Exiting due to error: {message}", **kwargs)
sys.exit(1)

def error(self, message):
def error(self, message, **kwargs):
"""
Display some inforrmation
Display some information
"""
if self._group is not None:
print(colored.red(self._group) + " " + message)
print(colored.red(self._group) + " " + message, **kwargs)
else:
print(message)
print(message, **kwargs)

@staticmethod
def print_colored(message, color):
Expand Down

0 comments on commit 0a235e3

Please sign in to comment.