From 49dc5a37a1de71f8595a079a5bc369def66bc27e Mon Sep 17 00:00:00 2001 From: Michael Mintz Date: Wed, 8 Nov 2023 00:26:44 -0500 Subject: [PATCH] Upgrade Python (#7) - v1.3.0 * Upgrade Python * Do some refactoring * Update GitHub Actions * Version 1.3.0 --- .github/workflows/python-package.yml | 10 ++--- sbvirtualdisplay/__version__.py | 2 +- sbvirtualdisplay/abstractdisplay.py | 2 - sbvirtualdisplay/display.py | 6 +-- sbvirtualdisplay/easyprocess.py | 39 +----------------- sbvirtualdisplay/unicodeutil.py | 38 +----------------- setup.py | 59 +++++++++++++++------------- 7 files changed, 43 insertions(+), 113 deletions(-) diff --git a/.github/workflows/python-package.yml b/.github/workflows/python-package.yml index 34cf299..0cae5bd 100644 --- a/.github/workflows/python-package.yml +++ b/.github/workflows/python-package.yml @@ -17,22 +17,22 @@ jobs: env: PY_COLORS: "1" - runs-on: ubuntu-20.04 + runs-on: ubuntu-latest strategy: fail-fast: false - max-parallel: 7 + max-parallel: 6 matrix: - python-version: ["2.7", "3.6", "3.7", "3.8", "3.9", "3.10", "3.11"] + python-version: ["3.7", "3.8", "3.9", "3.10", "3.11", "3.12"] steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Set up Python ${{ matrix.python-version }} uses: actions/setup-python@v4 with: python-version: ${{ matrix.python-version }} - name: Install dependencies run: | - python -m pip install --upgrade pip + python -m pip install --upgrade pip setuptools python -m pip install flake8 pytest if [ -f requirements.txt ]; then pip install -r requirements.txt; fi - name: Install sbvirtualdisplay diff --git a/sbvirtualdisplay/__version__.py b/sbvirtualdisplay/__version__.py index 0829a2b..154ccf0 100755 --- a/sbvirtualdisplay/__version__.py +++ b/sbvirtualdisplay/__version__.py @@ -1,2 +1,2 @@ # sbvirtualdisplay package -__version__ = "1.2.0" +__version__ = "1.3.0" diff --git a/sbvirtualdisplay/abstractdisplay.py b/sbvirtualdisplay/abstractdisplay.py index 86fbc07..bfbba78 100644 --- a/sbvirtualdisplay/abstractdisplay.py +++ b/sbvirtualdisplay/abstractdisplay.py @@ -76,8 +76,6 @@ def start(self): if self.use_xauth: self._setup_xauth() EasyProcess.start(self) - # https://github.com/ponty/PyVirtualDisplay/issues/2 - # https://github.com/ponty/PyVirtualDisplay/issues/14 self.old_display_var = os.environ.get("DISPLAY", None) self.redirect_display(True) # wait until X server is active diff --git a/sbvirtualdisplay/display.py b/sbvirtualdisplay/display.py index 42a2cc3..b4682b9 100755 --- a/sbvirtualdisplay/display.py +++ b/sbvirtualdisplay/display.py @@ -1,7 +1,5 @@ -""" -This module contains a customized version of pyvirtualdisplay. -These helper methods SHOULD NOT be called directly from tests. -""" +"""This module contains a customized version of pyvirtualdisplay. +These helper methods SHOULD NOT be called directly from tests.""" from sbvirtualdisplay.abstractdisplay import AbstractDisplay from sbvirtualdisplay.xephyr import XephyrDisplay from sbvirtualdisplay.xvfb import XvfbDisplay diff --git a/sbvirtualdisplay/easyprocess.py b/sbvirtualdisplay/easyprocess.py index 0cf3548..83b0378 100755 --- a/sbvirtualdisplay/easyprocess.py +++ b/sbvirtualdisplay/easyprocess.py @@ -1,5 +1,4 @@ """Easy to use python subprocess interface.""" - from sbvirtualdisplay.unicodeutil import ( split_command, unidecode, @@ -37,8 +36,7 @@ def __str__(self): class EasyProcessCheckInstalledError(Exception): """This exception is raised when a process run by check() returns - a non-zero exit status or OSError is raised. - """ + a non-zero exit status or OSError is raised.""" def __init__(self, easy_process): self.easy_process = easy_process @@ -66,11 +64,6 @@ class EasyProcess(object): simple interface for :mod:`subprocess` - shell is not supported (shell=False) - - .. warning:: - unicode is supported only for string list command (Python2.x) - (check :mod:`shlex` for more information) :param cmd: string ('ls -l') or list of strings (['ls','-l']) :param cwd: working directory :param use_temp_files: use temp files instead of pipes for @@ -111,7 +104,7 @@ def __init__( self.cwd = cwd cmd = split_command(cmd) self.cmd = cmd - self.cmd_as_string = " ".join(self.cmd) # TODO: not perfect + self.cmd_as_string = " ".join(self.cmd) log.debug('param: "%s" ', self.cmd_param) log.debug("command: %s", self.cmd) log.debug("joined command: %s", self.cmd_as_string) @@ -238,13 +231,6 @@ def is_alive(self): return False def wait(self, timeout=None): - """Wait for command to complete. - Timeout: - - discussion: - http://stackoverflow.com/questions/1191374/subprocess-with-timeout - - implementation: threading - :rtype: self - """ if timeout is not None: if not self._thread: self._thread = threading.Thread(target=self._wait4process) @@ -257,7 +243,6 @@ def wait(self, timeout=None): self.timeout_happened or self._thread.isAlive() ) else: - # no timeout and no existing thread self._wait4process() return self @@ -281,7 +266,6 @@ def remove_ending_lf(s): return time.sleep(POLL_TIME) else: - # wait() blocks process, timeout not possible self.popen.wait() self._outputs_processed = True self._stdout_file.seek(0) @@ -291,15 +275,6 @@ def remove_ending_lf(s): self._stdout_file.close() self._stderr_file.close() else: - # This will deadlock when using stdout=PIPE and/or stderr=PIPE - # and the child process generates enough output to a pipe such - # that it blocks waiting for the OS pipe buffer - # to accept more data. - # Use communicate() to avoid that. - # self.popen.wait() - # self.stdout = self.popen.stdout.read() - # self.stderr = self.popen.stderr.read() - # communicate() blocks process, timeout not possible self._outputs_processed = True (self.stdout, self.stderr) = self.popen.communicate() log.debug("process has ended") @@ -310,12 +285,6 @@ def remove_ending_lf(s): log.debug("stderr=%s", self.stderr) def stop(self): - """Kill process and wait for command to complete. - same as: - 1. :meth:`sendstop` - 2. :meth:`wait` - :rtype: self - """ return self.sendstop().wait() def sendstop(self): @@ -345,10 +314,6 @@ def sendstop(self): return self def sleep(self, sec): - """ - sleeping (same as :func:`time.sleep`) - :rtype: self - """ time.sleep(sec) return self diff --git a/sbvirtualdisplay/unicodeutil.py b/sbvirtualdisplay/unicodeutil.py index f94263e..9b0898f 100755 --- a/sbvirtualdisplay/unicodeutil.py +++ b/sbvirtualdisplay/unicodeutil.py @@ -1,18 +1,7 @@ import shlex import sys -import unicodedata - -PY3 = sys.version_info[0] >= 3 - -if PY3: - string_types = (str,) -else: - string_types = (basestring,) # noqa: ignore=F821 - - -class EasyProcessUnicodeError(Exception): - pass +string_types = (str,) def split_command(cmd, posix=None): @@ -26,19 +15,6 @@ def split_command(cmd, posix=None): # cmd is string list pass else: - if not PY3: - # cmd is string - # The shlex module currently does not support Unicode input in 2.x - if isinstance(cmd, unicode): # noqa: ignore=F821 - try: - cmd = unicodedata.normalize("NFKD", cmd).encode( - "ascii", "strict" - ) - except UnicodeEncodeError: - raise EasyProcessUnicodeError( - 'unicode command "%s" can not be processed.' % cmd + "" - "Use string list instead of string" - ) if posix is None: posix = "win" not in sys.platform cmd = shlex.split(cmd, posix=posix) @@ -46,18 +22,8 @@ def split_command(cmd, posix=None): def uniencode(s): - if PY3: - pass - else: - if isinstance(s, unicode): # noqa: ignore=F821 - s = s.encode("utf-8") return s def unidecode(s): - if PY3: - s = s.decode("utf-8", "ignore") - else: - if isinstance(s, str): - s = s.decode("utf-8", "ignore") - return s + return s.decode("utf-8", "ignore") diff --git a/setup.py b/setup.py index 1e2a749..5077d5a 100755 --- a/setup.py +++ b/setup.py @@ -1,9 +1,6 @@ -""" -*** sbvirtualdisplay *** +"""*** sbvirtualdisplay *** A modified version of pyvirtualdisplay for optimized SeleniumBase performance. -(Python 2.7+ and Python 3.6+) -""" - +(Python 3.7+)""" from setuptools import setup import os import sys @@ -33,13 +30,11 @@ if sys.argv[-1] == "publish": reply = None input_method = input - if not sys.version_info[0] >= 3: - input_method = raw_input # noqa: F821 confirm_text = ">>> Confirm release PUBLISH to PyPI? (yes/no): " reply = str(input_method(confirm_text)).lower().strip() if reply == "yes": print("\n*** Checking code health with flake8:\n") - os.system("python -m pip install 'flake8==5.0.4'") + os.system("python -m pip install 'flake8==6.1.0'") flake8_status = os.system("flake8 --exclude=recordings,temp") if flake8_status != 0: print("\nWARNING! Fix flake8 issues before publishing to PyPI!\n") @@ -50,11 +45,23 @@ os.system("rm -f dist/*.egg; rm -f dist/*.tar.gz; rm -f dist/*.whl") os.system("rm -rf build/bdist.*; rm -rf build/lib") print("\n*** Installing build: *** (Required for PyPI uploads)\n") - os.system("python -m pip install --upgrade 'build>=0.9.0'") + os.system("python -m pip install --upgrade 'build'") + print("\n*** Installing pkginfo: *** (Required for PyPI uploads)\n") + os.system("python -m pip install --upgrade 'pkginfo'") + print("\n*** Installing readme-renderer: *** (For PyPI uploads)\n") + os.system("python -m pip install --upgrade 'readme-renderer'") + print("\n*** Installing jaraco.classes: *** (For PyPI uploads)\n") + os.system("python -m pip install --upgrade 'jaraco.classes'") + print("\n*** Installing more-itertools: *** (For PyPI uploads)\n") + os.system("python -m pip install --upgrade 'more-itertools'") + print("\n*** Installing zipp: *** (Required for PyPI uploads)\n") + os.system("python -m pip install --upgrade 'zipp'") + print("\n*** Installing importlib-metadata: *** (For PyPI uploads)\n") + os.system("python -m pip install --upgrade 'importlib-metadata'") + print("\n*** Installing keyring, requests-toolbelt: *** (For PyPI)\n") + os.system("python -m pip install --upgrade keyring requests-toolbelt") print("\n*** Installing twine: *** (Required for PyPI uploads)\n") - os.system("python -m pip install --upgrade 'twine>=4.0.1'") - print("\n*** Installing tqdm: *** (Required for PyPI uploads)\n") - os.system("python -m pip install --upgrade tqdm") + os.system("python -m pip install --upgrade 'twine'") print("\n*** Rebuilding distribution packages: ***\n") os.system("python -m build") # Create new tar/wheel print("\n*** Publishing The Release to PyPI: ***\n") @@ -98,8 +105,6 @@ "Operating System :: POSIX :: Linux", "Programming Language :: Python", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 2.7", - "Programming Language :: Python :: 3.6", "Programming Language :: Python :: 3.7", "Programming Language :: Python :: 3.8", "Programming Language :: Python :: 3.9", @@ -116,29 +121,27 @@ "Topic :: Software Development :: Testing :: Traffic Generation", "Topic :: Utilities", ], - python_requires=">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*", # noqa: E501 + python_requires=">=3.7", install_requires=[], extras_require={ # pip install -e .[coverage] # Usage: coverage run -m pytest; coverage html; coverage report "coverage": [ - 'coverage==5.5;python_version<"3.6"', - 'coverage==6.2;python_version>="3.6" and python_version<"3.7"', - 'coverage==6.5.0;python_version>="3.7"', - 'pytest-cov==2.12.1;python_version<"3.6"', - 'pytest-cov==4.0.0;python_version>="3.6"', + 'coverage==7.2.7;python_version<"3.8"', + 'coverage==7.3.2;python_version>="3.8"', + 'pytest-cov==4.1.0', ], + # pip install -e .[flake8] # Usage: flake8 "flake8": [ - 'flake8==3.7.9;python_version<"3.6"', - 'flake8==5.0.4;python_version>="3.6"', - 'mccabe==0.6.1;python_version<"3.6"', - 'mccabe==0.7.0;python_version>="3.6"', - 'pyflakes==2.1.1;python_version<"3.6"', - 'pyflakes==2.5.0;python_version>="3.6"', - 'pycodestyle==2.5.0;python_version<"3.6"', - 'pycodestyle==2.9.1;python_version>="3.6"', + 'flake8==5.0.4;python_version<"3.9"', + 'flake8==6.1.0;python_version>="3.9"', + "mccabe==0.7.0", + 'pyflakes==2.5.0;python_version<"3.9"', + 'pyflakes==3.1.0;python_version>="3.9"', + 'pycodestyle==2.9.1;python_version<"3.9"', + 'pycodestyle==2.11.1;python_version>="3.9"', ], }, packages=[