Skip to content

Commit

Permalink
Switch to ruff, fix flagged issues
Browse files Browse the repository at this point in the history
  • Loading branch information
inducer committed Jul 1, 2024
1 parent 3d0ed55 commit 06bf752
Show file tree
Hide file tree
Showing 9 changed files with 150 additions and 115 deletions.
13 changes: 5 additions & 8 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,19 +10,16 @@ on:
- cron: '17 3 * * 0'

jobs:
flake8:
name: Flake8
ruff:
name: Ruff
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
-
uses: actions/setup-python@v5
with:
python-version: '3.8'
- uses: actions/setup-python@v5
- name: "Main Script"
run: |
curl -L -O https://gitlab.tiker.net/inducer/ci-support/raw/main/prepare-and-run-flake8.sh
. ./prepare-and-run-flake8.sh ./pycparserext ./test
pip install ruff
ruff check
pytest:
name: Pytest on Py${{ matrix.python-version }}
Expand Down
8 changes: 4 additions & 4 deletions .gitlab-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,11 @@ Python 3:
reports:
junit: test/pytest.xml

Flake8:
Ruff:
script:
- curl -L -O https://gitlab.tiker.net/inducer/ci-support/raw/main/prepare-and-run-flake8.sh
- ". ./prepare-and-run-flake8.sh pycparserext test"
- pipx install ruff
- ruff check
tags:
- python3
- docker-runner
except:
- tags
73 changes: 37 additions & 36 deletions pycparserext/ext_c_generator.py
Original file line number Diff line number Diff line change
@@ -1,23 +1,24 @@
import pycparser.c_ast as c_ast
from pycparser.c_generator import CGenerator as CGeneratorBaseBuggy

from pycparserext.ext_c_parser import FuncDeclExt, TypeDeclExt
import pycparser.c_ast as c_ast


class CGeneratorBase(CGeneratorBaseBuggy):
# bug fix
def visit_UnaryOp(self, n):
operand = self._parenthesize_unless_simple(n.expr)
if n.op == 'p++':
return '%s++' % operand
elif n.op == 'p--':
return '%s--' % operand
elif n.op == 'sizeof':
if n.op == "p++":
return "%s++" % operand
elif n.op == "p--":
return "%s--" % operand
elif n.op == "sizeof":
# Always parenthesize the argument of sizeof since it can be
# a name.
return 'sizeof(%s)' % self.visit(n.expr)
return "sizeof(%s)" % self.visit(n.expr)
else:
# avoid merging of "- - x" or "__real__varname"
return '%s %s' % (n.op, operand)
return "%s %s" % (n.op, operand)


class AsmAndAttributesMixin(object):
Expand Down Expand Up @@ -48,64 +49,64 @@ def _generate_type(self, n, modifiers=None, emit_declname=True):
if modifiers is None:
modifiers = []
typ = type(n)
#~ print(n, modifiers)
# print(n, modifiers)

if typ in (c_ast.TypeDecl, TypeDeclExt):
s = ''
s = ""
if n.quals:
s += ' '.join(n.quals) + ' '
s += " ".join(n.quals) + " "
s += self.visit(n.type)

nstr = n.declname if n.declname and emit_declname else ''
nstr = n.declname if n.declname and emit_declname else ""
# Resolve modifiers.
# Wrap in parens to distinguish pointer to array and pointer to
# function syntax.
#
for i, modifier in enumerate(modifiers):
if isinstance(modifier, c_ast.ArrayDecl):
if i != 0 and isinstance(modifiers[i - 1], c_ast.PtrDecl):
nstr = '(' + nstr + ')'
nstr = "(" + nstr + ")"

# BUG FIX: pycparser ignores quals
dim_quals = (' '.join(modifier.dim_quals) + ' '
if modifier.dim_quals else '')
dim_quals = (" ".join(modifier.dim_quals) + " "
if modifier.dim_quals else "")

nstr += '[' + dim_quals + self.visit(modifier.dim) + ']'
nstr += "[" + dim_quals + self.visit(modifier.dim) + "]"

elif isinstance(modifier, c_ast.FuncDecl):
if i != 0 and isinstance(modifiers[i - 1], c_ast.PtrDecl):
nstr = '(' + nstr + ')'
nstr += '(' + self.visit(modifier.args) + ')'
nstr = "(" + nstr + ")"
nstr += "(" + self.visit(modifier.args) + ")"

elif isinstance(modifier, FuncDeclExt):
if i != 0 and isinstance(modifiers[i - 1], c_ast.PtrDecl):
nstr = '(' + nstr + ')'
nstr += '(' + self.visit(modifier.args) + ')'
nstr = "(" + nstr + ")"
nstr += "(" + self.visit(modifier.args) + ")"

if modifier.asm is not None:
nstr += " " + self.visit(modifier.asm)

if modifier.attributes.exprs:
nstr += (
' __attribute__(('
" __attribute__(("
+ self.visit(modifier.attributes)
+ '))')
+ "))")

elif isinstance(modifier, c_ast.PtrDecl):
# BUG FIX: pycparser ignores quals
quals = ' '.join(modifier.quals)
quals = " ".join(modifier.quals)
if quals:
quals = quals + ' '
nstr = '*' + quals + nstr
quals = quals + " "
nstr = "*" + quals + nstr

if hasattr(n, "asm") and n.asm:
nstr += self.visit(n.asm)

if hasattr(n, "attributes") and n.attributes.exprs:
nstr += ' __attribute__((' + self.visit(n.attributes) + '))'
nstr += " __attribute__((" + self.visit(n.attributes) + "))"

if nstr:
s += ' ' + nstr
s += " " + nstr
return s

elif typ == c_ast.Decl:
Expand All @@ -115,7 +116,7 @@ def _generate_type(self, n, modifiers=None, emit_declname=True):
return self._generate_type(n.type, emit_declname=emit_declname)

elif typ == c_ast.IdentifierType:
return ' '.join(n.names) + ' '
return " ".join(n.names) + " "

elif typ in (c_ast.ArrayDecl, c_ast.PtrDecl, c_ast.FuncDecl, FuncDeclExt):
return self._generate_type(
Expand All @@ -127,7 +128,7 @@ def _generate_type(self, n, modifiers=None, emit_declname=True):
def _generate_decl(self, n):
""" Generation from a Decl node.
"""
s = ''
s = ""

def funcspec_to_str(i):
if isinstance(i, c_ast.Node):
Expand All @@ -136,14 +137,14 @@ def funcspec_to_str(i):
return i

if n.funcspec:
s = ' '.join(funcspec_to_str(i) for i in n.funcspec) + ' '
s = " ".join(funcspec_to_str(i) for i in n.funcspec) + " "
if n.storage:
s += ' '.join(n.storage) + ' '
s += " ".join(n.storage) + " "
s += self._generate_type(n.type)
return s

def visit_AttributeSpecifier(self, n):
return ' __attribute__((' + self.visit(n.exprlist) + '))'
return " __attribute__((" + self.visit(n.exprlist) + "))"


class GnuCGenerator(AsmAndAttributesMixin, CGeneratorBase):
Expand All @@ -154,10 +155,10 @@ def visit_TypeOfExpression(self, n):
return "%s(%s)" % (n.typeof_keyword, self.visit(n.expr))

def visit_TypeList(self, n):
return ', '.join(self.visit(ch) for ch in n.types)
return ", ".join(self.visit(ch) for ch in n.types)

def visit_RangeExpression(self, n):
return '%s ... %s' % (self.visit(n.first), self.visit(n.last))
return "%s ... %s" % (self.visit(n.first), self.visit(n.last))


class GNUCGenerator(GnuCGenerator):
Expand All @@ -169,13 +170,13 @@ def __init__(self):

class OpenCLCGenerator(AsmAndAttributesMixin, CGeneratorBase):
def visit_FileAST(self, n):
s = ''
s = ""
from pycparserext.ext_c_parser import PreprocessorLine
for ext in n.ext:
if isinstance(ext, (c_ast.FuncDef, PreprocessorLine)):
s += self.visit(ext)
else:
s += self.visit(ext) + ';\n'
s += self.visit(ext) + ";\n"
return s

def visit_PreprocessorLine(self, n):
Expand Down
52 changes: 27 additions & 25 deletions pycparserext/ext_c_lexer.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
from pycparser.c_lexer import CLexer as CLexerBase


try:
from pycparser.ply.lex import TOKEN
except ImportError:
Expand All @@ -8,16 +10,16 @@
class GnuCLexer(CLexerBase):
# support '3i' for imaginary literal
floating_constant = (
'(((('
+ CLexerBase.fractional_constant+')'
+ CLexerBase.exponent_part+'?)|([0-9]+'
+ CLexerBase.exponent_part+'))i?[FfLl]?)')
"(((("
+ CLexerBase.fractional_constant+")"
+ CLexerBase.exponent_part+"?)|([0-9]+"
+ CLexerBase.exponent_part+"))i?[FfLl]?)")

@TOKEN(floating_constant)
def t_FLOAT_CONST(self, t):
def t_FLOAT_CONST(self, t): # noqa: N802
return t

t_pppragma_ignore = ' \t<>.-{}();+-*/$%@&^~!?:,0123456789='
t_pppragma_ignore = " \t<>.-{}();+-*/$%@&^~!?:,0123456789="


class GNUCLexer(GnuCLexer):
Expand All @@ -30,21 +32,21 @@ def __init__(self, *args, **kwargs):


class OpenCLCLexer(CLexerBase):
tokens = CLexerBase.tokens + ('LINECOMMENT',)
tokens = CLexerBase.tokens + ("LINECOMMENT",)
states = (
# ('comment', 'exclusive'),
# ('preproc', 'exclusive'),
('ppline', 'exclusive'), # unused
('pppragma', 'exclusive'), # unused
("ppline", "exclusive"), # unused
("pppragma", "exclusive"), # unused
)

def t_LINECOMMENT(self, t):
r'\/\/([^\n]+)\n'
def t_LINECOMMENT(self, t): # noqa: N802
r"\/\/([^\n]+)\n"
t.lexer.lineno += t.value.count("\n")

# overrides pycparser, must have same name
def t_PPHASH(self, t):
r'[ \t]*\#([^\n]|\\\n)+[^\n\\]\n'
def t_PPHASH(self, t): # noqa: N802
r"[ \t]*\#([^\n]|\\\n)+[^\n\\]\n"
t.lexer.lineno += t.value.count("\n")
return t

Expand All @@ -61,25 +63,25 @@ def add_lexer_keywords(cls, keywords):


_COMMON_KEYWORDS = [
'__attribute__', '__attribute',
'__asm__', '__asm', 'asm']
"__attribute__", "__attribute",
"__asm__", "__asm", "asm"]

_GNU_KEYWORDS = [
'__typeof__', 'typeof', '__typeof',
'__real__', '__imag__',
'__builtin_types_compatible_p',
'__const',
'__restrict__', '__restrict',
'__inline__', '__inline',
'__extension__',
'__volatile', '__volatile__']
"__typeof__", "typeof", "__typeof",
"__real__", "__imag__",
"__builtin_types_compatible_p",
"__const",
"__restrict__", "__restrict",
"__inline__", "__inline",
"__extension__",
"__volatile", "__volatile__"]

add_lexer_keywords(GnuCLexer, _COMMON_KEYWORDS + _GNU_KEYWORDS)

# These will be added as unadorned keywords and keywords with '__' prepended
_CL_BASE_KEYWORDS = [
'kernel', 'constant', 'global', 'local', 'private',
'read_only', 'write_only', 'read_write']
"kernel", "constant", "global", "local", "private",
"read_only", "write_only", "read_write"]

_CL_KEYWORDS = _COMMON_KEYWORDS
_CL_KEYWORDS += _CL_BASE_KEYWORDS + ["__"+kw for kw in _CL_BASE_KEYWORDS]
Expand Down
Loading

0 comments on commit 06bf752

Please sign in to comment.