Commit 2c47e7d3 authored by Robert Bradshaw's avatar Robert Bradshaw

Add directive to control pickling.

parent 9e98eaf9
...@@ -144,6 +144,7 @@ _directive_defaults = { ...@@ -144,6 +144,7 @@ _directive_defaults = {
'embedsignature' : False, 'embedsignature' : False,
'locals' : {}, 'locals' : {},
'auto_cpdef': False, 'auto_cpdef': False,
'auto_pickle': None,
'cdivision': False, # was True before 0.12 'cdivision': False, # was True before 0.12
'cdivision_warnings': False, 'cdivision_warnings': False,
'overflowcheck': False, 'overflowcheck': False,
...@@ -263,6 +264,7 @@ def normalise_encoding_name(option_name, encoding): ...@@ -263,6 +264,7 @@ def normalise_encoding_name(option_name, encoding):
# Override types possibilities above, if needed # Override types possibilities above, if needed
directive_types = { directive_types = {
'auto_pickle': bool,
'final' : bool, # final cdef classes and methods 'final' : bool, # final cdef classes and methods
'internal' : bool, # cdef class visibility in the module dict 'internal' : bool, # cdef class visibility in the module dict
'infer_types' : bool, # values can be True/None/False 'infer_types' : bool, # values can be True/None/False
...@@ -285,6 +287,7 @@ for key, val in _directive_defaults.items(): ...@@ -285,6 +287,7 @@ for key, val in _directive_defaults.items():
directive_scopes = { # defaults to available everywhere directive_scopes = { # defaults to available everywhere
# 'module', 'function', 'class', 'with statement' # 'module', 'function', 'class', 'with statement'
'auto_pickle': ('module', 'cclass'),
'final' : ('cclass', 'function'), 'final' : ('cclass', 'function'),
'inline' : ('function',), 'inline' : ('function',),
'staticmethod' : ('function',), # FIXME: analysis currently lacks more specific function scope 'staticmethod' : ('function',), # FIXME: analysis currently lacks more specific function scope
......
...@@ -1571,6 +1571,10 @@ if VALUE is not None: ...@@ -1571,6 +1571,10 @@ if VALUE is not None:
def _inject_pickle_methods(self, node): def _inject_pickle_methods(self, node):
env = self.current_env() env = self.current_env()
if node.scope.directives['auto_pickle'] is False: # None means attempt it.
# Old behavior of not doing anything.
return
all_members = [] all_members = []
cls = node.entry.type cls = node.entry.type
cinit = None cinit = None
...@@ -1590,7 +1594,11 @@ if VALUE is not None: ...@@ -1590,7 +1594,11 @@ if VALUE is not None:
# TODO(robertwb): We could allow this if __cinit__ has no require arguments. # TODO(robertwb): We could allow this if __cinit__ has no require arguments.
msg = 'no default __reduce__ due to non-trivial __cinit__' msg = 'no default __reduce__ due to non-trivial __cinit__'
else: else:
msg = "%s cannot be converted to a Python object" % ','.join("self.%s" % e.name for e in non_py) msg = "%s cannot be converted to a Python object for pickling" % ','.join("self.%s" % e.name for e in non_py)
if node.scope.directives['auto_pickle'] is True:
error(node.pos, msg)
pickle_func = TreeFragment(u""" pickle_func = TreeFragment(u"""
def __reduce__(self): def __reduce__(self):
raise TypeError("%s") raise TypeError("%s")
......
import cython
import sys import sys
if sys.version_info[0] < 3: if sys.version_info[0] < 3:
...@@ -59,6 +60,7 @@ def makeB(kwds): ...@@ -59,6 +60,7 @@ def makeB(kwds):
return B(**kwds) return B(**kwds)
@cython.auto_pickle(True) # Not needed, just to test the directive.
cdef class DefaultReduce(object): cdef class DefaultReduce(object):
""" """
>>> a = DefaultReduce(11, 'abc'); a >>> a = DefaultReduce(11, 'abc'); a
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment