summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEli Bendersky <eliben@gmail.com>2015-04-21 17:04:53 -0700
committerEli Bendersky <eliben@gmail.com>2015-04-21 17:04:53 -0700
commit978ad7a61d7e1cfe77dbacb81f1690e6bb89a11b (patch)
tree4ab6b9e94950df6f24cc089f6e886d8f13ebeb9c
parent40af8bdaf34f42c488ea45f98b40c951250bc6d1 (diff)
downloadpycparser-978ad7a61d7e1cfe77dbacb81f1690e6bb89a11b.tar.gz
Support weakref to AST objects.
weakref support was broken by setting __slots__ on AST objects to conserve memory. Reinstate it. See issue #76, #75
-rw-r--r--TODO.txt3
-rw-r--r--pycparser/_ast_gen.py4
-rw-r--r--pycparser/c_ast.py92
-rw-r--r--pycparser/plyparser.py2
-rw-r--r--tests/test_c_ast.py8
5 files changed, 58 insertions, 51 deletions
diff --git a/TODO.txt b/TODO.txt
index c76b0a1..959fbb7 100644
--- a/TODO.txt
+++ b/TODO.txt
@@ -11,8 +11,7 @@ Version Update
--------------
setup.py, __init__.py, README, CHANGES
-- Make sure _build_tables was run in pycparser/ and the tables are in the
- MANIFEST
+- Make sure _build_tables was run in pycparser/
- Tag in git. When pushing to GitHub, git push --tags
- If PLY version changes, note it in README and ply/LICENSE
- Run tox tests
diff --git a/pycparser/_ast_gen.py b/pycparser/_ast_gen.py
index 654fad6..ddbfd67 100644
--- a/pycparser/_ast_gen.py
+++ b/pycparser/_ast_gen.py
@@ -93,10 +93,10 @@ class NodeCfg(object):
if self.all_entries:
args = ', '.join(self.all_entries)
slots = ', '.join("'{0}'".format(e) for e in self.all_entries)
- slots += ", 'coord'"
+ slots += ", 'coord', '__weakref__'"
arglist = '(self, %s, coord=None)' % args
else:
- slots = "'coord',"
+ slots = "'coord', '__weakref__'"
arglist = '(self, coord=None)'
src += " __slots__ = (%s)\n" % slots
diff --git a/pycparser/c_ast.py b/pycparser/c_ast.py
index 04a6e5e..d90ac36 100644
--- a/pycparser/c_ast.py
+++ b/pycparser/c_ast.py
@@ -128,7 +128,7 @@ class NodeVisitor(object):
class ArrayDecl(Node):
- __slots__ = ('type', 'dim', 'dim_quals', 'coord')
+ __slots__ = ('type', 'dim', 'dim_quals', 'coord', '__weakref__')
def __init__(self, type, dim, dim_quals, coord=None):
self.type = type
self.dim = dim
@@ -144,7 +144,7 @@ class ArrayDecl(Node):
attr_names = ('dim_quals', )
class ArrayRef(Node):
- __slots__ = ('name', 'subscript', 'coord')
+ __slots__ = ('name', 'subscript', 'coord', '__weakref__')
def __init__(self, name, subscript, coord=None):
self.name = name
self.subscript = subscript
@@ -159,7 +159,7 @@ class ArrayRef(Node):
attr_names = ()
class Assignment(Node):
- __slots__ = ('op', 'lvalue', 'rvalue', 'coord')
+ __slots__ = ('op', 'lvalue', 'rvalue', 'coord', '__weakref__')
def __init__(self, op, lvalue, rvalue, coord=None):
self.op = op
self.lvalue = lvalue
@@ -175,7 +175,7 @@ class Assignment(Node):
attr_names = ('op', )
class BinaryOp(Node):
- __slots__ = ('op', 'left', 'right', 'coord')
+ __slots__ = ('op', 'left', 'right', 'coord', '__weakref__')
def __init__(self, op, left, right, coord=None):
self.op = op
self.left = left
@@ -191,7 +191,7 @@ class BinaryOp(Node):
attr_names = ('op', )
class Break(Node):
- __slots__ = ('coord',)
+ __slots__ = ('coord', '__weakref__')
def __init__(self, coord=None):
self.coord = coord
@@ -201,7 +201,7 @@ class Break(Node):
attr_names = ()
class Case(Node):
- __slots__ = ('expr', 'stmts', 'coord')
+ __slots__ = ('expr', 'stmts', 'coord', '__weakref__')
def __init__(self, expr, stmts, coord=None):
self.expr = expr
self.stmts = stmts
@@ -217,7 +217,7 @@ class Case(Node):
attr_names = ()
class Cast(Node):
- __slots__ = ('to_type', 'expr', 'coord')
+ __slots__ = ('to_type', 'expr', 'coord', '__weakref__')
def __init__(self, to_type, expr, coord=None):
self.to_type = to_type
self.expr = expr
@@ -232,7 +232,7 @@ class Cast(Node):
attr_names = ()
class Compound(Node):
- __slots__ = ('block_items', 'coord')
+ __slots__ = ('block_items', 'coord', '__weakref__')
def __init__(self, block_items, coord=None):
self.block_items = block_items
self.coord = coord
@@ -246,7 +246,7 @@ class Compound(Node):
attr_names = ()
class CompoundLiteral(Node):
- __slots__ = ('type', 'init', 'coord')
+ __slots__ = ('type', 'init', 'coord', '__weakref__')
def __init__(self, type, init, coord=None):
self.type = type
self.init = init
@@ -261,7 +261,7 @@ class CompoundLiteral(Node):
attr_names = ()
class Constant(Node):
- __slots__ = ('type', 'value', 'coord')
+ __slots__ = ('type', 'value', 'coord', '__weakref__')
def __init__(self, type, value, coord=None):
self.type = type
self.value = value
@@ -274,7 +274,7 @@ class Constant(Node):
attr_names = ('type', 'value', )
class Continue(Node):
- __slots__ = ('coord',)
+ __slots__ = ('coord', '__weakref__')
def __init__(self, coord=None):
self.coord = coord
@@ -284,7 +284,7 @@ class Continue(Node):
attr_names = ()
class Decl(Node):
- __slots__ = ('name', 'quals', 'storage', 'funcspec', 'type', 'init', 'bitsize', 'coord')
+ __slots__ = ('name', 'quals', 'storage', 'funcspec', 'type', 'init', 'bitsize', 'coord', '__weakref__')
def __init__(self, name, quals, storage, funcspec, type, init, bitsize, coord=None):
self.name = name
self.quals = quals
@@ -305,7 +305,7 @@ class Decl(Node):
attr_names = ('name', 'quals', 'storage', 'funcspec', )
class DeclList(Node):
- __slots__ = ('decls', 'coord')
+ __slots__ = ('decls', 'coord', '__weakref__')
def __init__(self, decls, coord=None):
self.decls = decls
self.coord = coord
@@ -319,7 +319,7 @@ class DeclList(Node):
attr_names = ()
class Default(Node):
- __slots__ = ('stmts', 'coord')
+ __slots__ = ('stmts', 'coord', '__weakref__')
def __init__(self, stmts, coord=None):
self.stmts = stmts
self.coord = coord
@@ -333,7 +333,7 @@ class Default(Node):
attr_names = ()
class DoWhile(Node):
- __slots__ = ('cond', 'stmt', 'coord')
+ __slots__ = ('cond', 'stmt', 'coord', '__weakref__')
def __init__(self, cond, stmt, coord=None):
self.cond = cond
self.stmt = stmt
@@ -348,7 +348,7 @@ class DoWhile(Node):
attr_names = ()
class EllipsisParam(Node):
- __slots__ = ('coord',)
+ __slots__ = ('coord', '__weakref__')
def __init__(self, coord=None):
self.coord = coord
@@ -358,7 +358,7 @@ class EllipsisParam(Node):
attr_names = ()
class EmptyStatement(Node):
- __slots__ = ('coord',)
+ __slots__ = ('coord', '__weakref__')
def __init__(self, coord=None):
self.coord = coord
@@ -368,7 +368,7 @@ class EmptyStatement(Node):
attr_names = ()
class Enum(Node):
- __slots__ = ('name', 'values', 'coord')
+ __slots__ = ('name', 'values', 'coord', '__weakref__')
def __init__(self, name, values, coord=None):
self.name = name
self.values = values
@@ -382,7 +382,7 @@ class Enum(Node):
attr_names = ('name', )
class Enumerator(Node):
- __slots__ = ('name', 'value', 'coord')
+ __slots__ = ('name', 'value', 'coord', '__weakref__')
def __init__(self, name, value, coord=None):
self.name = name
self.value = value
@@ -396,7 +396,7 @@ class Enumerator(Node):
attr_names = ('name', )
class EnumeratorList(Node):
- __slots__ = ('enumerators', 'coord')
+ __slots__ = ('enumerators', 'coord', '__weakref__')
def __init__(self, enumerators, coord=None):
self.enumerators = enumerators
self.coord = coord
@@ -410,7 +410,7 @@ class EnumeratorList(Node):
attr_names = ()
class ExprList(Node):
- __slots__ = ('exprs', 'coord')
+ __slots__ = ('exprs', 'coord', '__weakref__')
def __init__(self, exprs, coord=None):
self.exprs = exprs
self.coord = coord
@@ -424,7 +424,7 @@ class ExprList(Node):
attr_names = ()
class FileAST(Node):
- __slots__ = ('ext', 'coord')
+ __slots__ = ('ext', 'coord', '__weakref__')
def __init__(self, ext, coord=None):
self.ext = ext
self.coord = coord
@@ -438,7 +438,7 @@ class FileAST(Node):
attr_names = ()
class For(Node):
- __slots__ = ('init', 'cond', 'next', 'stmt', 'coord')
+ __slots__ = ('init', 'cond', 'next', 'stmt', 'coord', '__weakref__')
def __init__(self, init, cond, next, stmt, coord=None):
self.init = init
self.cond = cond
@@ -457,7 +457,7 @@ class For(Node):
attr_names = ()
class FuncCall(Node):
- __slots__ = ('name', 'args', 'coord')
+ __slots__ = ('name', 'args', 'coord', '__weakref__')
def __init__(self, name, args, coord=None):
self.name = name
self.args = args
@@ -472,7 +472,7 @@ class FuncCall(Node):
attr_names = ()
class FuncDecl(Node):
- __slots__ = ('args', 'type', 'coord')
+ __slots__ = ('args', 'type', 'coord', '__weakref__')
def __init__(self, args, type, coord=None):
self.args = args
self.type = type
@@ -487,7 +487,7 @@ class FuncDecl(Node):
attr_names = ()
class FuncDef(Node):
- __slots__ = ('decl', 'param_decls', 'body', 'coord')
+ __slots__ = ('decl', 'param_decls', 'body', 'coord', '__weakref__')
def __init__(self, decl, param_decls, body, coord=None):
self.decl = decl
self.param_decls = param_decls
@@ -505,7 +505,7 @@ class FuncDef(Node):
attr_names = ()
class Goto(Node):
- __slots__ = ('name', 'coord')
+ __slots__ = ('name', 'coord', '__weakref__')
def __init__(self, name, coord=None):
self.name = name
self.coord = coord
@@ -517,7 +517,7 @@ class Goto(Node):
attr_names = ('name', )
class ID(Node):
- __slots__ = ('name', 'coord')
+ __slots__ = ('name', 'coord', '__weakref__')
def __init__(self, name, coord=None):
self.name = name
self.coord = coord
@@ -529,7 +529,7 @@ class ID(Node):
attr_names = ('name', )
class IdentifierType(Node):
- __slots__ = ('names', 'coord')
+ __slots__ = ('names', 'coord', '__weakref__')
def __init__(self, names, coord=None):
self.names = names
self.coord = coord
@@ -541,7 +541,7 @@ class IdentifierType(Node):
attr_names = ('names', )
class If(Node):
- __slots__ = ('cond', 'iftrue', 'iffalse', 'coord')
+ __slots__ = ('cond', 'iftrue', 'iffalse', 'coord', '__weakref__')
def __init__(self, cond, iftrue, iffalse, coord=None):
self.cond = cond
self.iftrue = iftrue
@@ -558,7 +558,7 @@ class If(Node):
attr_names = ()
class InitList(Node):
- __slots__ = ('exprs', 'coord')
+ __slots__ = ('exprs', 'coord', '__weakref__')
def __init__(self, exprs, coord=None):
self.exprs = exprs
self.coord = coord
@@ -572,7 +572,7 @@ class InitList(Node):
attr_names = ()
class Label(Node):
- __slots__ = ('name', 'stmt', 'coord')
+ __slots__ = ('name', 'stmt', 'coord', '__weakref__')
def __init__(self, name, stmt, coord=None):
self.name = name
self.stmt = stmt
@@ -586,7 +586,7 @@ class Label(Node):
attr_names = ('name', )
class NamedInitializer(Node):
- __slots__ = ('name', 'expr', 'coord')
+ __slots__ = ('name', 'expr', 'coord', '__weakref__')
def __init__(self, name, expr, coord=None):
self.name = name
self.expr = expr
@@ -602,7 +602,7 @@ class NamedInitializer(Node):
attr_names = ()
class ParamList(Node):
- __slots__ = ('params', 'coord')
+ __slots__ = ('params', 'coord', '__weakref__')
def __init__(self, params, coord=None):
self.params = params
self.coord = coord
@@ -616,7 +616,7 @@ class ParamList(Node):
attr_names = ()
class PtrDecl(Node):
- __slots__ = ('quals', 'type', 'coord')
+ __slots__ = ('quals', 'type', 'coord', '__weakref__')
def __init__(self, quals, type, coord=None):
self.quals = quals
self.type = type
@@ -630,7 +630,7 @@ class PtrDecl(Node):
attr_names = ('quals', )
class Return(Node):
- __slots__ = ('expr', 'coord')
+ __slots__ = ('expr', 'coord', '__weakref__')
def __init__(self, expr, coord=None):
self.expr = expr
self.coord = coord
@@ -643,7 +643,7 @@ class Return(Node):
attr_names = ()
class Struct(Node):
- __slots__ = ('name', 'decls', 'coord')
+ __slots__ = ('name', 'decls', 'coord', '__weakref__')
def __init__(self, name, decls, coord=None):
self.name = name
self.decls = decls
@@ -658,7 +658,7 @@ class Struct(Node):
attr_names = ('name', )
class StructRef(Node):
- __slots__ = ('name', 'type', 'field', 'coord')
+ __slots__ = ('name', 'type', 'field', 'coord', '__weakref__')
def __init__(self, name, type, field, coord=None):
self.name = name
self.type = type
@@ -674,7 +674,7 @@ class StructRef(Node):
attr_names = ('type', )
class Switch(Node):
- __slots__ = ('cond', 'stmt', 'coord')
+ __slots__ = ('cond', 'stmt', 'coord', '__weakref__')
def __init__(self, cond, stmt, coord=None):
self.cond = cond
self.stmt = stmt
@@ -689,7 +689,7 @@ class Switch(Node):
attr_names = ()
class TernaryOp(Node):
- __slots__ = ('cond', 'iftrue', 'iffalse', 'coord')
+ __slots__ = ('cond', 'iftrue', 'iffalse', 'coord', '__weakref__')
def __init__(self, cond, iftrue, iffalse, coord=None):
self.cond = cond
self.iftrue = iftrue
@@ -706,7 +706,7 @@ class TernaryOp(Node):
attr_names = ()
class TypeDecl(Node):
- __slots__ = ('declname', 'quals', 'type', 'coord')
+ __slots__ = ('declname', 'quals', 'type', 'coord', '__weakref__')
def __init__(self, declname, quals, type, coord=None):
self.declname = declname
self.quals = quals
@@ -721,7 +721,7 @@ class TypeDecl(Node):
attr_names = ('declname', 'quals', )
class Typedef(Node):
- __slots__ = ('name', 'quals', 'storage', 'type', 'coord')
+ __slots__ = ('name', 'quals', 'storage', 'type', 'coord', '__weakref__')
def __init__(self, name, quals, storage, type, coord=None):
self.name = name
self.quals = quals
@@ -737,7 +737,7 @@ class Typedef(Node):
attr_names = ('name', 'quals', 'storage', )
class Typename(Node):
- __slots__ = ('name', 'quals', 'type', 'coord')
+ __slots__ = ('name', 'quals', 'type', 'coord', '__weakref__')
def __init__(self, name, quals, type, coord=None):
self.name = name
self.quals = quals
@@ -752,7 +752,7 @@ class Typename(Node):
attr_names = ('name', 'quals', )
class UnaryOp(Node):
- __slots__ = ('op', 'expr', 'coord')
+ __slots__ = ('op', 'expr', 'coord', '__weakref__')
def __init__(self, op, expr, coord=None):
self.op = op
self.expr = expr
@@ -766,7 +766,7 @@ class UnaryOp(Node):
attr_names = ('op', )
class Union(Node):
- __slots__ = ('name', 'decls', 'coord')
+ __slots__ = ('name', 'decls', 'coord', '__weakref__')
def __init__(self, name, decls, coord=None):
self.name = name
self.decls = decls
@@ -781,7 +781,7 @@ class Union(Node):
attr_names = ('name', )
class While(Node):
- __slots__ = ('cond', 'stmt', 'coord')
+ __slots__ = ('cond', 'stmt', 'coord', '__weakref__')
def __init__(self, cond, stmt, coord=None):
self.cond = cond
self.stmt = stmt
diff --git a/pycparser/plyparser.py b/pycparser/plyparser.py
index 24d74e7..210a5f8 100644
--- a/pycparser/plyparser.py
+++ b/pycparser/plyparser.py
@@ -15,7 +15,7 @@ class Coord(object):
- Line number
- (optional) column number, for the Lexer
"""
- __slots__ = ('file', 'line', 'column')
+ __slots__ = ('file', 'line', 'column', '__weakref__')
def __init__(self, file, line, column=None):
self.file = file
self.line = line
diff --git a/tests/test_c_ast.py b/tests/test_c_ast.py
index e334e49..18fd542 100644
--- a/tests/test_c_ast.py
+++ b/tests/test_c_ast.py
@@ -2,6 +2,7 @@ import pprint
import re
import sys
import unittest
+import weakref
sys.path.insert(0, '..')
import pycparser.c_ast as c_ast
@@ -21,6 +22,13 @@ class Test_c_ast(unittest.TestCase):
self.failUnless(isinstance(b1.right, c_ast.ID))
self.assertEqual(b1.right.name, 'joe')
+ def test_weakref_works(self):
+ c1 = c_ast.Constant(type='float', value='3.14')
+ wr = weakref.ref(c1)
+ cref = wr()
+ self.assertEqual(cref.type, 'float')
+ self.assertEqual(weakref.getweakrefcount(c1), 1)
+
class TestNodeVisitor(unittest.TestCase):
class ConstantVisitor(c_ast.NodeVisitor):