We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Issues with popup on py3
When running the following code in py3 on windows I get the following error:

``` py
from kivy.uix.widget import Widget
from kivy.uix.popup import Popup

w1 = Widget()
w2 = Widget()
p1 = Popup(content=w1)
p2 = Popup(content=w2)
```

```
 Traceback (most recent call last):
   File "playground8.py", line 7, in <module>
     p2 = Popup(content=w2)
   File "C:\Users\Matthew Einhorn\Desktop\Kivy-1.8.0-py3.3-win32\kivy\kivy\uix\modalview.py", line 152, in __init__
     super(ModalView, self).__init__(**kwargs)
   File "C:\Users\Matthew Einhorn\Desktop\Kivy-1.8.0-py3.3-win32\kivy\kivy\uix\anchorlayout.py", line 68, in __init__
     super(AnchorLayout, self).__init__(**kwargs)
   File "C:\Users\Matthew Einhorn\Desktop\Kivy-1.8.0-py3.3-win32\kivy\kivy\uix\layout.py", line 66, in __init__
     super(Layout, self).__init__(**kwargs)
   File "C:\Users\Matthew Einhorn\Desktop\Kivy-1.8.0-py3.3-win32\kivy\kivy\uix\widget.py", line 261, in __init__
     super(Widget, self).__init__(**kwargs)
   File "kivy\_event.pyx", line 271, in kivy._event.EventDispatcher.__init__ (kivy\_event.c:4933)
   File "kivy\properties.pyx", line 397, in kivy.properties.Property.__set__ (kivy\properties.c:4680)
   File "kivy\properties.pyx", line 429, in kivy.properties.Property.set (kivy\properties.c:5203)
   File "kivy\properties.pyx", line 480, in kivy.properties.Property.dispatch (kivy\properties.c:5779)
   File "kivy\_event.pyx", line 1168, in kivy._event.EventObservers.dispatch (kivy\_event.c:12154)
   File "kivy\_event.pyx", line 1074, in kivy._event.EventObservers._dispatch (kivy\_event.c:11451)
   File "C:\Users\Matthew Einhorn\Desktop\Kivy-1.8.0-py3.3-win32\kivy\kivy\uix\popup.py", line 188, in on_content
     if not hasattr(value, 'popup'):
   File "kivy\properties.pyx", line 402, in kivy.properties.Property.__get__ (kivy\properties.c:4776)
   File "kivy\properties.pyx", line 435, in kivy.properties.Property.get (kivy\properties.c:5416)
 KeyError: 'popup'
```

The reason is because of https://github.com/kivy/kivy/blob/master/kivy/uix/popup.py#L188. Both Widgets are created first. Then upon creation of first Popup its `on_content` is executed and a property in that widget as well in Widget class is created. However, it's only initialized for w1, w2 `__storage` has not been initialized for w2. So when hasattr is called on widget 2 and in python 3 it causes obj.__storage['popup']` to be executed from get, because storage has not been initialized for 'popup' in this widget it crashes.

The question is, why does the Popup code do this `create_property` stuff?


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `kivy/uix/popup.py`
Content:
```
1 '''
2 Popup
3 =====
4 
5 .. versionadded:: 1.0.7
6 
7 .. image:: images/popup.jpg
8     :align: right
9 
10 The :class:`Popup` widget is used to create modal popups. By default, the popup
11 will cover the whole "parent" window. When you are creating a popup, you
12 must at least set a :attr:`Popup.title` and :attr:`Popup.content`.
13 
14 Remember that the default size of a Widget is size_hint=(1, 1). If you don't
15 want your popup to be fullscreen, either use size hints with values less than 1
16 (for instance size_hint=(.8, .8)) or deactivate the size_hint and use
17 fixed size attributes.
18 
19 
20 .. versionchanged:: 1.4.0
21     The :class:`Popup` class now inherits from
22     :class:`~kivy.uix.modalview.ModalView`. The :class:`Popup` offers a default
23     layout with a title and a separation bar.
24 
25 Examples
26 --------
27 
28 Example of a simple 400x400 Hello world popup::
29 
30     popup = Popup(title='Test popup',
31         content=Label(text='Hello world'),
32         size_hint=(None, None), size=(400, 400))
33 
34 By default, any click outside the popup will dismiss/close it. If you don't
35 want that, you can set
36 :attr:`~kivy.uix.modalview.ModalView.auto_dismiss` to False::
37 
38     popup = Popup(title='Test popup', content=Label(text='Hello world'),
39                   auto_dismiss=False)
40     popup.open()
41 
42 To manually dismiss/close the popup, use
43 :attr:`~kivy.uix.modalview.ModalView.dismiss`::
44 
45     popup.dismiss()
46 
47 Both :meth:`~kivy.uix.modalview.ModalView.open` and
48 :meth:`~kivy.uix.modalview.ModalView.dismiss` are bindable. That means you
49 can directly bind the function to an action, e.g. to a button's on_press::
50 
51     # create content and add to the popup
52     content = Button(text='Close me!')
53     popup = Popup(content=content, auto_dismiss=False)
54 
55     # bind the on_press event of the button to the dismiss function
56     content.bind(on_press=popup.dismiss)
57 
58     # open the popup
59     popup.open()
60 
61 
62 Popup Events
63 ------------
64 
65 There are two events available: `on_open` which is raised when the popup is
66 opening, and `on_dismiss` which is raised when the popup is closed.
67 For `on_dismiss`, you can prevent the
68 popup from closing by explictly returning True from your callback::
69 
70     def my_callback(instance):
71         print('Popup', instance, 'is being dismissed but is prevented!')
72         return True
73     popup = Popup(content=Label(text='Hello world'))
74     popup.bind(on_dismiss=my_callback)
75     popup.open()
76 
77 '''
78 
79 __all__ = ('Popup', 'PopupException')
80 
81 from kivy.uix.modalview import ModalView
82 from kivy.properties import (StringProperty, ObjectProperty, OptionProperty,
83                              NumericProperty, ListProperty)
84 
85 
86 class PopupException(Exception):
87     '''Popup exception, fired when multiple content widgets are added to the
88     popup.
89 
90     .. versionadded:: 1.4.0
91     '''
92 
93 
94 class Popup(ModalView):
95     '''Popup class. See module documentation for more information.
96 
97     :Events:
98         `on_open`:
99             Fired when the Popup is opened.
100         `on_dismiss`:
101             Fired when the Popup is closed. If the callback returns True, the
102             dismiss will be canceled.
103     '''
104 
105     title = StringProperty('No title')
106     '''String that represents the title of the popup.
107 
108     :attr:`title` is a :class:`~kivy.properties.StringProperty` and defaults to
109     'No title'.
110     '''
111 
112     title_size = NumericProperty('14sp')
113     '''Represents the font size of the popup title.
114 
115     .. versionadded:: 1.6.0
116 
117     :attr:`title_size` is a :class:`~kivy.properties.NumericProperty` and
118     defaults to '14sp'.
119     '''
120 
121     title_align = OptionProperty('left',
122                                  options=['left', 'center', 'right', 'justify'])
123     '''Horizontal alignment of the title.
124 
125     .. versionadded:: 1.9.0
126 
127     :attr:`title_align` is a :class:`~kivy.properties.OptionProperty` and
128     defaults to 'left'. Available options are left, middle, right and justify.
129     '''
130 
131     title_font = StringProperty('DroidSans')
132     '''Font used to render the title text.
133 
134     .. versionadded:: 1.9.0
135 
136     :attr:`title_font` is a :class:`~kivy.properties.StringProperty` and
137     defaults to 'DroidSans'.
138     '''
139 
140     content = ObjectProperty(None)
141     '''Content of the popup that is displayed just under the title.
142 
143     :attr:`content` is an :class:`~kivy.properties.ObjectProperty` and defaults
144     to None.
145     '''
146 
147     title_color = ListProperty([1, 1, 1, 1])
148     '''Color used by the Title.
149 
150     .. versionadded:: 1.8.0
151 
152     :attr:`title_color` is a :class:`~kivy.properties.ListProperty` and
153     defaults to [1, 1, 1, 1].
154     '''
155 
156     separator_color = ListProperty([47 / 255., 167 / 255., 212 / 255., 1.])
157     '''Color used by the separator between title and content.
158 
159     .. versionadded:: 1.1.0
160 
161     :attr:`separator_color` is a :class:`~kivy.properties.ListProperty` and
162     defaults to [47 / 255., 167 / 255., 212 / 255., 1.]
163     '''
164 
165     separator_height = NumericProperty('2dp')
166     '''Height of the separator.
167 
168     .. versionadded:: 1.1.0
169 
170     :attr:`separator_height` is a :class:`~kivy.properties.NumericProperty` and
171     defaults to 2dp.
172     '''
173 
174     # Internal properties used for graphical representation.
175 
176     _container = ObjectProperty(None)
177 
178     def add_widget(self, widget):
179         if self._container:
180             if self.content:
181                 raise PopupException(
182                     'Popup can have only one widget as content')
183             self.content = widget
184         else:
185             super(Popup, self).add_widget(widget)
186 
187     def on_content(self, instance, value):
188         if not hasattr(value, 'popup'):
189             value.create_property('popup')
190         value.popup = self
191         if self._container:
192             self._container.clear_widgets()
193             self._container.add_widget(value)
194 
195     def on__container(self, instance, value):
196         if value is None or self.content is None:
197             return
198         self._container.clear_widgets()
199         self._container.add_widget(self.content)
200 
201     def on_touch_down(self, touch):
202         if self.disabled and self.collide_point(*touch.pos):
203             return True
204         return super(Popup, self).on_touch_down(touch)
205 
206 
207 if __name__ == '__main__':
208     from kivy.base import runTouchApp
209     from kivy.uix.button import Button
210     from kivy.uix.label import Label
211     from kivy.uix.gridlayout import GridLayout
212     from kivy.core.window import Window
213 
214     # add popup
215     content = GridLayout(cols=1)
216     content_cancel = Button(text='Cancel', size_hint_y=None, height=40)
217     content.add_widget(Label(text='This is a hello world'))
218     content.add_widget(content_cancel)
219     popup = Popup(title='Test popup',
220                   size_hint=(None, None), size=(256, 256),
221                   content=content, disabled=True)
222     content_cancel.bind(on_release=popup.dismiss)
223 
224     layout = GridLayout(cols=3)
225     for x in range(9):
226         btn = Button(text=str(x))
227         btn.bind(on_release=popup.open)
228         layout.add_widget(btn)
229 
230     Window.add_widget(layout)
231 
232     popup.open()
233 
234     runTouchApp()
235
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/kivy/uix/popup.py b/kivy/uix/popup.py
--- a/kivy/uix/popup.py
+++ b/kivy/uix/popup.py
@@ -185,9 +185,6 @@
             super(Popup, self).add_widget(widget)
 
     def on_content(self, instance, value):
-        if not hasattr(value, 'popup'):
-            value.create_property('popup')
-        value.popup = self
         if self._container:
             self._container.clear_widgets()
             self._container.add_widget(value)

{"golden_diff": "diff --git a/kivy/uix/popup.py b/kivy/uix/popup.py\n--- a/kivy/uix/popup.py\n+++ b/kivy/uix/popup.py\n@@ -185,9 +185,6 @@\n             super(Popup, self).add_widget(widget)\n \n     def on_content(self, instance, value):\n-        if not hasattr(value, 'popup'):\n-            value.create_property('popup')\n-        value.popup = self\n         if self._container:\n             self._container.clear_widgets()\n             self._container.add_widget(value)\n", "issue": "Issues with popup on py3\nWhen running the following code in py3 on windows I get the following error:\n\n``` py\nfrom kivy.uix.widget import Widget\nfrom kivy.uix.popup import Popup\n\nw1 = Widget()\nw2 = Widget()\np1 = Popup(content=w1)\np2 = Popup(content=w2)\n```\n\n```\n Traceback (most recent call last):\n   File \"playground8.py\", line 7, in <module>\n     p2 = Popup(content=w2)\n   File \"C:\\Users\\Matthew Einhorn\\Desktop\\Kivy-1.8.0-py3.3-win32\\kivy\\kivy\\uix\\modalview.py\", line 152, in __init__\n     super(ModalView, self).__init__(**kwargs)\n   File \"C:\\Users\\Matthew Einhorn\\Desktop\\Kivy-1.8.0-py3.3-win32\\kivy\\kivy\\uix\\anchorlayout.py\", line 68, in __init__\n     super(AnchorLayout, self).__init__(**kwargs)\n   File \"C:\\Users\\Matthew Einhorn\\Desktop\\Kivy-1.8.0-py3.3-win32\\kivy\\kivy\\uix\\layout.py\", line 66, in __init__\n     super(Layout, self).__init__(**kwargs)\n   File \"C:\\Users\\Matthew Einhorn\\Desktop\\Kivy-1.8.0-py3.3-win32\\kivy\\kivy\\uix\\widget.py\", line 261, in __init__\n     super(Widget, self).__init__(**kwargs)\n   File \"kivy\\_event.pyx\", line 271, in kivy._event.EventDispatcher.__init__ (kivy\\_event.c:4933)\n   File \"kivy\\properties.pyx\", line 397, in kivy.properties.Property.__set__ (kivy\\properties.c:4680)\n   File \"kivy\\properties.pyx\", line 429, in kivy.properties.Property.set (kivy\\properties.c:5203)\n   File \"kivy\\properties.pyx\", line 480, in kivy.properties.Property.dispatch (kivy\\properties.c:5779)\n   File \"kivy\\_event.pyx\", line 1168, in kivy._event.EventObservers.dispatch (kivy\\_event.c:12154)\n   File \"kivy\\_event.pyx\", line 1074, in kivy._event.EventObservers._dispatch (kivy\\_event.c:11451)\n   File \"C:\\Users\\Matthew Einhorn\\Desktop\\Kivy-1.8.0-py3.3-win32\\kivy\\kivy\\uix\\popup.py\", line 188, in on_content\n     if not hasattr(value, 'popup'):\n   File \"kivy\\properties.pyx\", line 402, in kivy.properties.Property.__get__ (kivy\\properties.c:4776)\n   File \"kivy\\properties.pyx\", line 435, in kivy.properties.Property.get (kivy\\properties.c:5416)\n KeyError: 'popup'\n```\n\nThe reason is because of https://github.com/kivy/kivy/blob/master/kivy/uix/popup.py#L188. Both Widgets are created first. Then upon creation of first Popup its `on_content` is executed and a property in that widget as well in Widget class is created. However, it's only initialized for w1, w2 `__storage` has not been initialized for w2. So when hasattr is called on widget 2 and in python 3 it causes obj.__storage['popup']` to be executed from get, because storage has not been initialized for 'popup' in this widget it crashes.\n\nThe question is, why does the Popup code do this `create_property` stuff?\n\n", "before_files": [{"content": "'''\nPopup\n=====\n\n.. versionadded:: 1.0.7\n\n.. image:: images/popup.jpg\n    :align: right\n\nThe :class:`Popup` widget is used to create modal popups. By default, the popup\nwill cover the whole \"parent\" window. When you are creating a popup, you\nmust at least set a :attr:`Popup.title` and :attr:`Popup.content`.\n\nRemember that the default size of a Widget is size_hint=(1, 1). If you don't\nwant your popup to be fullscreen, either use size hints with values less than 1\n(for instance size_hint=(.8, .8)) or deactivate the size_hint and use\nfixed size attributes.\n\n\n.. versionchanged:: 1.4.0\n    The :class:`Popup` class now inherits from\n    :class:`~kivy.uix.modalview.ModalView`. The :class:`Popup` offers a default\n    layout with a title and a separation bar.\n\nExamples\n--------\n\nExample of a simple 400x400 Hello world popup::\n\n    popup = Popup(title='Test popup',\n        content=Label(text='Hello world'),\n        size_hint=(None, None), size=(400, 400))\n\nBy default, any click outside the popup will dismiss/close it. If you don't\nwant that, you can set\n:attr:`~kivy.uix.modalview.ModalView.auto_dismiss` to False::\n\n    popup = Popup(title='Test popup', content=Label(text='Hello world'),\n                  auto_dismiss=False)\n    popup.open()\n\nTo manually dismiss/close the popup, use\n:attr:`~kivy.uix.modalview.ModalView.dismiss`::\n\n    popup.dismiss()\n\nBoth :meth:`~kivy.uix.modalview.ModalView.open` and\n:meth:`~kivy.uix.modalview.ModalView.dismiss` are bindable. That means you\ncan directly bind the function to an action, e.g. to a button's on_press::\n\n    # create content and add to the popup\n    content = Button(text='Close me!')\n    popup = Popup(content=content, auto_dismiss=False)\n\n    # bind the on_press event of the button to the dismiss function\n    content.bind(on_press=popup.dismiss)\n\n    # open the popup\n    popup.open()\n\n\nPopup Events\n------------\n\nThere are two events available: `on_open` which is raised when the popup is\nopening, and `on_dismiss` which is raised when the popup is closed.\nFor `on_dismiss`, you can prevent the\npopup from closing by explictly returning True from your callback::\n\n    def my_callback(instance):\n        print('Popup', instance, 'is being dismissed but is prevented!')\n        return True\n    popup = Popup(content=Label(text='Hello world'))\n    popup.bind(on_dismiss=my_callback)\n    popup.open()\n\n'''\n\n__all__ = ('Popup', 'PopupException')\n\nfrom kivy.uix.modalview import ModalView\nfrom kivy.properties import (StringProperty, ObjectProperty, OptionProperty,\n                             NumericProperty, ListProperty)\n\n\nclass PopupException(Exception):\n    '''Popup exception, fired when multiple content widgets are added to the\n    popup.\n\n    .. versionadded:: 1.4.0\n    '''\n\n\nclass Popup(ModalView):\n    '''Popup class. See module documentation for more information.\n\n    :Events:\n        `on_open`:\n            Fired when the Popup is opened.\n        `on_dismiss`:\n            Fired when the Popup is closed. If the callback returns True, the\n            dismiss will be canceled.\n    '''\n\n    title = StringProperty('No title')\n    '''String that represents the title of the popup.\n\n    :attr:`title` is a :class:`~kivy.properties.StringProperty` and defaults to\n    'No title'.\n    '''\n\n    title_size = NumericProperty('14sp')\n    '''Represents the font size of the popup title.\n\n    .. versionadded:: 1.6.0\n\n    :attr:`title_size` is a :class:`~kivy.properties.NumericProperty` and\n    defaults to '14sp'.\n    '''\n\n    title_align = OptionProperty('left',\n                                 options=['left', 'center', 'right', 'justify'])\n    '''Horizontal alignment of the title.\n\n    .. versionadded:: 1.9.0\n\n    :attr:`title_align` is a :class:`~kivy.properties.OptionProperty` and\n    defaults to 'left'. Available options are left, middle, right and justify.\n    '''\n\n    title_font = StringProperty('DroidSans')\n    '''Font used to render the title text.\n\n    .. versionadded:: 1.9.0\n\n    :attr:`title_font` is a :class:`~kivy.properties.StringProperty` and\n    defaults to 'DroidSans'.\n    '''\n\n    content = ObjectProperty(None)\n    '''Content of the popup that is displayed just under the title.\n\n    :attr:`content` is an :class:`~kivy.properties.ObjectProperty` and defaults\n    to None.\n    '''\n\n    title_color = ListProperty([1, 1, 1, 1])\n    '''Color used by the Title.\n\n    .. versionadded:: 1.8.0\n\n    :attr:`title_color` is a :class:`~kivy.properties.ListProperty` and\n    defaults to [1, 1, 1, 1].\n    '''\n\n    separator_color = ListProperty([47 / 255., 167 / 255., 212 / 255., 1.])\n    '''Color used by the separator between title and content.\n\n    .. versionadded:: 1.1.0\n\n    :attr:`separator_color` is a :class:`~kivy.properties.ListProperty` and\n    defaults to [47 / 255., 167 / 255., 212 / 255., 1.]\n    '''\n\n    separator_height = NumericProperty('2dp')\n    '''Height of the separator.\n\n    .. versionadded:: 1.1.0\n\n    :attr:`separator_height` is a :class:`~kivy.properties.NumericProperty` and\n    defaults to 2dp.\n    '''\n\n    # Internal properties used for graphical representation.\n\n    _container = ObjectProperty(None)\n\n    def add_widget(self, widget):\n        if self._container:\n            if self.content:\n                raise PopupException(\n                    'Popup can have only one widget as content')\n            self.content = widget\n        else:\n            super(Popup, self).add_widget(widget)\n\n    def on_content(self, instance, value):\n        if not hasattr(value, 'popup'):\n            value.create_property('popup')\n        value.popup = self\n        if self._container:\n            self._container.clear_widgets()\n            self._container.add_widget(value)\n\n    def on__container(self, instance, value):\n        if value is None or self.content is None:\n            return\n        self._container.clear_widgets()\n        self._container.add_widget(self.content)\n\n    def on_touch_down(self, touch):\n        if self.disabled and self.collide_point(*touch.pos):\n            return True\n        return super(Popup, self).on_touch_down(touch)\n\n\nif __name__ == '__main__':\n    from kivy.base import runTouchApp\n    from kivy.uix.button import Button\n    from kivy.uix.label import Label\n    from kivy.uix.gridlayout import GridLayout\n    from kivy.core.window import Window\n\n    # add popup\n    content = GridLayout(cols=1)\n    content_cancel = Button(text='Cancel', size_hint_y=None, height=40)\n    content.add_widget(Label(text='This is a hello world'))\n    content.add_widget(content_cancel)\n    popup = Popup(title='Test popup',\n                  size_hint=(None, None), size=(256, 256),\n                  content=content, disabled=True)\n    content_cancel.bind(on_release=popup.dismiss)\n\n    layout = GridLayout(cols=3)\n    for x in range(9):\n        btn = Button(text=str(x))\n        btn.bind(on_release=popup.open)\n        layout.add_widget(btn)\n\n    Window.add_widget(layout)\n\n    popup.open()\n\n    runTouchApp()\n", "path": "kivy/uix/popup.py"}], "after_files": [{"content": "'''\nPopup\n=====\n\n.. versionadded:: 1.0.7\n\n.. image:: images/popup.jpg\n    :align: right\n\nThe :class:`Popup` widget is used to create modal popups. By default, the popup\nwill cover the whole \"parent\" window. When you are creating a popup, you\nmust at least set a :attr:`Popup.title` and :attr:`Popup.content`.\n\nRemember that the default size of a Widget is size_hint=(1, 1). If you don't\nwant your popup to be fullscreen, either use size hints with values less than 1\n(for instance size_hint=(.8, .8)) or deactivate the size_hint and use\nfixed size attributes.\n\n\n.. versionchanged:: 1.4.0\n    The :class:`Popup` class now inherits from\n    :class:`~kivy.uix.modalview.ModalView`. The :class:`Popup` offers a default\n    layout with a title and a separation bar.\n\nExamples\n--------\n\nExample of a simple 400x400 Hello world popup::\n\n    popup = Popup(title='Test popup',\n        content=Label(text='Hello world'),\n        size_hint=(None, None), size=(400, 400))\n\nBy default, any click outside the popup will dismiss/close it. If you don't\nwant that, you can set\n:attr:`~kivy.uix.modalview.ModalView.auto_dismiss` to False::\n\n    popup = Popup(title='Test popup', content=Label(text='Hello world'),\n                  auto_dismiss=False)\n    popup.open()\n\nTo manually dismiss/close the popup, use\n:attr:`~kivy.uix.modalview.ModalView.dismiss`::\n\n    popup.dismiss()\n\nBoth :meth:`~kivy.uix.modalview.ModalView.open` and\n:meth:`~kivy.uix.modalview.ModalView.dismiss` are bindable. That means you\ncan directly bind the function to an action, e.g. to a button's on_press::\n\n    # create content and add to the popup\n    content = Button(text='Close me!')\n    popup = Popup(content=content, auto_dismiss=False)\n\n    # bind the on_press event of the button to the dismiss function\n    content.bind(on_press=popup.dismiss)\n\n    # open the popup\n    popup.open()\n\n\nPopup Events\n------------\n\nThere are two events available: `on_open` which is raised when the popup is\nopening, and `on_dismiss` which is raised when the popup is closed.\nFor `on_dismiss`, you can prevent the\npopup from closing by explictly returning True from your callback::\n\n    def my_callback(instance):\n        print('Popup', instance, 'is being dismissed but is prevented!')\n        return True\n    popup = Popup(content=Label(text='Hello world'))\n    popup.bind(on_dismiss=my_callback)\n    popup.open()\n\n'''\n\n__all__ = ('Popup', 'PopupException')\n\nfrom kivy.uix.modalview import ModalView\nfrom kivy.properties import (StringProperty, ObjectProperty, OptionProperty,\n                             NumericProperty, ListProperty)\n\n\nclass PopupException(Exception):\n    '''Popup exception, fired when multiple content widgets are added to the\n    popup.\n\n    .. versionadded:: 1.4.0\n    '''\n\n\nclass Popup(ModalView):\n    '''Popup class. See module documentation for more information.\n\n    :Events:\n        `on_open`:\n            Fired when the Popup is opened.\n        `on_dismiss`:\n            Fired when the Popup is closed. If the callback returns True, the\n            dismiss will be canceled.\n    '''\n\n    title = StringProperty('No title')\n    '''String that represents the title of the popup.\n\n    :attr:`title` is a :class:`~kivy.properties.StringProperty` and defaults to\n    'No title'.\n    '''\n\n    title_size = NumericProperty('14sp')\n    '''Represents the font size of the popup title.\n\n    .. versionadded:: 1.6.0\n\n    :attr:`title_size` is a :class:`~kivy.properties.NumericProperty` and\n    defaults to '14sp'.\n    '''\n\n    title_align = OptionProperty('left',\n                                 options=['left', 'center', 'right', 'justify'])\n    '''Horizontal alignment of the title.\n\n    .. versionadded:: 1.9.0\n\n    :attr:`title_align` is a :class:`~kivy.properties.OptionProperty` and\n    defaults to 'left'. Available options are left, middle, right and justify.\n    '''\n\n    title_font = StringProperty('DroidSans')\n    '''Font used to render the title text.\n\n    .. versionadded:: 1.9.0\n\n    :attr:`title_font` is a :class:`~kivy.properties.StringProperty` and\n    defaults to 'DroidSans'.\n    '''\n\n    content = ObjectProperty(None)\n    '''Content of the popup that is displayed just under the title.\n\n    :attr:`content` is an :class:`~kivy.properties.ObjectProperty` and defaults\n    to None.\n    '''\n\n    title_color = ListProperty([1, 1, 1, 1])\n    '''Color used by the Title.\n\n    .. versionadded:: 1.8.0\n\n    :attr:`title_color` is a :class:`~kivy.properties.ListProperty` and\n    defaults to [1, 1, 1, 1].\n    '''\n\n    separator_color = ListProperty([47 / 255., 167 / 255., 212 / 255., 1.])\n    '''Color used by the separator between title and content.\n\n    .. versionadded:: 1.1.0\n\n    :attr:`separator_color` is a :class:`~kivy.properties.ListProperty` and\n    defaults to [47 / 255., 167 / 255., 212 / 255., 1.]\n    '''\n\n    separator_height = NumericProperty('2dp')\n    '''Height of the separator.\n\n    .. versionadded:: 1.1.0\n\n    :attr:`separator_height` is a :class:`~kivy.properties.NumericProperty` and\n    defaults to 2dp.\n    '''\n\n    # Internal properties used for graphical representation.\n\n    _container = ObjectProperty(None)\n\n    def add_widget(self, widget):\n        if self._container:\n            if self.content:\n                raise PopupException(\n                    'Popup can have only one widget as content')\n            self.content = widget\n        else:\n            super(Popup, self).add_widget(widget)\n\n    def on_content(self, instance, value):\n        if self._container:\n            self._container.clear_widgets()\n            self._container.add_widget(value)\n\n    def on__container(self, instance, value):\n        if value is None or self.content is None:\n            return\n        self._container.clear_widgets()\n        self._container.add_widget(self.content)\n\n    def on_touch_down(self, touch):\n        if self.disabled and self.collide_point(*touch.pos):\n            return True\n        return super(Popup, self).on_touch_down(touch)\n\n\nif __name__ == '__main__':\n    from kivy.base import runTouchApp\n    from kivy.uix.button import Button\n    from kivy.uix.label import Label\n    from kivy.uix.gridlayout import GridLayout\n    from kivy.core.window import Window\n\n    # add popup\n    content = GridLayout(cols=1)\n    content_cancel = Button(text='Cancel', size_hint_y=None, height=40)\n    content.add_widget(Label(text='This is a hello world'))\n    content.add_widget(content_cancel)\n    popup = Popup(title='Test popup',\n                  size_hint=(None, None), size=(256, 256),\n                  content=content, disabled=True)\n    content_cancel.bind(on_release=popup.dismiss)\n\n    layout = GridLayout(cols=3)\n    for x in range(9):\n        btn = Button(text=str(x))\n        btn.bind(on_release=popup.open)\n        layout.add_widget(btn)\n\n    Window.add_widget(layout)\n\n    popup.open()\n\n    runTouchApp()\n", "path": "kivy/uix/popup.py"}]}