Skip to content
Merged
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
7 changes: 4 additions & 3 deletions .github/workflows/workflow.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@ on: [push, pull_request]

jobs:
build-linux:
runs-on: ubuntu-22.04
runs-on: ubuntu-24.04
timeout-minutes: 15
strategy:
matrix:
python-version: ["3.8", "3.9", "3.10", "3.11", "3.12", "3.13"]
python-version: ["3.9", "3.10", "3.11", "3.12", "3.13", "3.14"]
fail-fast: false

steps:
Expand Down Expand Up @@ -39,12 +39,13 @@ jobs:
python -m pip install --upgrade setuptools
pip install PyYAML coverage schema python-magic pyparsing sphinx wheel
sudo apt-get update
sudo apt-get install cvs
sudo apt-get install cvs subversion

- name: Run unit tests
run: |
git config --global init.defaultBranch master # keep the old name
git config --global protocol.file.allow always # roll back CVE-2022-39253
sudo sh -c "echo 0 > /proc/sys/kernel/apparmor_restrict_unprivileged_userns"
eatmydata ./test/run-tests.sh -c xml -v

- name: Build Python package
Expand Down
2 changes: 1 addition & 1 deletion doc/installation.rst
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ Installation
Dependencies
============

Bob is built with Python3 (>=3.8). Some additional Python packages are
Bob is built with Python3 (>=3.9). Some additional Python packages are
required. They are installed automatically as dependencies.

Apart from the Python dependencies additional run time dependencies could arise,
Expand Down
4 changes: 2 additions & 2 deletions pym/bob/archive.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
from .errors import BuildError, BobError
from .tty import stepAction, stepMessage, \
SKIPPED, EXECUTED, WARNING, INFO, TRACE, ERROR, IMPORTANT
from .utils import asHexStr, removePath, isWindows, getBashPath, tarfileOpen, binStat, removePrefix
from .utils import asHexStr, removePath, isWindows, getBashPath, tarfileOpen, binStat
from .webdav import WebDav, WebdavError, WebdavNotFoundError, WebdavAlreadyExistsError
from tempfile import mkstemp, NamedTemporaryFile, TemporaryFile, gettempdir
import asyncio
Expand Down Expand Up @@ -936,7 +936,7 @@ def _listDir(self, path):
entries = []
for info in path_info:
if info["path"]:
entries.append(removePrefix(info["path"], path + "/"))
entries.append(info["path"].removeprefix(path + "/"))
return entries

def _delete(self, filename):
Expand Down
12 changes: 6 additions & 6 deletions pym/bob/cmds/archive.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
import tarfile

# need to enable this for nested expression parsing performance
pyparsing.ParserElement.enablePackrat()
pyparsing.ParserElement.enable_packrat()

class ArchiveScanner:
CUR_VERSION = 3
Expand Down Expand Up @@ -344,12 +344,12 @@ def getRetained(self):
# meta.package == "root" && build.date > "2017-06-19" LIMIT 5 ORDER BY build.date ASC
def query(scanner, expressions):
varReference = pyparsing.Word(pyparsing.alphanums+'._-')
varReference.setParseAction(lambda s, loc, toks: VarReference(s, loc, toks))
varReference.set_parse_action(lambda s, loc, toks: VarReference(s, loc, toks))

stringLiteral = pyparsing.QuotedString('"', '\\')
stringLiteral.setParseAction(lambda s, loc, toks: StringLiteral(s, loc, toks))
stringLiteral.set_parse_action(lambda s, loc, toks: StringLiteral(s, loc, toks))

selectExpr = pyparsing.infixNotation(
selectExpr = pyparsing.infix_notation(
stringLiteral | varReference,
[
('!', 1, pyparsing.opAssoc.RIGHT, lambda s, loc, toks: NotPredicate(s, loc, toks)),
Expand All @@ -371,10 +371,10 @@ def query(scanner, expressions):
varReference +
pyparsing.Optional(pyparsing.CaselessKeyword("ASC") |
pyparsing.CaselessKeyword("DESC"))))
expr.setParseAction(lambda s, loc, toks: RetainExpression(s, loc, toks))
expr.set_parse_action(lambda s, loc, toks: RetainExpression(s, loc, toks))

try:
retainExpressions = [ expr.parseString(e, True)[0] for e in expressions ]
retainExpressions = [ expr.parse_string(e, True)[0] for e in expressions ]
except pyparsing.ParseBaseException as e:
raise BobError("Invalid retention expression: " + str(e))

Expand Down
4 changes: 2 additions & 2 deletions pym/bob/develop/version.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@
if sys.version_info.major != 3:
print("Bob requires Python 3")
sys.exit(1)
elif sys.version_info.minor < 8:
print("Bob requires at least Python 3.8")
elif sys.version_info.minor < 9:
print("Bob requires at least Python 3.9")
sys.exit(1)

def getVersion():
Expand Down
16 changes: 8 additions & 8 deletions pym/bob/pathspec.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
import sqlite3

# need to enable this for nested expression parsing performance
pyparsing.ParserElement.enablePackrat()
pyparsing.ParserElement.enable_packrat()

# See "Efficient algorithms for processing XPath queries" [1] for the core
# algorithms that are applied here.
Expand Down Expand Up @@ -766,12 +766,12 @@ def __init__(self, cacheKey, aliases, stringFunctions, packageGenerator, emptyMo
abbreviatedStep = pyparsing.Keyword('.')

sQStringLiteral = pyparsing.QuotedString("'")
sQStringLiteral.setParseAction(
sQStringLiteral.set_parse_action(
lambda s, loc, toks: StringLiteral(s, loc, toks, False,
self.__stringFunctions,
self.__getGraphIter))
dQStringLiteral = pyparsing.QuotedString('"', '\\')
dQStringLiteral.setParseAction(
dQStringLiteral.set_parse_action(
lambda s, loc, toks: StringLiteral(s, loc, toks, True,
self.__stringFunctions,
self.__getGraphIter))
Expand All @@ -784,11 +784,11 @@ def __init__(self, cacheKey, aliases, stringFunctions, packageGenerator, emptyMo
pyparsing.Optional(functionArg +
pyparsing.ZeroOrMore(pyparsing.Suppress(',') + functionArg)) + \
pyparsing.Suppress(')')
functionCall.setParseAction(
functionCall.set_parse_action(
lambda s, loc, toks: FunctionCall(s, loc, toks, self.__stringFunctions,
self.__getGraphIter))

predExpr = pyparsing.infixNotation(
predExpr = pyparsing.infix_notation(
locationPath ^ stringLiteral ^ functionCall,
[
('!', 1, pyparsing.opAssoc.RIGHT, lambda s, loc, toks: NotOperator(s, loc, toks, self.__getGraphRoot, 9)),
Expand All @@ -804,7 +804,7 @@ def __init__(self, cacheKey, aliases, stringFunctions, packageGenerator, emptyMo
predicate = '[' + predExpr + ']'
step = abbreviatedStep | (pyparsing.Optional(axisSpecifier) +
nodeTest + pyparsing.Optional(predicate))
step.setParseAction(lambda s, loc, toks: LocationStep(s, loc, toks))
step.set_parse_action(lambda s, loc, toks: LocationStep(s, loc, toks))
abbreviatedRelativeLocationPath = step + '//' + relativeLocationPath
relativeLocationPath << (
abbreviatedRelativeLocationPath |
Expand All @@ -814,7 +814,7 @@ def __init__(self, cacheKey, aliases, stringFunctions, packageGenerator, emptyMo
absoluteLocationPath = abbreviatedAbsoluteLocationPath | \
('/' + relativeLocationPath)
locationPath << (absoluteLocationPath | relativeLocationPath)
locationPath.setParseAction(
locationPath.set_parse_action(
lambda s, loc, toks: LocationPath(s, loc, toks, self.__getGraphRoot))

self.__pathGrammer = locationPath
Expand Down Expand Up @@ -876,7 +876,7 @@ def __query(self, path):
while path.endswith('/'): path = path[:-1]
if path:
try:
path = self.__pathGrammer.parseString(path, True)
path = self.__pathGrammer.parse_string(path, True)
except pyparsing.ParseBaseException as e:
raise BobError("Invalid syntax: " + str(e),
help=markLocation(e.line, e.col))
Expand Down
12 changes: 6 additions & 6 deletions pym/bob/stringparser.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
import re

# need to enable this for nested expression parsing performance
pyparsing.ParserElement.enablePackrat()
pyparsing.ParserElement.enable_packrat()

NAME_START = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz'
NAME_CHARS = NAME_START + '0123456789'
Expand Down Expand Up @@ -378,11 +378,11 @@ class IfExpressionParser:
def __init__(self):
# create parsing grammer
sQStringLiteral = pyparsing.QuotedString("'")
sQStringLiteral.setParseAction(
sQStringLiteral.set_parse_action(
lambda s, loc, toks: StringLiteral(s, loc, toks, False))

dQStringLiteral = pyparsing.QuotedString('"', '\\')
dQStringLiteral.setParseAction(
dQStringLiteral.set_parse_action(
lambda s, loc, toks: StringLiteral(s, loc, toks, True))

stringLiteral = sQStringLiteral | dQStringLiteral
Expand All @@ -394,10 +394,10 @@ def __init__(self):
pyparsing.Optional(functionArg +
pyparsing.ZeroOrMore(pyparsing.Suppress(',') + functionArg)) + \
pyparsing.Suppress(')')
functionCall.setParseAction(
functionCall.set_parse_action(
lambda s, loc, toks: FunctionCall(s, loc, toks))

predExpr = pyparsing.infixNotation(
predExpr = pyparsing.infix_notation(
stringLiteral ^ functionCall ,
[
('!', 1, pyparsing.opAssoc.RIGHT, lambda s, loc, toks: NotOperator(s, loc, toks)),
Expand All @@ -415,7 +415,7 @@ def __init__(self):

def parseExpression(self, expression):
try:
ret = self.__ifgrammer.parseString(expression, True)
ret = self.__ifgrammer.parse_string(expression, True)
except pyparsing.ParseBaseException as e:
raise ParseError("Invalid syntax: " + str(e))
return ret[0]
Expand Down
8 changes: 0 additions & 8 deletions pym/bob/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -142,14 +142,6 @@ def onerror(func, path, exc):
except OSError as e:
raise BuildError("Error removing '"+path+"': " + str(e))

def removePrefix(string, prefix):
if sys.version_info >= (3, 9):
return string.removeprefix(prefix)
else:
if string.startswith(prefix):
string = string[len(prefix):]
return string

def emptyDirectory(path):
try:
if os.path.exists(path):
Expand Down
4 changes: 2 additions & 2 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -131,12 +131,12 @@ class build(build_orig):
cmdclass = cmdclass,

# Our runtime dependencies
python_requires = '>=3.8',
python_requires = '>=3.9',
install_requires = [
'PyYAML',
'schema',
'python-magic',
'pyparsing',
'pyparsing>=3',
],

# Optional dependencies that are not needed by default
Expand Down
Loading