Skip to content

Commit 02b6ab1

Browse files
Comparison of off-/online mentions works
1 parent 7deeca7 commit 02b6ab1

File tree

7 files changed

+486
-17
lines changed

7 files changed

+486
-17
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
- Fix: Uploading a file via an import URL was cast to a `None` instead of `FileImportSuccess`.
2020
- Chg: Return `FileUploadStatus` in `UploadedFile.file_import_result` for easier usage.
2121
- Fix: All objects are no longer `hash`able as they are mutable and thus the former behaviour was semantically incorrect.
22+
- Fix: Comparison of off-/online `MentionObject`s works, also when `UserRef` is used.
2223

2324
## Version 0.9.5, 2025-10-24
2425

src/ultimate_notion/markdown.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -134,17 +134,17 @@ def is_math(rt: RichTextBase) -> TypeGuard[Math]:
134134
return rt.is_equation
135135

136136
for idx, text in enumerate(rich_texts):
137+
plain_text = text.obj_ref.plain_text
137138
if is_math(text):
138-
md_rich_texts[idx] = '$' + text.obj_ref.plain_text.strip() + '$'
139+
md_rich_texts[idx] = '$' + plain_text.strip() + '$'
139140
elif is_mention(text):
140-
obj_ref = text.obj_ref
141141
match text.type:
142142
case 'user' | 'date':
143-
md_rich_texts[idx] = f'[{obj_ref.plain_text}]()' # @ is already included
143+
md_rich_texts[idx] = f'[{plain_text}]()' # @ is already included
144144
case 'custom_emoji':
145-
md_rich_texts[idx] = f'{obj_ref.plain_text}' # parentheses are already included
145+
md_rich_texts[idx] = f'{plain_text}' # parentheses are already included
146146
case _:
147-
md_rich_texts[idx] = f'↗[{obj_ref.plain_text}]({obj_ref.href})'
147+
md_rich_texts[idx] = f'↗[{plain_text}]({text.obj_ref.href})'
148148

149149
def find_span(
150150
rich_texts: list[RichTextBase], style_cond: Callable[[RichTextBase], bool]

src/ultimate_notion/obj_api/core.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -255,6 +255,10 @@ def _recurse(obj: Any) -> Any:
255255
setattr(obj_copy, field_name, Unset)
256256
elif field_name == 'color' and is_unset(field_value):
257257
setattr(obj_copy, field_name, _normalize_color(field_value))
258+
elif isinstance(obj, TypedObject) and obj.type == 'mention' and field_name == 'plain_text':
259+
setattr(
260+
obj_copy, field_name, Unset
261+
) # allows comparing offline-built mentions with UserRef to online ones
258262
else:
259263
setattr(obj_copy, field_name, _recurse(field_value))
260264
return obj_copy

src/ultimate_notion/obj_api/objects.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -379,13 +379,14 @@ class MentionUser(MentionBase[User | UserRef], type='user'):
379379
user: SerializeAsAny[User | UserRef]
380380

381381
@classmethod
382-
def build_mention_from(cls, user: User, *, style: Annotations | None = None) -> MentionObject:
382+
def build_mention_from(cls, user: User | UserRef, *, style: Annotations | None = None) -> MentionObject:
383383
# When creating a user mention, we need to send only the id, not the full object.
384-
user_ref = UserRef.build(user)
384+
user_ref = UserRef.build(user) if isinstance(user, User) else user
385385
mention = cls.model_construct(user=user_ref)
386386
# note that `href` is always `None` for user mentions, also we prepend the '@' to mimic server side
387387
return MentionObject.model_construct(
388-
plain_text=f'@{user.name}',
388+
# Note that in case of UserRef, we set an dummy name that will be replaced by the Notion server later.
389+
plain_text=f'@{user.name}' if isinstance(user, User) else f'@{user_ref.id}',
389390
href=None,
390391
annotations=Unset if style is None else deepcopy(style),
391392
mention=mention,

src/ultimate_notion/rich_text.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -239,7 +239,7 @@ def rich_texts(self) -> tuple[RichTextBase, ...]:
239239
def wrap_obj_ref(cls, obj_refs: list[objs.RichTextBaseObject] | None) -> Self:
240240
obj_refs = [] if obj_refs is None else obj_refs
241241
rich_texts = [RichTextBase.wrap_obj_ref(obj_ref) for obj_ref in obj_refs]
242-
plain_text = ''.join(text.obj_ref.plain_text for text in rich_texts if text)
242+
plain_text = ''.join(text.obj_ref.plain_text for text in rich_texts if isinstance(text.obj_ref.plain_text, str))
243243
obj = cls(plain_text)
244244
obj._rich_texts = cls._compact(rich_texts)
245245
return obj

0 commit comments

Comments
 (0)