Skip to content

Commit

Permalink
Don't init property created in KV with given value because it is stor…
Browse files Browse the repository at this point in the history
…ed in the class causing memory leaks.
  • Loading branch information
matham committed Jul 27, 2019
1 parent e8a0914 commit 0614f11
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 16 deletions.
58 changes: 43 additions & 15 deletions kivy/_event.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -800,7 +800,7 @@ cdef class EventDispatcher(ObjectWithUid):
ret[x] = p[x]
return ret

def create_property(self, str name, value=None, *largs, **kwargs):
def create_property(self, str name, value=None, default_value=True, *largs, **kwargs):
'''Create a new property at runtime.
.. versionadded:: 1.0.9
Expand All @@ -817,6 +817,10 @@ cdef class EventDispatcher(ObjectWithUid):
Also, now and positional and keyword arguments are passed to the
property when created.
.. versionchanged:: 2.0.0
default_value has been added.
.. warning::
This function is designed for the Kivy language, don't use it in
Expand All @@ -829,7 +833,10 @@ cdef class EventDispatcher(ObjectWithUid):
`value`: object, optional
Default value of the property. Type is also used for creating
more appropriate property types. Defaults to None.
`default_value`: bool, True by default
If True, `value` will be the default for the property. Otherwise,
the property will be initialized with the the property type's
normal default value, and subsequently set to ``value``.
::
Expand All @@ -840,25 +847,46 @@ cdef class EventDispatcher(ObjectWithUid):
True
'''
cdef Property prop
if value is None: # shortcut
prop = ObjectProperty(None, *largs, **kwargs)
if isinstance(value, bool):
prop = BooleanProperty(value, *largs, **kwargs)
elif isinstance(value, (int, float)):
prop = NumericProperty(value, *largs, **kwargs)
elif isinstance(value, string_types):
prop = StringProperty(value, *largs, **kwargs)
elif isinstance(value, (list, tuple)):
prop = ListProperty(value, *largs, **kwargs)
elif isinstance(value, dict):
prop = DictProperty(value, *largs, **kwargs)

if default_value:
if value is None: # shortcut
prop = ObjectProperty(None, *largs, **kwargs)
if isinstance(value, bool):
prop = BooleanProperty(value, *largs, **kwargs)
elif isinstance(value, (int, float)):
prop = NumericProperty(value, *largs, **kwargs)
elif isinstance(value, string_types):
prop = StringProperty(value, *largs, **kwargs)
elif isinstance(value, (list, tuple)):
prop = ListProperty(value, *largs, **kwargs)
elif isinstance(value, dict):
prop = DictProperty(value, *largs, **kwargs)
else:
prop = ObjectProperty(value, *largs, **kwargs)
else:
prop = ObjectProperty(value, *largs, **kwargs)
if value is None: # shortcut
prop = ObjectProperty(*largs, **kwargs)
if isinstance(value, bool):
prop = BooleanProperty(*largs, **kwargs)
elif isinstance(value, (int, float)):
prop = NumericProperty(*largs, **kwargs)
elif isinstance(value, string_types):
prop = StringProperty(*largs, **kwargs)
elif isinstance(value, (list, tuple)):
prop = ListProperty(*largs, **kwargs)
elif isinstance(value, dict):
prop = DictProperty(*largs, **kwargs)
else:
prop = ObjectProperty(*largs, **kwargs)

prop.link(self, name)
prop.link_deps(self, name)
self.__properties[name] = prop
setattr(self.__class__, name, prop)

if not default_value:
setattr(self, name, value)

def apply_property(self, **kwargs):
'''Adds properties at runtime to the class. The function accepts
keyword arguments of the form `prop_name=prop`, where `prop` is a
Expand Down
2 changes: 1 addition & 1 deletion kivy/lang/parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -281,7 +281,7 @@ def create_missing(self, widget):
value = self.properties[name].co_value
if type(value) is CodeType:
value = None
widget.create_property(name, value)
widget.create_property(name, value, default_value=False)

def _forbid_selectors(self):
c = self.name[0]
Expand Down

0 comments on commit 0614f11

Please sign in to comment.