Skip to content

Commit dcf9396

Browse files
v1: Replace Colors.BLACK{shade} with BLACK_{shade}, WHITE{shade} with WHITE_{shade} (#5752)
* Fix attribute setting in Observable class Corrects logic in Observable to set attribute directly if it does not exist, preventing unnecessary value comparison and notification for new attributes. * Refactor attribute setting in Observable class Simplifies logic for setting attributes by removing redundant checks and directly handling cases where the attribute may not exist. This improves code clarity and maintains correct notification behavior. * Fix attribute update order in Observable class Moves attribute assignment before value comparison in Observable.__setattr__ to ensure correct notification behavior when attribute values change. * Add deprecated color aliases to Colors enum Introduced DeprecatedEnumMeta to support deprecated enum members and added deprecated color aliases to the Colors enum for backward compatibility. Deprecated aliases now emit a DeprecationWarning and redirect to the new member names. Also updated __all__ and imports to expose DeprecatedEnumMeta. * Update color constants to new naming convention Replaces deprecated color constants like BLACK54, WHITE24, etc. with their new underscore-named versions (e.g., BLACK_54, WHITE_24) across all example, tutorial, and documentation files for consistency with the latest Flet API. * Add TODO for deprecated color aliases removal Added a TODO comment indicating that deprecated color aliases should be removed in Flet 1.0. This helps track planned cleanup for future releases.
1 parent 42dcc71 commit dcf9396

File tree

10 files changed

+110
-43
lines changed

10 files changed

+110
-43
lines changed

sdk/python/packages/flet-video/src/flet_video/types.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -189,7 +189,7 @@ class VideoSubtitleConfiguration:
189189
word_spacing=0.0,
190190
color=ft.Colors.WHITE,
191191
weight=ft.FontWeight.NORMAL,
192-
bgcolor=ft.Colors.BLACK54,
192+
bgcolor=ft.Colors.BLACK_54,
193193
)
194194
)
195195
"""The text style to be used for the subtitles."""

sdk/python/packages/flet/docs/controls/submenubutton.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
---
22
class_name: flet.SubmenuButton
33
examples: ../../examples/controls/submenu_button
4-
example_images: ../test-images/examples/core/golden/macos/submenu_button
4+
example_images: ../test-images/examples/material/golden/macos/submenu_button
55
---
66

77
{{ class_summary(class_name, example_images + "/image_for_docs.png", image_caption="Activated submenu button") }}

sdk/python/packages/flet/docs/cookbook/colors.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -82,8 +82,8 @@ Most palettes range from `50` to `900`, in increments of `100`, while **accent s
8282
(e.g., [`Colors.RED_ACCENT`][flet.Colors.RED_ACCENT]) have only `100`, `200`, `400`, and `700`.
8383

8484
In addition to color swatches, Flet provides named black and white variants with built-in opacities, such as:
85-
- [`Colors.BLACK54`][flet.Colors.BLACK54] → black at 54% opacity
86-
- [`Colors.WHITE70`][flet.Colors.WHITE70] → white at 70% opacity
85+
- [`Colors.BLACK_54`][flet.Colors.BLACK_54] → black at 54% opacity
86+
- [`Colors.WHITE_70`][flet.Colors.WHITE_70] → white at 70% opacity
8787

8888
These palette colors can be used:
8989
- directly as values for control color properties (e.g., `bgcolor`, `color`)

sdk/python/packages/flet/docs/cookbook/drag-and-drop.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ def main(page: ft.Page):
125125
def drag_will_accept(e):
126126
# black border when it's allowed to drop and red when it's not
127127
e.control.content.border = ft.border.all(
128-
2, ft.Colors.BLACK45 if e.data == "true" else ft.Colors.RED
128+
2, ft.Colors.BLACK_45 if e.data == "true" else ft.Colors.RED
129129
)
130130
e.control.update()
131131

sdk/python/packages/flet/docs/tutorials/calculator.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -218,7 +218,7 @@ Now let's create child classes for all three types of buttons:
218218
class DigitButton(CalcButton):
219219
def __init__(self, text, expand=1):
220220
CalcButton.__init__(self, text, expand)
221-
self.bgcolor = ft.Colors.WHITE24
221+
self.bgcolor = ft.Colors.WHITE_24
222222
self.color = ft.Colors.WHITE
223223

224224
class ActionButton(CalcButton):

sdk/python/packages/flet/docs/tutorials/chat.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -231,7 +231,7 @@ def on_message(message: Message):
231231
chat.controls.append(ft.Text(f"{message.user}: {message.text}"))
232232
elif message.message_type == "login_message":
233233
chat.controls.append(
234-
ft.Text(message.text, italic=True, color=ft.Colors.BLACK45, size=12)
234+
ft.Text(message.text, italic=True, color=ft.Colors.BLACK_45, size=12)
235235
)
236236
page.update()
237237
```
@@ -365,7 +365,7 @@ Instances of `ChatMessage` will be created instead of plain `Text` chat messages
365365
if message.message_type == "chat_message":
366366
m = ChatMessage(message)
367367
elif message.message_type == "login_message":
368-
m = ft.Text(message.text, italic=True, color=ft.Colors.BLACK45, size=12)
368+
m = ft.Text(message.text, italic=True, color=ft.Colors.BLACK_45, size=12)
369369
chat.controls.append(m)
370370
page.update()
371371
```

sdk/python/packages/flet/src/flet/components/observable.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -147,10 +147,9 @@ def __setattr__(self, name: str, value: Any):
147147
object.__setattr__(self, name, value)
148148
return
149149
value = self._wrap_if_collection(name, value)
150-
had = hasattr(self, name)
151-
old = object.__getattribute__(self, name) if had else None
150+
old = object.__getattribute__(self, name) if hasattr(self, name) else None
151+
object.__setattr__(self, name, value)
152152
if not value_equal(old, value):
153-
object.__setattr__(self, name, value)
154153
self._notify(name)
155154

156155
def __delattr__(self, name: str):

sdk/python/packages/flet/src/flet/controls/colors.py

Lines changed: 41 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -55,13 +55,15 @@
5555
from enum import Enum
5656
from typing import TYPE_CHECKING, Optional, Union
5757

58+
from flet.utils.deprecated_enum import DeprecatedEnumMeta
59+
5860
if TYPE_CHECKING:
5961
from flet.controls.types import ColorValue
6062

6163
__all__ = ["Colors"]
6264

6365

64-
class Colors(str, Enum):
66+
class Colors(str, Enum, metaclass=DeprecatedEnumMeta):
6567
def __eq__(self, other):
6668
if isinstance(other, str):
6769
return self.value.lower() == other.lower()
@@ -198,12 +200,12 @@ def with_opacity(opacity: Union[int, float], color: "ColorValue") -> str:
198200
AMBER_ACCENT_400 = "amberaccent400"
199201
AMBER_ACCENT_700 = "amberaccent700"
200202
BLACK = "black"
201-
BLACK12 = "black12"
202-
BLACK26 = "black26"
203-
BLACK38 = "black38"
204-
BLACK45 = "black45"
205-
BLACK54 = "black54"
206-
BLACK87 = "black87"
203+
BLACK_12 = "black12"
204+
BLACK_26 = "black26"
205+
BLACK_38 = "black38"
206+
BLACK_45 = "black45"
207+
BLACK_54 = "black54"
208+
BLACK_87 = "black87"
207209
BLUE = "blue"
208210
BLUE_100 = "blue100"
209211
BLUE_200 = "blue200"
@@ -463,14 +465,14 @@ def with_opacity(opacity: Union[int, float], color: "ColorValue") -> str:
463465
TEAL_ACCENT_700 = "tealaccent700"
464466
TRANSPARENT = "transparent"
465467
WHITE = "white"
466-
WHITE10 = "white10"
467-
WHITE12 = "white12"
468-
WHITE24 = "white24"
469-
WHITE30 = "white30"
470-
WHITE38 = "white38"
471-
WHITE54 = "white54"
472-
WHITE60 = "white60"
473-
WHITE70 = "white70"
468+
WHITE_10 = "white10"
469+
WHITE_12 = "white12"
470+
WHITE_24 = "white24"
471+
WHITE_30 = "white30"
472+
WHITE_38 = "white38"
473+
WHITE_54 = "white54"
474+
WHITE_60 = "white60"
475+
WHITE_70 = "white70"
474476
YELLOW = "yellow"
475477
YELLOW_100 = "yellow100"
476478
YELLOW_200 = "yellow200"
@@ -487,3 +489,27 @@ def with_opacity(opacity: Union[int, float], color: "ColorValue") -> str:
487489
YELLOW_ACCENT_200 = "yellowaccent200"
488490
YELLOW_ACCENT_400 = "yellowaccent400"
489491
YELLOW_ACCENT_700 = "yellowaccent700"
492+
493+
494+
# TODO - remove in Flet 1.0
495+
_DEPRECATED_COLOR_ALIASES = {
496+
"BLACK12": ("BLACK_12", "Use Colors.BLACK_12 instead."),
497+
"BLACK26": ("BLACK_26", "Use Colors.BLACK_26 instead."),
498+
"BLACK38": ("BLACK_38", "Use Colors.BLACK_38 instead."),
499+
"BLACK45": ("BLACK_45", "Use Colors.BLACK_45 instead."),
500+
"BLACK54": ("BLACK_54", "Use Colors.BLACK_54 instead."),
501+
"BLACK87": ("BLACK_87", "Use Colors.BLACK_87 instead."),
502+
"WHITE10": ("WHITE_10", "Use Colors.WHITE_10 instead."),
503+
"WHITE12": ("WHITE_12", "Use Colors.WHITE_12 instead."),
504+
"WHITE24": ("WHITE_24", "Use Colors.WHITE_24 instead."),
505+
"WHITE30": ("WHITE_30", "Use Colors.WHITE_30 instead."),
506+
"WHITE38": ("WHITE_38", "Use Colors.WHITE_38 instead."),
507+
"WHITE54": ("WHITE_54", "Use Colors.WHITE_54 instead."),
508+
"WHITE60": ("WHITE_60", "Use Colors.WHITE_60 instead."),
509+
"WHITE70": ("WHITE_70", "Use Colors.WHITE_70 instead."),
510+
}
511+
512+
Colors._deprecated_members_ = _DEPRECATED_COLOR_ALIASES
513+
514+
for alias_name, (target_name, _) in _DEPRECATED_COLOR_ALIASES.items():
515+
Colors._member_map_[alias_name] = getattr(Colors, target_name)

sdk/python/packages/flet/src/flet/utils/__init__.py

Lines changed: 19 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
from flet.utils.browser import open_in_browser
22
from flet.utils.classproperty import classproperty
33
from flet.utils.deprecated import deprecated, deprecated_class, deprecated_warning
4+
from flet.utils.deprecated_enum import DeprecatedEnumMeta
45
from flet.utils.files import (
56
cleanup_path,
67
copy_tree,
@@ -35,27 +36,23 @@
3536
from flet.utils.vector import Vector
3637

3738
__all__ = [
38-
"open_in_browser",
39+
"DeprecatedEnumMeta",
40+
"Once",
41+
"Vector",
42+
"calculate_file_hash",
3943
"classproperty",
44+
"cleanup_path",
45+
"copy_tree",
4046
"deprecated",
4147
"deprecated_class",
4248
"deprecated_warning",
43-
"cleanup_path",
44-
"copy_tree",
45-
"get_current_script_dir",
46-
"is_within_directory",
47-
"safe_tar_extractall",
48-
"which",
4949
"from_dict",
50-
"calculate_file_hash",
51-
"sha1",
52-
"to_json",
53-
"get_free_tcp_port",
54-
"get_local_ip",
55-
"Once",
56-
"patch_dataclass",
5750
"get_arch",
5851
"get_bool_env_var",
52+
"get_current_script_dir",
53+
"get_free_tcp_port",
54+
"get_local_ip",
55+
"get_param_count",
5956
"get_platform",
6057
"is_android",
6158
"is_asyncio",
@@ -67,8 +64,13 @@
6764
"is_mobile",
6865
"is_pyodide",
6966
"is_windows",
70-
"slugify",
67+
"is_within_directory",
68+
"open_in_browser",
69+
"patch_dataclass",
7170
"random_string",
72-
"Vector",
73-
"get_param_count",
71+
"safe_tar_extractall",
72+
"sha1",
73+
"slugify",
74+
"to_json",
75+
"which",
7476
]
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
from __future__ import annotations
2+
3+
import warnings
4+
from enum import EnumMeta
5+
6+
__all__ = ["DeprecatedEnumMeta"]
7+
8+
9+
class DeprecatedEnumMeta(EnumMeta):
10+
"""Enum metaclass that supports deprecation aliases.
11+
12+
Enums can declare `_deprecated_members_` as a mapping of alias name to a tuple
13+
containing the canonical member name and a deprecation message. Accessing an alias
14+
returns the canonical member while emitting a `DeprecationWarning`.
15+
"""
16+
17+
def _resolve_deprecated(cls, name: str):
18+
deprecated = getattr(cls, "_deprecated_members_", {})
19+
info = deprecated.get(name)
20+
if not info:
21+
return None
22+
target_name, message = info
23+
warnings.warn(
24+
f"{cls.__name__}.{name} is deprecated. {message}",
25+
DeprecationWarning,
26+
stacklevel=2,
27+
)
28+
return getattr(cls, target_name)
29+
30+
def __getattr__(cls, name: str):
31+
member = cls._resolve_deprecated(name)
32+
if member is not None:
33+
return member
34+
return super().__getattr__(name)
35+
36+
def __getitem__(cls, name: str):
37+
member = cls._resolve_deprecated(name)
38+
if member is not None:
39+
return member
40+
return super().__getitem__(name)

0 commit comments

Comments
 (0)