flet 1.0.0.dev0__tar.gz → 1.0.0.dev2__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (330) hide show
  1. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/PKG-INFO +9 -9
  2. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/pyproject.toml +10 -9
  3. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/controls/object_patch.py +26 -1
  4. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/utils/__init__.py +2 -0
  5. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/utils/files.py +23 -0
  6. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/version.py +1 -1
  7. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet.egg-info/PKG-INFO +9 -9
  8. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet.egg-info/SOURCES.txt +1 -0
  9. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet.egg-info/requires.txt +8 -8
  10. flet-1.0.0.dev2/tests/test_files.py +79 -0
  11. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/tests/test_object_diff_frozen.py +86 -0
  12. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/README.md +0 -0
  13. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/setup.cfg +0 -0
  14. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/__init__.py +0 -0
  15. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/app.py +0 -0
  16. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/auth/__init__.py +0 -0
  17. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/auth/authorization.py +0 -0
  18. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/auth/authorization_service.py +0 -0
  19. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/auth/group.py +0 -0
  20. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/auth/oauth_provider.py +0 -0
  21. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/auth/oauth_token.py +0 -0
  22. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/auth/providers/__init__.py +0 -0
  23. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/auth/providers/auth0_oauth_provider.py +0 -0
  24. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/auth/providers/azure_oauth_provider.py +0 -0
  25. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/auth/providers/github_oauth_provider.py +0 -0
  26. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/auth/providers/google_oauth_provider.py +0 -0
  27. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/auth/user.py +0 -0
  28. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/canvas/__init__.py +0 -0
  29. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/cli.py +0 -0
  30. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/components/__init__.py +0 -0
  31. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/components/component.py +0 -0
  32. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/components/component_decorator.py +0 -0
  33. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/components/component_owned.py +0 -0
  34. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/components/hooks/__init__.py +0 -0
  35. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/components/hooks/hook.py +0 -0
  36. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/components/hooks/use_callback.py +0 -0
  37. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/components/hooks/use_context.py +0 -0
  38. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/components/hooks/use_dialog.py +0 -0
  39. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/components/hooks/use_effect.py +0 -0
  40. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/components/hooks/use_memo.py +0 -0
  41. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/components/hooks/use_ref.py +0 -0
  42. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/components/hooks/use_state.py +0 -0
  43. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/components/memo.py +0 -0
  44. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/components/observable.py +0 -0
  45. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/components/public_utils.py +0 -0
  46. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/components/router.py +0 -0
  47. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/components/utils.py +0 -0
  48. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/controls/__init__.py +0 -0
  49. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/controls/action_control.py +0 -0
  50. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/controls/adaptive_control.py +0 -0
  51. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/controls/alignment.py +0 -0
  52. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/controls/animation.py +0 -0
  53. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/controls/base_control.py +0 -0
  54. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/controls/base_page.py +0 -0
  55. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/controls/blur.py +0 -0
  56. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/controls/border.py +0 -0
  57. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/controls/border_radius.py +0 -0
  58. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/controls/box.py +0 -0
  59. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/controls/buttons.py +0 -0
  60. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/controls/client_action.py +0 -0
  61. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/controls/colors.py +0 -0
  62. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/controls/context.py +0 -0
  63. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/controls/control.py +0 -0
  64. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/controls/control_event.py +0 -0
  65. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/controls/control_state.py +0 -0
  66. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/controls/core/__init__.py +0 -0
  67. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/controls/core/animated_switcher.py +0 -0
  68. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/controls/core/autofill_group.py +0 -0
  69. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/controls/core/canvas/__init__.py +0 -0
  70. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/controls/core/canvas/arc.py +0 -0
  71. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/controls/core/canvas/canvas.py +0 -0
  72. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/controls/core/canvas/circle.py +0 -0
  73. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/controls/core/canvas/color.py +0 -0
  74. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/controls/core/canvas/fill.py +0 -0
  75. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/controls/core/canvas/image.py +0 -0
  76. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/controls/core/canvas/line.py +0 -0
  77. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/controls/core/canvas/oval.py +0 -0
  78. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/controls/core/canvas/path.py +0 -0
  79. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/controls/core/canvas/points.py +0 -0
  80. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/controls/core/canvas/rect.py +0 -0
  81. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/controls/core/canvas/shadow.py +0 -0
  82. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/controls/core/canvas/shape.py +0 -0
  83. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/controls/core/canvas/text.py +0 -0
  84. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/controls/core/column.py +0 -0
  85. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/controls/core/dismissible.py +0 -0
  86. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/controls/core/drag_target.py +0 -0
  87. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/controls/core/draggable.py +0 -0
  88. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/controls/core/flet_app.py +0 -0
  89. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/controls/core/gesture_detector.py +0 -0
  90. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/controls/core/grid_view.py +0 -0
  91. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/controls/core/hero.py +0 -0
  92. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/controls/core/icon.py +0 -0
  93. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/controls/core/image.py +0 -0
  94. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/controls/core/interactive_viewer.py +0 -0
  95. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/controls/core/keyboard_listener.py +0 -0
  96. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/controls/core/list_view.py +0 -0
  97. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/controls/core/markdown.py +0 -0
  98. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/controls/core/merge_semantics.py +0 -0
  99. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/controls/core/page_view.py +0 -0
  100. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/controls/core/pagelet.py +0 -0
  101. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/controls/core/placeholder.py +0 -0
  102. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/controls/core/raw_image.py +0 -0
  103. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/controls/core/reorderable_drag_handle.py +0 -0
  104. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/controls/core/responsive_row.py +0 -0
  105. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/controls/core/rotated_box.py +0 -0
  106. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/controls/core/row.py +0 -0
  107. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/controls/core/safe_area.py +0 -0
  108. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/controls/core/screenshot.py +0 -0
  109. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/controls/core/semantics.py +0 -0
  110. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/controls/core/shader_mask.py +0 -0
  111. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/controls/core/shimmer.py +0 -0
  112. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/controls/core/stack.py +0 -0
  113. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/controls/core/text.py +0 -0
  114. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/controls/core/text_span.py +0 -0
  115. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/controls/core/transparent_pointer.py +0 -0
  116. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/controls/core/view.py +0 -0
  117. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/controls/core/window.py +0 -0
  118. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/controls/core/window_drag_area.py +0 -0
  119. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/controls/cupertino/__init__.py +0 -0
  120. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/controls/cupertino/cupertino_action_sheet.py +0 -0
  121. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/controls/cupertino/cupertino_action_sheet_action.py +0 -0
  122. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/controls/cupertino/cupertino_activity_indicator.py +0 -0
  123. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/controls/cupertino/cupertino_alert_dialog.py +0 -0
  124. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/controls/cupertino/cupertino_app_bar.py +0 -0
  125. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/controls/cupertino/cupertino_bottom_sheet.py +0 -0
  126. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/controls/cupertino/cupertino_button.py +0 -0
  127. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/controls/cupertino/cupertino_checkbox.py +0 -0
  128. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/controls/cupertino/cupertino_colors.py +0 -0
  129. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/controls/cupertino/cupertino_context_menu.py +0 -0
  130. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/controls/cupertino/cupertino_context_menu_action.py +0 -0
  131. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/controls/cupertino/cupertino_date_picker.py +0 -0
  132. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/controls/cupertino/cupertino_dialog_action.py +0 -0
  133. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/controls/cupertino/cupertino_filled_button.py +0 -0
  134. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/controls/cupertino/cupertino_icons.json +0 -0
  135. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/controls/cupertino/cupertino_icons.py +0 -0
  136. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/controls/cupertino/cupertino_icons.pyi +0 -0
  137. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/controls/cupertino/cupertino_list_tile.py +0 -0
  138. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/controls/cupertino/cupertino_navigation_bar.py +0 -0
  139. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/controls/cupertino/cupertino_picker.py +0 -0
  140. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/controls/cupertino/cupertino_radio.py +0 -0
  141. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/controls/cupertino/cupertino_segmented_button.py +0 -0
  142. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/controls/cupertino/cupertino_slider.py +0 -0
  143. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/controls/cupertino/cupertino_sliding_segmented_button.py +0 -0
  144. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/controls/cupertino/cupertino_switch.py +0 -0
  145. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/controls/cupertino/cupertino_textfield.py +0 -0
  146. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/controls/cupertino/cupertino_timer_picker.py +0 -0
  147. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/controls/cupertino/cupertino_tinted_button.py +0 -0
  148. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/controls/device_info.py +0 -0
  149. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/controls/dialog_control.py +0 -0
  150. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/controls/duration.py +0 -0
  151. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/controls/embed_json_encoder.py +0 -0
  152. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/controls/events.py +0 -0
  153. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/controls/exceptions.py +0 -0
  154. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/controls/geometry.py +0 -0
  155. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/controls/gradients.py +0 -0
  156. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/controls/icon_data.py +0 -0
  157. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/controls/id_counter.py +0 -0
  158. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/controls/keys.py +0 -0
  159. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/controls/layout_control.py +0 -0
  160. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/controls/margin.py +0 -0
  161. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/controls/material/__init__.py +0 -0
  162. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/controls/material/alert_dialog.py +0 -0
  163. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/controls/material/app_bar.py +0 -0
  164. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/controls/material/auto_complete.py +0 -0
  165. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/controls/material/badge.py +0 -0
  166. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/controls/material/banner.py +0 -0
  167. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/controls/material/bottom_app_bar.py +0 -0
  168. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/controls/material/bottom_sheet.py +0 -0
  169. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/controls/material/button.py +0 -0
  170. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/controls/material/card.py +0 -0
  171. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/controls/material/checkbox.py +0 -0
  172. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/controls/material/chip.py +0 -0
  173. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/controls/material/circle_avatar.py +0 -0
  174. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/controls/material/container.py +0 -0
  175. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/controls/material/context_menu.py +0 -0
  176. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/controls/material/datatable.py +0 -0
  177. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/controls/material/date_picker.py +0 -0
  178. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/controls/material/date_range_picker.py +0 -0
  179. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/controls/material/divider.py +0 -0
  180. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/controls/material/dropdown.py +0 -0
  181. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/controls/material/dropdownm2.py +0 -0
  182. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/controls/material/expansion_panel.py +0 -0
  183. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/controls/material/expansion_tile.py +0 -0
  184. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/controls/material/filled_button.py +0 -0
  185. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/controls/material/filled_tonal_button.py +0 -0
  186. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/controls/material/floating_action_button.py +0 -0
  187. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/controls/material/form_field_control.py +0 -0
  188. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/controls/material/icon_button.py +0 -0
  189. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/controls/material/icons.json +0 -0
  190. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/controls/material/icons.py +0 -0
  191. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/controls/material/icons.pyi +0 -0
  192. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/controls/material/list_tile.py +0 -0
  193. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/controls/material/menu_bar.py +0 -0
  194. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/controls/material/menu_item_button.py +0 -0
  195. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/controls/material/navigation_bar.py +0 -0
  196. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/controls/material/navigation_drawer.py +0 -0
  197. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/controls/material/navigation_rail.py +0 -0
  198. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/controls/material/outlined_button.py +0 -0
  199. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/controls/material/popup_menu_button.py +0 -0
  200. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/controls/material/progress_bar.py +0 -0
  201. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/controls/material/progress_ring.py +0 -0
  202. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/controls/material/radio.py +0 -0
  203. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/controls/material/radio_group.py +0 -0
  204. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/controls/material/range_slider.py +0 -0
  205. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/controls/material/reorderable_list_view.py +0 -0
  206. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/controls/material/search_bar.py +0 -0
  207. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/controls/material/segmented_button.py +0 -0
  208. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/controls/material/selection_area.py +0 -0
  209. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/controls/material/slider.py +0 -0
  210. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/controls/material/snack_bar.py +0 -0
  211. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/controls/material/submenu_button.py +0 -0
  212. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/controls/material/switch.py +0 -0
  213. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/controls/material/tabs.py +0 -0
  214. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/controls/material/text_button.py +0 -0
  215. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/controls/material/textfield.py +0 -0
  216. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/controls/material/time_picker.py +0 -0
  217. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/controls/material/tooltip.py +0 -0
  218. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/controls/material/vertical_divider.py +0 -0
  219. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/controls/multi_view.py +0 -0
  220. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/controls/padding.py +0 -0
  221. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/controls/page.py +0 -0
  222. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/controls/painting.py +0 -0
  223. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/controls/query_string.py +0 -0
  224. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/controls/ref.py +0 -0
  225. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/controls/scrollable_control.py +0 -0
  226. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/controls/services/__init__.py +0 -0
  227. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/controls/services/accelerometer.py +0 -0
  228. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/controls/services/barometer.py +0 -0
  229. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/controls/services/battery.py +0 -0
  230. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/controls/services/browser_context_menu.py +0 -0
  231. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/controls/services/clipboard.py +0 -0
  232. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/controls/services/connectivity.py +0 -0
  233. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/controls/services/file_picker.py +0 -0
  234. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/controls/services/gyroscope.py +0 -0
  235. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/controls/services/haptic_feedback.py +0 -0
  236. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/controls/services/magnetometer.py +0 -0
  237. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/controls/services/screen_brightness.py +0 -0
  238. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/controls/services/semantics_service.py +0 -0
  239. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/controls/services/sensor_error_event.py +0 -0
  240. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/controls/services/service.py +0 -0
  241. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/controls/services/shake_detector.py +0 -0
  242. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/controls/services/share.py +0 -0
  243. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/controls/services/shared_preferences.py +0 -0
  244. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/controls/services/storage_paths.py +0 -0
  245. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/controls/services/url_launcher.py +0 -0
  246. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/controls/services/user_accelerometer.py +0 -0
  247. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/controls/services/wakelock.py +0 -0
  248. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/controls/template_route.py +0 -0
  249. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/controls/text_style.py +0 -0
  250. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/controls/theme.py +0 -0
  251. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/controls/transform.py +0 -0
  252. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/controls/types.py +0 -0
  253. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/controls/value_types.py +0 -0
  254. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/data_channel.py +0 -0
  255. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/fastapi/__init__.py +0 -0
  256. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/messaging/connection.py +0 -0
  257. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/messaging/flet_dart_bridge_server.py +0 -0
  258. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/messaging/flet_socket_server.py +0 -0
  259. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/messaging/protocol.py +0 -0
  260. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/messaging/pyodide_connection.py +0 -0
  261. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/messaging/session.py +0 -0
  262. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/messaging/session_store.py +0 -0
  263. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/pubsub/__init__.py +0 -0
  264. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/pubsub/pubsub_client.py +0 -0
  265. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/pubsub/pubsub_hub.py +0 -0
  266. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/py.typed +0 -0
  267. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/pytest_plugin.py +0 -0
  268. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/security/__init__.py +0 -0
  269. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/testing/__init__.py +0 -0
  270. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/testing/finder.py +0 -0
  271. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/testing/flet_test_app.py +0 -0
  272. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/testing/remote_tester.py +0 -0
  273. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/testing/tester.py +0 -0
  274. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/utils/browser.py +0 -0
  275. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/utils/classproperty.py +0 -0
  276. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/utils/deprecated.py +0 -0
  277. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/utils/deprecated_enum.py +0 -0
  278. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/utils/environment.py +0 -0
  279. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/utils/from_dict.py +0 -0
  280. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/utils/griffe_deprecations.py +0 -0
  281. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/utils/hashing.py +0 -0
  282. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/utils/json_utils.py +0 -0
  283. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/utils/locks.py +0 -0
  284. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/utils/network.py +0 -0
  285. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/utils/object_model.py +0 -0
  286. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/utils/once.py +0 -0
  287. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/utils/pip.py +0 -0
  288. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/utils/platform_utils.py +0 -0
  289. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/utils/slugify.py +0 -0
  290. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/utils/strings.py +0 -0
  291. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/utils/typing_utils.py +0 -0
  292. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/utils/validation.py +0 -0
  293. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet/utils/vector.py +0 -0
  294. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet.egg-info/dependency_links.txt +0 -0
  295. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet.egg-info/entry_points.txt +0 -0
  296. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/src/flet.egg-info/top_level.txt +0 -0
  297. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/tests/test_assets_dir_resolution.py +0 -0
  298. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/tests/test_auth_lazy_imports.py +0 -0
  299. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/tests/test_base_control.py +0 -0
  300. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/tests/test_client_actions.py +0 -0
  301. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/tests/test_colors.py +0 -0
  302. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/tests/test_component_diff.py +0 -0
  303. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/tests/test_component_effects.py +0 -0
  304. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/tests/test_component_owned_identity.py +0 -0
  305. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/tests/test_component_renderer.py +0 -0
  306. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/tests/test_context_auto_update.py +0 -0
  307. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/tests/test_dataclasses.py +0 -0
  308. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/tests/test_datetime.py +0 -0
  309. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/tests/test_deprecated.py +0 -0
  310. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/tests/test_environment.py +0 -0
  311. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/tests/test_events.py +0 -0
  312. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/tests/test_from_dict.py +0 -0
  313. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/tests/test_generator_handler_yield.py +0 -0
  314. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/tests/test_griffe_deprecations.py +0 -0
  315. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/tests/test_icons.py +0 -0
  316. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/tests/test_object_diff_in_place.py +0 -0
  317. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/tests/test_object_diff_memory_churn.py +0 -0
  318. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/tests/test_object_diff_performance.py +0 -0
  319. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/tests/test_observable.py +0 -0
  320. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/tests/test_patch_dataclass.py +0 -0
  321. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/tests/test_raw_image_pixels.py +0 -0
  322. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/tests/test_router_modal.py +0 -0
  323. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/tests/test_router_pop.py +0 -0
  324. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/tests/test_router_recursive.py +0 -0
  325. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/tests/test_session_disconnect_buffering.py +0 -0
  326. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/tests/test_skip_double_update.py +0 -0
  327. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/tests/test_use_dialog.py +0 -0
  328. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/tests/test_validation.py +0 -0
  329. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/tests/test_validation_benchmark.py +0 -0
  330. {flet-1.0.0.dev0 → flet-1.0.0.dev2}/tests/test_version.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: flet
3
- Version: 1.0.0.dev0
3
+ Version: 1.0.0.dev2
4
4
  Summary: Flet for Python - easily build interactive multi-platform apps in Python
5
5
  Author-email: "Appveyor Systems Inc." <hello@flet.dev>
6
6
  License-Expression: Apache-2.0
@@ -9,23 +9,23 @@ Project-URL: Repository, https://github.com/flet-dev/flet
9
9
  Project-URL: Documentation, https://flet.dev/docs/
10
10
  Requires-Python: >=3.10
11
11
  Description-Content-Type: text/markdown
12
- Requires-Dist: flet-cli==1.0.0.dev0; extra == "cli"
13
- Requires-Dist: flet-web==1.0.0.dev0; extra == "web"
12
+ Requires-Dist: flet-cli==1.0.0.dev2; extra == "cli"
13
+ Requires-Dist: flet-web==1.0.0.dev2; extra == "web"
14
14
  Requires-Dist: oauthlib>=3.2.2; platform_system != "Emscripten"
15
15
  Requires-Dist: httpx>=0.28.1; platform_system != "Emscripten"
16
16
  Requires-Dist: repath>=0.9.0
17
17
  Requires-Dist: msgpack>=1.1.0
18
18
  Requires-Dist: typing-extensions; python_version < "3.11"
19
19
  Provides-Extra: all
20
- Requires-Dist: flet-cli==1.0.0.dev0; extra == "all"
21
- Requires-Dist: flet-web==1.0.0.dev0; extra == "all"
22
- Requires-Dist: flet-desktop==1.0.0.dev0; extra == "all"
20
+ Requires-Dist: flet-cli==1.0.0.dev2; extra == "all"
21
+ Requires-Dist: flet-web==1.0.0.dev2; extra == "all"
22
+ Requires-Dist: flet-desktop==1.0.0.dev2; extra == "all"
23
23
  Provides-Extra: cli
24
- Requires-Dist: flet-cli==1.0.0.dev0; extra == "cli"
24
+ Requires-Dist: flet-cli==1.0.0.dev2; extra == "cli"
25
25
  Provides-Extra: desktop
26
- Requires-Dist: flet-desktop==1.0.0.dev0; extra == "desktop"
26
+ Requires-Dist: flet-desktop==1.0.0.dev2; extra == "desktop"
27
27
  Provides-Extra: web
28
- Requires-Dist: flet-web==1.0.0.dev0; extra == "web"
28
+ Requires-Dist: flet-web==1.0.0.dev2; extra == "web"
29
29
  Provides-Extra: test
30
30
  Requires-Dist: pytest>=7.2.0; extra == "test"
31
31
  Requires-Dist: pytest-asyncio>=1.1.0; extra == "test"
@@ -1,14 +1,14 @@
1
1
  [project]
2
2
  name = "flet"
3
- version = "1.0.0.dev0"
3
+ version = "1.0.0.dev2"
4
4
  description = "Flet for Python - easily build interactive multi-platform apps in Python"
5
5
  authors = [{name = "Appveyor Systems Inc.", email = "hello@flet.dev"}]
6
6
  license = "Apache-2.0"
7
7
  readme = "README.md"
8
8
  requires-python = ">=3.10"
9
9
  dependencies = [
10
- "flet-cli==1.0.0.dev0; extra == 'cli'",
11
- "flet-web==1.0.0.dev0; extra == 'web'",
10
+ "flet-cli==1.0.0.dev2; extra == 'cli'",
11
+ "flet-web==1.0.0.dev2; extra == 'web'",
12
12
  "oauthlib >=3.2.2; platform_system != 'Emscripten'",
13
13
  "httpx >=0.28.1; platform_system != 'Emscripten'",
14
14
  "repath >=0.9.0",
@@ -23,15 +23,15 @@ Documentation = "https://flet.dev/docs/"
23
23
 
24
24
  [project.optional-dependencies]
25
25
  all = [
26
- "flet-cli==1.0.0.dev0",
27
- "flet-web==1.0.0.dev0",
28
- "flet-desktop==1.0.0.dev0",
26
+ "flet-cli==1.0.0.dev2",
27
+ "flet-web==1.0.0.dev2",
28
+ "flet-desktop==1.0.0.dev2",
29
29
  ]
30
- cli = ["flet-cli==1.0.0.dev0"]
30
+ cli = ["flet-cli==1.0.0.dev2"]
31
31
  desktop = [
32
- "flet-desktop==1.0.0.dev0",
32
+ "flet-desktop==1.0.0.dev2",
33
33
  ]
34
- web = ["flet-web==1.0.0.dev0"]
34
+ web = ["flet-web==1.0.0.dev2"]
35
35
  # Dependencies needed to run integration tests written with `flet.testing`
36
36
  # (the `flet test` command / the pytest plugin). Pillow/numpy/scikit-image
37
37
  # back screenshot and GIF comparison.
@@ -62,6 +62,7 @@ extensions = [
62
62
  "flet-flashlight",
63
63
  "flet-geolocator",
64
64
  "flet-lottie",
65
+ "flet-local-auth",
65
66
  "flet-map",
66
67
  "flet-permission-handler",
67
68
  "flet-rive",
@@ -1369,7 +1369,19 @@ class DiffBuilder:
1369
1369
  default = prop_defaults.get(fname)
1370
1370
  old = src_vals.get(fname, default)
1371
1371
  new = dst_vals.get(fname, default)
1372
- if old is new or old == new:
1372
+ if old is new:
1373
+ continue
1374
+ # A child control that compares equal to its predecessor
1375
+ # is still a *different instance* that must be reconciled:
1376
+ # adopt the old _i, get its _parent stamped and replace the
1377
+ # old instance in the session index. Skipping it leaves an
1378
+ # orphan in the new tree (fresh _i, no _parent) while the
1379
+ # index keeps the old instance whose parent chain dies
1380
+ # with the old tree — the next event dispatched to it
1381
+ # fails with "Control must be added to the page first".
1382
+ # Reconciling an equal subtree emits no operations, so the
1383
+ # equality check is only worth it for non-control values.
1384
+ if not self._holds_control(new) and old == new:
1373
1385
  continue
1374
1386
  if fname in event_fields:
1375
1387
  old = old is not None
@@ -1505,6 +1517,19 @@ class DiffBuilder:
1505
1517
  if dataclasses.is_dataclass(dst) and key is not None:
1506
1518
  prev_classes[key] = dst
1507
1519
 
1520
+ def _holds_control(self, value: Any) -> bool:
1521
+ """Return whether `value` is a control or a list/dict holding controls."""
1522
+ control_cls = self.control_cls
1523
+ if control_cls is None:
1524
+ return False
1525
+ if isinstance(value, control_cls):
1526
+ return True
1527
+ if isinstance(value, (list, tuple)):
1528
+ return any(isinstance(v, control_cls) for v in value)
1529
+ if isinstance(value, dict):
1530
+ return any(isinstance(v, control_cls) for v in value.values())
1531
+ return False
1532
+
1508
1533
  def _dataclass_added(self, item: Any, parent: Any, frozen: bool) -> None:
1509
1534
  """Register dataclasses contained in a newly added value."""
1510
1535
  logger.debug("\n\nDataclass added: %s %s %s", item, parent, frozen)
@@ -6,6 +6,7 @@ from flet.utils.files import (
6
6
  copy_tree,
7
7
  get_current_script_dir,
8
8
  is_within_directory,
9
+ rmtree,
9
10
  safe_tar_extractall,
10
11
  safe_zip_extractall,
11
12
  which,
@@ -67,6 +68,7 @@ __all__ = [
67
68
  "open_in_browser",
68
69
  "patch_dataclass",
69
70
  "random_string",
71
+ "rmtree",
70
72
  "safe_tar_extractall",
71
73
  "safe_zip_extractall",
72
74
  "sha1",
@@ -1,5 +1,6 @@
1
1
  import os
2
2
  import shutil
3
+ import stat
3
4
  import sys
4
5
 
5
6
 
@@ -132,3 +133,25 @@ def get_current_script_dir():
132
133
  """
133
134
  pathname = os.path.dirname(sys.argv[0])
134
135
  return os.path.abspath(pathname)
136
+
137
+
138
+ def rmtree(path, ignore_errors=False):
139
+ """
140
+ Recursively deletes a directory tree, safely handling read-only files on Windows.
141
+
142
+ Args:
143
+ path: Directory path to remove.
144
+ ignore_errors: Whether to ignore errors during deletion.
145
+ """
146
+ p = str(path)
147
+ if not os.path.exists(p):
148
+ return
149
+
150
+ def _remove_readonly(func, file_path, _):
151
+ os.chmod(file_path, stat.S_IWRITE)
152
+ func(file_path)
153
+
154
+ if sys.version_info >= (3, 12):
155
+ shutil.rmtree(p, ignore_errors=ignore_errors, onexc=_remove_readonly)
156
+ else:
157
+ shutil.rmtree(p, ignore_errors=ignore_errors, onerror=_remove_readonly)
@@ -16,7 +16,7 @@ __all__ = [
16
16
  ]
17
17
 
18
18
  # set by CI
19
- flet_version = "1.0.0.dev0"
19
+ flet_version = "1.0.0.dev2"
20
20
  """
21
21
  The Flet version in use.
22
22
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: flet
3
- Version: 1.0.0.dev0
3
+ Version: 1.0.0.dev2
4
4
  Summary: Flet for Python - easily build interactive multi-platform apps in Python
5
5
  Author-email: "Appveyor Systems Inc." <hello@flet.dev>
6
6
  License-Expression: Apache-2.0
@@ -9,23 +9,23 @@ Project-URL: Repository, https://github.com/flet-dev/flet
9
9
  Project-URL: Documentation, https://flet.dev/docs/
10
10
  Requires-Python: >=3.10
11
11
  Description-Content-Type: text/markdown
12
- Requires-Dist: flet-cli==1.0.0.dev0; extra == "cli"
13
- Requires-Dist: flet-web==1.0.0.dev0; extra == "web"
12
+ Requires-Dist: flet-cli==1.0.0.dev2; extra == "cli"
13
+ Requires-Dist: flet-web==1.0.0.dev2; extra == "web"
14
14
  Requires-Dist: oauthlib>=3.2.2; platform_system != "Emscripten"
15
15
  Requires-Dist: httpx>=0.28.1; platform_system != "Emscripten"
16
16
  Requires-Dist: repath>=0.9.0
17
17
  Requires-Dist: msgpack>=1.1.0
18
18
  Requires-Dist: typing-extensions; python_version < "3.11"
19
19
  Provides-Extra: all
20
- Requires-Dist: flet-cli==1.0.0.dev0; extra == "all"
21
- Requires-Dist: flet-web==1.0.0.dev0; extra == "all"
22
- Requires-Dist: flet-desktop==1.0.0.dev0; extra == "all"
20
+ Requires-Dist: flet-cli==1.0.0.dev2; extra == "all"
21
+ Requires-Dist: flet-web==1.0.0.dev2; extra == "all"
22
+ Requires-Dist: flet-desktop==1.0.0.dev2; extra == "all"
23
23
  Provides-Extra: cli
24
- Requires-Dist: flet-cli==1.0.0.dev0; extra == "cli"
24
+ Requires-Dist: flet-cli==1.0.0.dev2; extra == "cli"
25
25
  Provides-Extra: desktop
26
- Requires-Dist: flet-desktop==1.0.0.dev0; extra == "desktop"
26
+ Requires-Dist: flet-desktop==1.0.0.dev2; extra == "desktop"
27
27
  Provides-Extra: web
28
- Requires-Dist: flet-web==1.0.0.dev0; extra == "web"
28
+ Requires-Dist: flet-web==1.0.0.dev2; extra == "web"
29
29
  Provides-Extra: test
30
30
  Requires-Dist: pytest>=7.2.0; extra == "test"
31
31
  Requires-Dist: pytest-asyncio>=1.1.0; extra == "test"
@@ -305,6 +305,7 @@ tests/test_datetime.py
305
305
  tests/test_deprecated.py
306
306
  tests/test_environment.py
307
307
  tests/test_events.py
308
+ tests/test_files.py
308
309
  tests/test_from_dict.py
309
310
  tests/test_generator_handler_yield.py
310
311
  tests/test_griffe_deprecations.py
@@ -2,10 +2,10 @@ repath>=0.9.0
2
2
  msgpack>=1.1.0
3
3
 
4
4
  [:extra == "cli"]
5
- flet-cli==1.0.0.dev0
5
+ flet-cli==1.0.0.dev2
6
6
 
7
7
  [:extra == "web"]
8
- flet-web==1.0.0.dev0
8
+ flet-web==1.0.0.dev2
9
9
 
10
10
  [:platform_system != "Emscripten"]
11
11
  oauthlib>=3.2.2
@@ -15,15 +15,15 @@ httpx>=0.28.1
15
15
  typing-extensions
16
16
 
17
17
  [all]
18
- flet-cli==1.0.0.dev0
19
- flet-web==1.0.0.dev0
20
- flet-desktop==1.0.0.dev0
18
+ flet-cli==1.0.0.dev2
19
+ flet-web==1.0.0.dev2
20
+ flet-desktop==1.0.0.dev2
21
21
 
22
22
  [cli]
23
- flet-cli==1.0.0.dev0
23
+ flet-cli==1.0.0.dev2
24
24
 
25
25
  [desktop]
26
- flet-desktop==1.0.0.dev0
26
+ flet-desktop==1.0.0.dev2
27
27
 
28
28
  [test]
29
29
  pytest>=7.2.0
@@ -33,4 +33,4 @@ pillow>=10.3.0
33
33
  scikit-image>=0.25.2
34
34
 
35
35
  [web]
36
- flet-web==1.0.0.dev0
36
+ flet-web==1.0.0.dev2
@@ -0,0 +1,79 @@
1
+ import os
2
+ import stat
3
+ import sys
4
+ import tempfile
5
+ from unittest.mock import patch
6
+
7
+ import pytest
8
+
9
+ from flet.utils import rmtree
10
+
11
+
12
+ def test_rmtree_removes_readonly_files():
13
+ temp_dir = tempfile.mkdtemp()
14
+ sub_dir = os.path.join(temp_dir, "subdir")
15
+ os.makedirs(sub_dir)
16
+
17
+ readonly_file = os.path.join(sub_dir, "readonly.idx")
18
+ with open(readonly_file, "w") as fp:
19
+ fp.write("index-data")
20
+
21
+ # Set file to read-only (which fails on Windows with standard shutil.rmtree)
22
+ os.chmod(readonly_file, stat.S_IREAD)
23
+
24
+ rmtree(temp_dir)
25
+ assert not os.path.exists(temp_dir)
26
+
27
+
28
+ def test_rmtree_nonexistent_directory():
29
+ # Should not raise exception
30
+ nonexistent = os.path.join(tempfile.gettempdir(), "nonexistent_dir_12345")
31
+ rmtree(nonexistent)
32
+
33
+
34
+ def test_rmtree_raises_permission_error_when_deletion_fails():
35
+ temp_dir = tempfile.mkdtemp()
36
+ test_file = os.path.join(temp_dir, "locked.txt")
37
+ with open(test_file, "w") as fp:
38
+ fp.write("locked")
39
+
40
+ try:
41
+ with (
42
+ patch("os.unlink", side_effect=PermissionError("File locked")),
43
+ pytest.raises(PermissionError),
44
+ ):
45
+ rmtree(temp_dir)
46
+ finally:
47
+ if os.path.exists(temp_dir):
48
+ rmtree(temp_dir, ignore_errors=True)
49
+
50
+
51
+ def test_rmtree_ignore_errors_when_deletion_fails():
52
+ temp_dir = tempfile.mkdtemp()
53
+ test_file = os.path.join(temp_dir, "locked.txt")
54
+ with open(test_file, "w") as fp:
55
+ fp.write("locked")
56
+
57
+ try:
58
+ with patch("os.unlink", side_effect=PermissionError("File locked")):
59
+ rmtree(temp_dir, ignore_errors=True)
60
+ finally:
61
+ if os.path.exists(temp_dir):
62
+ import shutil
63
+
64
+ shutil.rmtree(temp_dir, ignore_errors=True)
65
+
66
+
67
+ @pytest.mark.skipif(sys.platform != "win32", reason="Windows-specific file locking")
68
+ def test_rmtree_raises_permission_error_on_locked_file_windows():
69
+ temp_dir = tempfile.mkdtemp()
70
+ test_file = os.path.join(temp_dir, "locked.txt")
71
+ with open(test_file, "w") as fp:
72
+ fp.write("locked")
73
+
74
+ # On Windows, keeping an open handle locks the file from deletion
75
+ with open(test_file), pytest.raises(PermissionError):
76
+ rmtree(temp_dir)
77
+
78
+ if os.path.exists(temp_dir):
79
+ rmtree(temp_dir, ignore_errors=True)
@@ -1329,3 +1329,89 @@ def test_fields_start_with_on_update():
1329
1329
 
1330
1330
  assert isinstance(u_msg, list)
1331
1331
  assert u_msg == expected
1332
+
1333
+
1334
+ def _stable_handler(e):
1335
+ pass
1336
+
1337
+
1338
+ @ft.control("PropListHolder")
1339
+ class PropListHolder(ft.BaseControl):
1340
+ # required list field, no default_factory → Prop-managed (like
1341
+ # DataTable.columns), not a structural field like Column.controls
1342
+ items: list[MyText]
1343
+
1344
+
1345
+ def test_frozen_value_equal_content_child_is_reconciled():
1346
+ # A re-rendered component rebuilds its output. A child in a Prop-managed
1347
+ # field that compares equal to the previous render's is still a different
1348
+ # instance: it must adopt the old _i, get its parent stamped and be
1349
+ # reported as added so the session index swaps to it — otherwise the new
1350
+ # tree holds an orphan and the next event on it raises
1351
+ # "Control must be added to the page first".
1352
+ old_child = MyText("a", on_select=_stable_handler)
1353
+ new_child = MyText("a", on_select=_stable_handler)
1354
+ assert old_child == new_child
1355
+ assert old_child is not new_child
1356
+ old = ft.Container(content=old_child)
1357
+ new = ft.Container(content=new_child)
1358
+ old._frozen = True
1359
+
1360
+ patch, _, added_controls, _ = make_diff(new, old)
1361
+
1362
+ assert patch == []
1363
+ assert new_child._i == old_child._i
1364
+ assert new_child.parent is new
1365
+ assert new_child in added_controls
1366
+
1367
+
1368
+ def test_frozen_value_equal_list_prop_children_are_reconciled():
1369
+ assert "items" in PropListHolder._prop_defaults
1370
+ old_items = [
1371
+ MyText("a", on_select=_stable_handler),
1372
+ MyText("b", on_select=_stable_handler),
1373
+ ]
1374
+ new_items = [
1375
+ MyText("a", on_select=_stable_handler),
1376
+ MyText("b", on_select=_stable_handler),
1377
+ ]
1378
+ assert old_items == new_items
1379
+ old = PropListHolder(items=old_items)
1380
+ new = PropListHolder(items=new_items)
1381
+ old._frozen = True
1382
+
1383
+ patch, _, added_controls, _ = make_diff(new, old)
1384
+
1385
+ assert patch == []
1386
+ for old_item, new_item in zip(old_items, new_items):
1387
+ assert new_item._i == old_item._i
1388
+ assert new_item.parent is new
1389
+ assert new_item in added_controls
1390
+
1391
+
1392
+ def test_frozen_identical_content_child_is_skipped():
1393
+ # the same instance on both sides needs no reconciliation at all
1394
+ child = MyText("a", on_select=_stable_handler)
1395
+ old = ft.Container(content=child)
1396
+ new = ft.Container(content=child)
1397
+ old._frozen = True
1398
+
1399
+ patch, _, added_controls, _ = make_diff(new, old)
1400
+
1401
+ assert patch == []
1402
+ assert child not in added_controls
1403
+
1404
+
1405
+ def test_frozen_changed_content_child_still_patches():
1406
+ old = ft.Container(content=MyText("a", on_select=_stable_handler))
1407
+ new_child = MyText("b", on_select=_stable_handler)
1408
+ new = ft.Container(content=new_child)
1409
+ old._frozen = True
1410
+
1411
+ patch, _, added_controls, _ = make_diff(new, old)
1412
+
1413
+ assert cmp_ops(
1414
+ patch, [{"op": "replace", "path": ["content", "value"], "value": "b"}]
1415
+ )
1416
+ assert new_child.parent is new
1417
+ assert new_child in added_controls
File without changes
File without changes
File without changes
File without changes