Commit 67b9fb10 authored by Aurelien Campeas's avatar Aurelien Campeas
Browse files

remove most 3.10 bw compat

Related to #3799117.

The boxes and entityvcomponent objects cannot really be removed as they
are still used throughout the code base (and possible cubes).

This may be caused by a non-working deprecation and needs some more
work.
parent 7769d0f61810
......@@ -176,23 +176,6 @@ class XMLSyntaxValidator(Validator):
return super(XMLSyntaxValidator, self)._parse(data)
class XMLDemotingValidator(XMLValidator):
""" some views produce html instead of xhtml, using demote_to_html
this is typically related to the use of external dependencies
which do not produce valid xhtml (google maps, ...)
"""
__metaclass__ = class_deprecated
__deprecation_warning__ = '[3.10] this is now handled in testlib.py'
def preprocess_data(self, data):
if data.startswith('<?xml'):
self.parser = etree.XMLParser()
else:
self.parser = etree.HTMLParser()
return data
class HTMLValidator(Validator):
def __init__(self):
......
What's new in CubicWeb 3.20
===========================
Deprecated Code Drops
----------------------
* most 3.10 backward compat is gone (box related objects are still
there, but you are encouraged to not depend on them)
......@@ -1367,100 +1367,6 @@ class Entity(AppObject):
def clear_all_caches(self):
return self.cw_clear_all_caches()
@property
@deprecated('[3.10] use entity.cw_edited')
def edited_attributes(self):
return self.cw_edited
@property
@deprecated('[3.10] use entity.cw_edited.skip_security')
def skip_security_attributes(self):
return self.cw_edited.skip_security
@property
@deprecated('[3.10] use entity.cw_edited.skip_security')
def _cw_skip_security_attributes(self):
return self.cw_edited.skip_security
@property
@deprecated('[3.10] use entity.cw_edited.querier_pending_relations')
def querier_pending_relations(self):
return self.cw_edited.querier_pending_relations
@deprecated('[3.10] use key in entity.cw_attr_cache')
def __contains__(self, key):
return key in self.cw_attr_cache
@deprecated('[3.10] iter on entity.cw_attr_cache')
def __iter__(self):
return iter(self.cw_attr_cache)
@deprecated('[3.10] use entity.cw_attr_cache[attr]')
def __getitem__(self, key):
return self.cw_attr_cache[key]
@deprecated('[3.10] use entity.cw_attr_cache.get(attr[, default])')
def get(self, key, default=None):
return self.cw_attr_cache.get(key, default)
@deprecated('[3.10] use entity.cw_attr_cache.clear()')
def clear(self):
self.cw_attr_cache.clear()
# XXX clear cw_edited ?
@deprecated('[3.10] use entity.cw_edited[attr] = value or entity.cw_attr_cache[attr] = value')
def __setitem__(self, attr, value):
"""override __setitem__ to update self.cw_edited.
Typically, a before_[update|add]_hook could do::
entity['generated_attr'] = generated_value
and this way, cw_edited will be updated accordingly. Also, add
the attribute to skip_security since we don't want to check security
for such attributes set by hooks.
"""
try:
self.cw_edited[attr] = value
except AttributeError:
self.cw_attr_cache[attr] = value
@deprecated('[3.10] use del entity.cw_edited[attr]')
def __delitem__(self, attr):
"""override __delitem__ to update self.cw_edited on cleanup of
undesired changes introduced in the entity's dict. For example, see the
code snippet below from the `forge` cube:
.. sourcecode:: python
edited = self.entity.cw_edited
has_load_left = 'load_left' in edited
if 'load' in edited and self.entity.load_left is None:
self.entity.load_left = self.entity['load']
elif not has_load_left and edited:
# cleanup, this may cause undesired changes
del self.entity['load_left']
"""
del self.cw_edited[attr]
@deprecated('[3.10] use entity.cw_edited.setdefault(attr, default)')
def setdefault(self, attr, default):
"""override setdefault to update self.cw_edited"""
return self.cw_edited.setdefault(attr, default)
@deprecated('[3.10] use entity.cw_edited.pop(attr[, default])')
def pop(self, attr, *args):
"""override pop to update self.cw_edited on cleanup of
undesired changes introduced in the entity's dict. See `__delitem__`
"""
return self.cw_edited.pop(attr, *args)
@deprecated('[3.10] use entity.cw_edited.update(values)')
def update(self, values):
"""override update to update self.cw_edited. See `__setitem__`
"""
self.cw_edited.update(values)
# attribute and relation descriptors ##########################################
......
# copyright 2003-2013 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
# copyright 2003-2014 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
#
# This file is part of CubicWeb.
......@@ -415,10 +415,6 @@ class HooksManager(object):
for event in ALL_HOOKS:
CWRegistryStore.REGISTRY_FACTORY['%s_hooks' % event] = HooksRegistry
@deprecated('[3.10] use entity.cw_edited.oldnewvalue(attr)')
def entity_oldnewvalue(entity, attr):
return entity.cw_edited.oldnewvalue(attr)
# some hook specific predicates #################################################
......@@ -763,10 +759,6 @@ class Operation(object):
def handle_event(self, event):
"""delegate event handling to the opertaion"""
if event == 'postcommit_event' and hasattr(self, 'commit_event'):
warn('[3.10] %s: commit_event method has been replaced by postcommit_event'
% self.__class__, DeprecationWarning)
self.commit_event() # pylint: disable=E1101
getattr(self, event)()
def precommit_event(self):
......@@ -903,58 +895,6 @@ postcommit method of the operation."""
return self._container
@deprecated('[3.10] use opcls.get_instance(cnx, **opkwargs).add_data(value)')
def set_operation(cnx, datakey, value, opcls, containercls=set, **opkwargs):
"""Function to ease applying a single operation on a set of data, avoiding
to create as many as operation as they are individual modification. You
should try to use this instead of creating on operation for each `value`,
since handling operations becomes coslty on massive data import.
Arguments are:
* `cnx`, the current connection
* `datakey`, a specially forged key that will be used as key in
cnx.transaction_data
* `value` that is the actual payload of an individual operation
* `opcls`, the class of the operation. An instance is created on the first
call for the given key, and then subsequent calls will simply add the
payload to the container (hence `opkwargs` is only used on that first
call)
* `containercls`, the container class that should be instantiated to hold
payloads. An instance is created on the first call for the given key, and
then subsequent calls will add the data to the existing container. Default
to a set. Give `list` if you want to keep arrival ordering.
* more optional parameters to give to the operation (here the rtype which do not
vary accross operations).
The body of the operation must then iterate over the values that have been mapped
in the transaction_data dictionary to the forged key, e.g.:
.. sourcecode:: python
for value in self._cw.transaction_data.pop(datakey):
...
.. Note::
**poping** the key from `transaction_data` is not an option, else you may
get unexpected data loss in some case of nested hooks.
"""
try:
# Search for cnx.transaction_data[`datakey`] (expected to be a set):
# if found, simply append `value`
_container_add(cnx.transaction_data[datakey], value)
except KeyError:
# else, initialize it to containercls([`value`]) and instantiate the given
# `opcls` operation class with additional keyword arguments
opcls(cnx, **opkwargs)
cnx.transaction_data[datakey] = containercls()
_container_add(cnx.transaction_data[datakey], value)
class LateOperation(Operation):
"""special operation which should be called after all possible (ie non late)
......
......@@ -290,12 +290,6 @@ class View(AppObject):
clabel = vtitle
return u'%s (%s)' % (clabel, self._cw.property_value('ui.site-title'))
@deprecated('[3.10] use vreg["etypes"].etype_class(etype).cw_create_url(req)')
def create_url(self, etype, **kwargs):
""" return the url of the entity creation form for a given entity type"""
return self._cw.vreg["etypes"].etype_class(etype).cw_create_url(
self._cw, **kwargs)
def field(self, label, value, row=True, show_label=True, w=None, tr=True,
table=False):
"""read-only field"""
......@@ -505,10 +499,6 @@ class ReloadableMixIn(object):
def domid(self):
return domid(self.__regid__)
@deprecated('[3.10] use .domid property')
def div_id(self):
return self.domid
class Component(ReloadableMixIn, View):
"""base class for components"""
......@@ -526,10 +516,6 @@ class Component(ReloadableMixIn, View):
def domid(self):
return '%sComponent' % domid(self.__regid__)
@deprecated('[3.10] use .cssclass property')
def div_class(self):
return self.cssclass
class Adapter(AppObject):
"""base class for adapters"""
......
......@@ -270,7 +270,7 @@ class LayoutableMixIn(object):
layout_id = None # to be defined in concret class
layout_args = {}
def layout_render(self, w):
def layout_render(self, w, **kwargs):
getlayout = self._cw.vreg['components'].select
layout = getlayout(self.layout_id, self._cw, **self.layout_select_args())
layout.render(w)
......@@ -331,19 +331,8 @@ class CtxComponent(LayoutableMixIn, AppObject):
title = None
layout_id = 'component_layout'
# XXX support kwargs for compat with old boxes which gets the view as
# argument
def render(self, w, **kwargs):
if hasattr(self, 'call'):
warn('[3.10] should not anymore implement call on %s, see new CtxComponent api'
% self.__class__, DeprecationWarning)
self.w = w
def wview(__vid, rset=None, __fallback_vid=None, **kwargs):
self._cw.view(__vid, rset, __fallback_vid, w=self.w, **kwargs)
self.wview = wview
self.call(**kwargs) # pylint: disable=E1101
return
self.layout_render(w)
self.layout_render(w, **kwargs)
def layout_select_args(self):
args = super(CtxComponent, self).layout_select_args()
......@@ -410,19 +399,6 @@ class CtxComponent(LayoutableMixIn, AppObject):
def separator(self):
return Separator()
@deprecated('[3.10] use action_link() / link()')
def box_action(self, action): # XXX action_link
return self.build_link(self._cw._(action.title), action.url())
@deprecated('[3.10] use action_link() / link()')
def build_link(self, title, url, **kwargs):
if self._cw.selected(url):
try:
kwargs['klass'] += ' selected'
except KeyError:
kwargs['klass'] = 'selected'
return tags.a(title, href=url, **kwargs)
class EntityCtxComponent(CtxComponent):
"""base class for boxes related to a single entity"""
......@@ -725,30 +701,3 @@ class EntityVComponent(Component):
def entity_call(self, entity, view=None):
raise NotImplementedError()
class RelatedObjectsVComponent(EntityVComponent):
"""a section to display some related entities"""
__select__ = EntityVComponent.__select__ & partial_has_related_entities()
vid = 'list'
# to be defined in concrete classes
rtype = title = None
def rql(self):
"""override this method if you want to use a custom rql query"""
return None
def cell_call(self, row, col, view=None):
rql = self.rql()
if rql is None:
entity = self.cw_rset.get_entity(row, col)
rset = entity.related(self.rtype, role(self))
else:
eid = self.cw_rset[row][col]
rset = self._cw.execute(self.rql(), {'x': eid})
if not rset.rowcount:
return
self.w(u'<div class="%s">' % self.cssclass)
self.w(u'<h4>%s</h4>\n' % self._cw._(self.title).capitalize())
self.wview(self.vid, rset)
self.w(u'</div>')
......@@ -349,13 +349,7 @@ class Field(object):
def initial_typed_value(self, form, load_bytes):
if self.value is not _MARKER:
if callable(self.value):
# pylint: disable=E1102
if support_args(self.value, 'form', 'field'):
return self.value(form, self)
else:
warn("[3.10] field's value callback must now take form and "
"field as argument (%s)" % self, DeprecationWarning)
return self.value(form)
return self.value(form, self)
return self.value
formattr = '%s_%s_default' % (self.role, self.name)
if self.eidparam and self.role is not None:
......
......@@ -439,10 +439,6 @@ class _CubicWebRequestBase(RequestSessionBase):
"""
self.add_js('cubicweb.ajax.js')
jsfunc = kwargs.pop('jsfunc', 'userCallbackThenReloadPage')
if 'msg' in kwargs:
warn('[3.10] msg should be given as positional argument',
DeprecationWarning, stacklevel=2)
args = (kwargs.pop('msg'),) + args
assert not kwargs, 'dunno what to do with remaining kwargs: %s' % kwargs
cbname = self.register_onetime_callback(cb, *cbargs)
return "javascript: %s" % getattr(js, jsfunc)(cbname, *args)
......
......@@ -104,7 +104,9 @@ class EntityFieldsFormTC(CubicWebTC):
req.form['__linkto'] = 'in_group:%s:subject' % geid
form = self.vreg['forms'].select('edition', req, entity=e)
form.content_type = 'text/html'
pageinfo = self._check_html(form.render(), form, template=None)
data = []
form.render(w=data.append)
pageinfo = self._check_html(u'\n'.join(data), form, template=None)
inputs = pageinfo.find_tag('select', False)
ok = False
for selectnode in pageinfo.matching_nodes('select', name='from_in_group-subject:A'):
......@@ -133,14 +135,18 @@ class EntityFieldsFormTC(CubicWebTC):
creation_date = DateTimeField(widget=DateTimePicker)
form = CustomChangeStateForm(req, redirect_path='perdu.com',
entity=req.user)
form.render(formvalues=dict(state=123, trcomment=u'',
data = []
form.render(w=data.append,
formvalues=dict(state=123, trcomment=u'',
trcomment_format=u'text/plain'))
def test_change_state_form(self):
with self.admin_access.web_request() as req:
form = ChangeStateForm(req, redirect_path='perdu.com',
entity=req.user)
form.render(formvalues=dict(state=123, trcomment=u'',
data = []
form.render(w=data.append,
formvalues=dict(state=123, trcomment=u'',
trcomment_format=u'text/plain'))
# fields tests ############################################################
......
# copyright 2003-2012 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
# copyright 2003-2014 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
#
# This file is part of CubicWeb.
......@@ -142,12 +142,7 @@ class FormRenderer(AppObject):
help = []
descr = field.help
if callable(descr):
if support_args(descr, 'form', 'field'):
descr = descr(form, field)
else:
warn("[3.10] field's help callback must now take form and field as argument (%s)"
% field, DeprecationWarning)
descr = descr(form)
descr = descr(form, field)
if descr:
help.append('<div class="helper">%s</div>' % self._cw._(descr))
example = field.example_format(self._cw)
......
......@@ -197,24 +197,10 @@ class FieldsForm(form.Form):
Extra keyword arguments will be given to renderer's :meth:`render` method.
"""
w = kwargs.pop('w', None)
if w is None:
warn('[3.10] you should specify "w" to form.render() named arguments',
DeprecationWarning, stacklevel=2)
data = []
w = data.append
else:
data = None
self.build_context(formvalues)
if renderer is None:
renderer = self.default_renderer()
if support_args(renderer.render, 'w'):
renderer.render(w, self, kwargs)
else:
warn('[3.10] you should add "w" as first argument o %s.render()'
% renderer.__class__, DeprecationWarning)
w(renderer.render(self, kwargs))
if data is not None:
return '\n'.join(data)
renderer.render(w, self, kwargs)
def default_renderer(self):
return self._cw.vreg['formrenderers'].select(
......
# copyright 2003-2011 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
# copyright 2003-2014 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
#
# This file is part of CubicWeb.
......@@ -64,16 +64,9 @@ class IBreadCrumbsAdapter(EntityAdapter):
"""
parent = self.parent_entity()
if parent is not None:
if recurs is True:
_recurs = set()
warn('[3.10] recurs argument should be a set() or None',
DeprecationWarning, stacklevel=2)
elif recurs:
if recurs:
_recurs = recurs
else:
if recurs is False:
warn('[3.10] recurs argument should be a set() or None',
DeprecationWarning, stacklevel=2)
_recurs = set()
if _recurs and parent.eid in _recurs:
self.error('cycle in breadcrumbs for entity %s' % self.entity)
......
# copyright 2003-2012 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
# copyright 2003-2014 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
#
# This file is part of CubicWeb.
......@@ -34,23 +34,6 @@ from cubicweb.web import component, httpcache
from cubicweb.web.views import primary, baseviews
@deprecated('[3.10] use a custom IDownloadable adapter instead')
def download_box(w, entity, title=None, label=None, footer=u''):
req = entity._cw
w(u'<div class="sideBox">')
if title is None:
title = req._('download')
w(u'<div class="sideBoxTitle downloadBoxTitle"><span>%s</span></div>'
% xml_escape(title))
w(u'<div class="sideBox downloadBox"><div class="sideBoxBody">')
w(u'<a href="%s"><img src="%s" alt="%s"/> %s</a>'
% (xml_escape(entity.cw_adapt_to('IDownloadable').download_url()),
req.uiprops['DOWNLOAD_ICON'],
req._('download icon'), xml_escape(label or entity.dc_title())))
w(u'%s</div>' % footer)
w(u'</div></div>\n')
class DownloadBox(component.EntityCtxComponent):
"""add download box"""
__regid__ = 'download_box' # no download box for images
......@@ -175,10 +158,6 @@ class IDownloadableOneLineView(baseviews.OneLineView):
self.w(u'<a href="%s">%s</a> [<a href="%s">%s</a>]' %
(url, name, durl, self._cw._('download')))
IDownloadableLineView = class_renamed(
'IDownloadableLineView', IDownloadableOneLineView,
'[3.10] IDownloadableLineView is deprecated, use IDownloadableOneLineView')
class AbstractEmbeddedView(EntityView):
__abstract__ = True
......
# copyright 2003-2012 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
# copyright 2003-2014 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
#
# This file is part of CubicWeb.
......@@ -131,16 +131,7 @@ class PrimaryView(EntityView):
boxes = None
if boxes or hasattr(self, 'render_side_related'):
self.w(u'<table width="100%"><tr><td style="width: 75%">')
if hasattr(self, 'render_entity_summary'):
warn('[3.10] render_entity_summary method is deprecated (%s)' % self,
DeprecationWarning)
self.render_entity_summary(entity) # pylint: disable=E1101
summary = self.summary(entity)
if summary:
warn('[3.10] summary method is deprecated (%s)' % self,
DeprecationWarning)
self.w(u'<div class="summary">%s</div>' % summary)
self.w(u'<div class="mainInfo">')
self.content_navigation_components('navcontenttop')
self.render_entity_attributes(entity)
......@@ -189,10 +180,6 @@ class PrimaryView(EntityView):
def render_entity_toolbox(self, entity):
self.content_navigation_components('ctxtoolbar')
def summary(self, entity):
"""default implementation return an empty string"""
return u''
def render_entity_attributes(self, entity):
"""Renders all attributes and relations in the 'attributes' section.
"""
......@@ -263,23 +250,10 @@ class PrimaryView(EntityView):
explicit box appobjects selectable in this context.
"""
for box in boxes:
if isinstance(box, tuple):
try:
label, rset, vid, dispctrl = box
except ValueError:
label, rset, vid = box
dispctrl = {}
warn('[3.10] box views should now be a RsetBox instance, '
'please update %s' % self.__class__.__name__,
DeprecationWarning)
self.w(u'<div class="sideBox">')
self.wview(vid, rset, title=label, initargs={'dispctrl': dispctrl})
self.w(u'</div>')
else:
try:
box.render(w=self.w, row=self.cw_row)
except TypeError:
box.render(w=self.w)
try:
box.render(w=self.w, row=self.cw_row)
except TypeError:
box.render(w=self.w)
def _prepare_side_boxes(self, entity):
sideboxes = []
......
# copyright 2003-2011 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
# copyright 2003-2014 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
#
# This file is part of CubicWeb.
......@@ -169,14 +169,7 @@ class WFHistoryVComponent(component.EntityCtxComponent):
title = _('Workflow history')
def render_body(self, w):
if hasattr(self, 'cell_call'):
warn('[3.10] %s should now implement render_body instead of cell_call'
% self.__class__, DeprecationWarning)
self.w = w
# pylint: disable=E1101
self.cell_call(self.entity.cw_row, self.entity.cw_col)
else:
self.entity.view('wfhistory', w=w, title=None)
self.entity.view('wfhistory', w=w, title=None)
class InContextWithStateView(EntityView):
......
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