Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

drop python < 3.8 #56

Open
wants to merge 9 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
83 changes: 22 additions & 61 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,92 +21,53 @@ jobs:
strategy:
fail-fast: false
matrix:
include:
# Linux
- tox_env: "py39-coverage"
python: "3.9"
os: ubuntu-20.04
- tox_env: "py38-coverage"
python: "3.8"
os: ubuntu-20.04
- tox_env: "py37-coverage"
python: "3.7"
os: ubuntu-20.04
- tox_env: "py36-coverage"
python: "3.6"
os: ubuntu-20.04
- tox_env: "py35-coverage"
python: "3.5"
os: ubuntu-20.04

- tox_env: "py27-coverage"
python: "2.7"
os: ubuntu-20.04

- tox_env: "pypy3-coverage"
python: "pypy-3.7"
os: ubuntu-20.04
- tox_env: "pypy-coverage"
python: "pypy-2.7"
os: ubuntu-20.04
os: [ubuntu-latest]
python: ["3.8", "3.9", "3.10", "3.11"]

steps:
- uses: actions/checkout@v2
with:
fetch-depth: 0
- uses: actions/checkout@v4
- name: Set up Python ${{ matrix.python }}
uses: actions/setup-python@v2
uses: actions/setup-python@v4
with:
python-version: ${{ matrix.python }}

# Caching.
- name: Set tox_env
run: |
pyv=$(echo ${{matrix.python}} | sed 's/\.//')
tox_env=py${pyv}-coverage
echo "tox env name: ${tox_env}"
echo "tox_env=${tox_env}">> $GITHUB_ENV

- name: set PY_CACHE_KEY
run: echo "PY_CACHE_KEY=$(python -c 'import hashlib, sys;print(hashlib.sha256(sys.version.encode()+sys.executable.encode()).hexdigest())')" >> $GITHUB_ENV
- name: Cache .tox
uses: actions/cache@v1
uses: actions/cache@v3
with:
path: ${{ github.workspace }}/.tox/${{ matrix.tox_env }}
key: "tox|${{ matrix.os }}|${{ matrix.tox_env }}|${{ env.PY_CACHE_KEY }}|${{ hashFiles('tox.ini', 'setup.*') }}"
path: ${{ github.workspace }}/.tox/${{ env.tox_env }}
key: "tox|${{ matrix.os }}|${{ env.tox_env }}|${{ env.PY_CACHE_KEY }}|${{ hashFiles('tox.ini', 'setup.*') }}"

- name: (Initial) version information/pinning
- name: Install/update tools
run: |
set -x
python -m site
python -m pip --version
python -m pip list
if [[ "${{ matrix.python }}" == "3.4" ]]; then
# Install latest available pip.
# 7.1.2 (installed) is too old to not install too new packages,
# including pip itself. 19.2 dropped support for Python 3.4.
python -m pip install -U pip==19.1.1
fi
python -m pip install -U setuptools==42.0.2
python -m pip install -U virtualenv==20.4.3

- name: Install tox
run: python -m pip install git+https://github.com/blueyed/tox@master

- name: Version information
run: python -m pip list
pip install -U pip setuptools virtualenv tox

- name: Setup tox environment
id: setup-tox
run: python -m tox --notest -v --durations -e ${{ matrix.tox_env }}
run: tox --notest -v -e ${{ env.tox_env }}

- name: Test
env:
COLUMNS: "90" # better alignment (working around https://github.com/blueyed/pytest/issues/491).
COLUMNS: "90" # better alignment (working around https://github.com/blueyed/pytest/issues/491).
PY_COLORS: "1"
# UTF-8 mode for Windows (https://docs.python.org/3/using/windows.html#utf-8-mode).
PYTHONUTF8: "1"
TOX_TESTENV_PASSENV: "PYTHONUTF8"
run: python -m tox -v --durations -e ${{ matrix.tox_env }}
run: tox -v -e ${{ env.tox_env }}

- name: Report coverage
if: always() && (steps.setup-tox.outcome == 'success' && contains(matrix.tox_env, '-coverage'))
uses: codecov/codecov-action@v1
if: always() && (steps.setup-tox.outcome == 'success' && contains(env.tox_env, '-coverage'))
uses: codecov/codecov-action@v3
with:
files: ./coverage.xml
flags: ${{ runner.os }}
name: ${{ matrix.tox_env }}
name: ${{ env.tox_env }}
fail_ci_if_error: true
28 changes: 28 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
name: Publish package to PyPI

on:
release:
types:
- published
workflow_dispatch:

jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v4
with:
python-version: "3.9"
- name: Install requirements
run: |
pip install -U pip twine build
- name: Build
run: python -m build
- run: check-manifest
- run: twine check dist/*
- name: Publish to PyPI
env:
TWINE_USERNAME: "__token__"
TWINE_PASSWORD: ${{ secrets.PYPI_TOKEN }}
run: twine upload dist/*
56 changes: 56 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
__pycache__/
*.py[cod]
*$py.class
*.so
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
share/python-wheels/
*.egg-info/
.installed.cfg
*.egg
MANIFEST
*.manifest
*.spec
pip-log.txt
pip-delete-this-directory.txt
htmlcov/
.tox/
.nox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*.cover
*.py,cover
.hypothesis/
.pytest_cache/
cover/
*.mo
*.pot
*.log

.env
.venv
env/
venv/
ENV/
env.bak/
venv.bak/

.mypy_cache/
.dmypy.json
dmypy.json

.ruff_cache/
31 changes: 0 additions & 31 deletions .travis.yml

This file was deleted.

16 changes: 16 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
[tool.ruff.lint]
select = [
# pycodestyle
"E",
# Pyflakes
"F",
# pyupgrade
"UP",
# flake8-bugbear
"B",
# flake8-simplify
"SIM",
# isort
"I",
]
ignore = ["F401"]
20 changes: 9 additions & 11 deletions pyrepl/_minimal_curses.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,19 +17,19 @@ class error(Exception):


def _find_clib():
trylibs = ['ncursesw', 'ncurses', 'curses']
trylibs = ["ncursesw", "ncurses", "curses"]

for lib in trylibs:
path = ctypes.util.find_library(lib)
if path:
return path
raise ImportError("curses library not found")


_clibpath = _find_clib()
clib = ctypes.cdll.LoadLibrary(_clibpath)

clib.setupterm.argtypes = [ctypes.c_char_p, ctypes.c_int,
ctypes.POINTER(ctypes.c_int)]
clib.setupterm.argtypes = [ctypes.c_char_p, ctypes.c_int, ctypes.POINTER(ctypes.c_int)]
clib.setupterm.restype = ctypes.c_int

clib.tigetstr.argtypes = [ctypes.c_char_p]
Expand All @@ -45,27 +45,25 @@ def _find_clib():

try:
from __pypy__ import builtinify
builtinify # silence broken pyflakes
except ImportError:
builtinify = lambda f: f
def builtinify(f):
return f


@builtinify
def setupterm(termstr, fd):
if termstr is not None:
if not isinstance(termstr, bytes):
termstr = termstr.encode()
if termstr is not None and not isinstance(termstr, bytes):
termstr = termstr.encode()
err = ctypes.c_int(0)
result = clib.setupterm(termstr, fd, ctypes.byref(err))
if result == ERR:
raise error("setupterm(%r, %d) failed (err=%d)" % (
termstr, fd, err.value))
raise error("setupterm(%r, %d) failed (err=%d)" % (termstr, fd, err.value))


@builtinify
def tigetstr(cap):
if not isinstance(cap, bytes):
cap = cap.encode('ascii')
cap = cap.encode("ascii")
result = clib.tigetstr(cap)
if ctypes.cast(result, ctypes.c_void_p).value == ERR:
return None
Expand Down
39 changes: 19 additions & 20 deletions pyrepl/cmdrepl.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,33 +33,31 @@
which is in fact done by the `pythoni' script that comes with
pyrepl."""

from __future__ import print_function

import cmd

from pyrepl import completer
from pyrepl.completing_reader import CompletingReader as CR
import cmd


class CmdReader(CR):
def collect_keymap(self):
return super(CmdReader, self).collect_keymap() + (
return super().collect_keymap() + (
("\\M-\\n", "invalid-key"),
("\\n", "accept"))
("\\n", "accept"),
)

def __init__(self, completions):
super(CmdReader, self).__init__()
super().__init__()
self.completions = completions

def get_completions(self, stem):
if len(stem) != self.pos:
return []
return sorted(set(s
for s in self.completions
if s.startswith(stem)))
return sorted(set(s for s in self.completions if s.startswith(stem)))


def replize(klass, history_across_invocations=1):

"""Return a subclass of the cmd.Cmd-derived klass that uses
pyrepl instead of readline.

Expand All @@ -69,29 +67,29 @@ def replize(klass, history_across_invocations=1):
controls whether instances of the returned class share
histories."""

completions = [s[3:]
for s in completer.get_class_members(klass)
if s.startswith("do_")]
completions = [
s[3:] for s in completer.get_class_members(klass) if s.startswith("do_")
]

assert issubclass(klass, cmd.Cmd)
# if klass.cmdloop.im_class is not cmd.Cmd:
# print "this may not work"
# if klass.cmdloop.im_class is not cmd.Cmd:
# print "this may not work"

class MultiHist(object):
class MultiHist:
__history = []

def __init__(self, *args, **kw):
super(MultiHist, self).__init__(*args, **kw)
super().__init__(*args, **kw)
self.__reader = CmdReader(completions)
self.__reader.history = self.__history
self.__reader.historyi = len(self.__history)

class SimpleHist(object):
class SimpleHist:
def __init__(self, *args, **kw):
super(SimpleHist, self).__init__(*args, **kw)
super().__init__(*args, **kw)
self.__reader = CmdReader(completions)

class CmdLoopMixin(object):
class CmdLoopMixin:
def cmdloop(self, intro=None):
self.preloop()
if intro is not None:
Expand All @@ -117,5 +115,6 @@ def cmdloop(self, intro=None):
hist = MultiHist if history_across_invocations else SimpleHist

class CmdRepl(hist, CmdLoopMixin, klass):
__name__ = "replize(%s.%s)" % (klass.__module__, klass.__name__)
__name__ = f"replize({klass.__module__}.{klass.__name__})"

return CmdRepl
Loading