From 62f3fc778ee2f04f8fabd97ce80e8447d2791687 Mon Sep 17 00:00:00 2001 From: ale-rt Date: Wed, 27 May 2026 22:28:44 +0200 Subject: [PATCH 1/3] Clean up Backport some clean up from https://github.com/plone/plone.api/pull/592/ --- docs/portal.md | 7 +------ news/592.bugfix.md | 1 + src/plone/api/content.py | 4 ++-- src/plone/api/portal.py | 5 ----- src/plone/api/tests/test_portal.py | 9 +-------- src/plone/api/user.py | 9 ++++++--- 6 files changed, 11 insertions(+), 24 deletions(-) create mode 100644 news/592.bugfix.md diff --git a/docs/portal.md b/docs/portal.md index f3a22a3e..468af179 100644 --- a/docs/portal.md +++ b/docs/portal.md @@ -205,12 +205,7 @@ api.portal.send_email( % % self.assertEqual(len(mailhost.messages), 1) % -% try: -% # Python 3 -% from email import message_from_bytes -% except ImportError: -% # Python 2 -% from email import message_from_string as message_from_bytes +% from email import message_from_bytes % msg = message_from_bytes(mailhost.messages[0]) % self.assertEqual(msg['To'], 'bob@plone.org') % self.assertEqual(msg['From'], 'noreply@plone.org') diff --git a/news/592.bugfix.md b/news/592.bugfix.md new file mode 100644 index 00000000..b55dbc5e --- /dev/null +++ b/news/592.bugfix.md @@ -0,0 +1 @@ +Clean up. @ale-rt diff --git a/src/plone/api/content.py b/src/plone/api/content.py index 9d4c6d91..552afffd 100644 --- a/src/plone/api/content.py +++ b/src/plone/api/content.py @@ -25,7 +25,7 @@ import transaction import uuid -_marker = [] +_marker = object() # Maximum number of attempts to generate a unique random ID MAX_UNIQUE_ID_ATTEMPTS = 100 @@ -753,7 +753,7 @@ def iter_ancestors(obj=None, function=None, interface=None, stop_at=_marker): # # This is useful if we want to have an empty iterator when checking # for ancestors in the portal. - return iter(()) + yield from () chain = aq_chain(aq_inner(obj)) diff --git a/src/plone/api/portal.py b/src/plone/api/portal.py index 6d3f1b46..74e8bf98 100644 --- a/src/plone/api/portal.py +++ b/src/plone/api/portal.py @@ -170,11 +170,6 @@ def send_email( # formataddr probably got confused by special characters. sender = from_address - # If the mail headers are not properly encoded we need to extract - # them and let MailHost manage the encoding. - if isinstance(body, str): - body = body.encode(encoding) - host = get_tool("MailHost") host.send( body, diff --git a/src/plone/api/tests/test_portal.py b/src/plone/api/tests/test_portal.py index ac8124d7..e5bb0076 100644 --- a/src/plone/api/tests/test_portal.py +++ b/src/plone/api/tests/test_portal.py @@ -2,6 +2,7 @@ from datetime import date from datetime import datetime +from email import message_from_bytes from packaging import version from plone.api import content from plone.api import env @@ -25,14 +26,6 @@ import DateTime import unittest -try: - # Python 3 - from email import message_from_bytes -except ImportError: - # Python 2 - from email import message_from_string as message_from_bytes - - HAS_PLONE5 = version.parse(env.plone_version()) >= version.parse("5.0b2") diff --git a/src/plone/api/user.py b/src/plone/api/user.py index 2e93b98f..087a5783 100644 --- a/src/plone/api/user.py +++ b/src/plone/api/user.py @@ -438,9 +438,12 @@ def revoke_roles(username=None, user=None, obj=None, roles=None): if user is None: raise InvalidParameterError("User could not be found") - roles = set(roles) + if not isinstance(roles, (list, tuple)): + raise InvalidParameterError("Roles must be a list or a tuple of strings") - if "Anonymous" in roles or "Authenticated" in roles: + roles_set = set(roles) + + if "Anonymous" in roles_set or "Authenticated" in roles_set: raise InvalidParameterError inherit = True @@ -454,7 +457,7 @@ def revoke_roles(username=None, user=None, obj=None, roles=None): if role not in ["Anonymous", "Authenticated"] } - roles = list(actual_roles - roles) + roles = list(actual_roles - roles_set) if obj is None: user.setSecurityProfile(roles=roles) From 257aee32dc22c76a04c86dfb6fd6d83a18a38f26 Mon Sep 17 00:00:00 2001 From: ale-rt Date: Thu, 28 May 2026 13:35:59 +0200 Subject: [PATCH 2/3] fixup! Clean up --- src/plone/api/user.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/plone/api/user.py b/src/plone/api/user.py index 087a5783..4ddf4ebb 100644 --- a/src/plone/api/user.py +++ b/src/plone/api/user.py @@ -438,10 +438,12 @@ def revoke_roles(username=None, user=None, obj=None, roles=None): if user is None: raise InvalidParameterError("User could not be found") - if not isinstance(roles, (list, tuple)): - raise InvalidParameterError("Roles must be a list or a tuple of strings") - - roles_set = set(roles) + try: + roles_set = set(roles) + if not all(isinstance(role, str) for role in roles_set): + raise InvalidParameterError("Roles must be an iterable containing only strings") + except TypeError: + raise InvalidParameterError("Roles must be an iterable containing only strings") if "Anonymous" in roles_set or "Authenticated" in roles_set: raise InvalidParameterError From ef8dd610f1791c1de67f3809e4b8aa5d5943fa14 Mon Sep 17 00:00:00 2001 From: ale-rt Date: Thu, 28 May 2026 13:39:07 +0200 Subject: [PATCH 3/3] fixup! Clean up --- src/plone/api/user.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/plone/api/user.py b/src/plone/api/user.py index 4ddf4ebb..a82de89c 100644 --- a/src/plone/api/user.py +++ b/src/plone/api/user.py @@ -441,7 +441,9 @@ def revoke_roles(username=None, user=None, obj=None, roles=None): try: roles_set = set(roles) if not all(isinstance(role, str) for role in roles_set): - raise InvalidParameterError("Roles must be an iterable containing only strings") + raise InvalidParameterError( + "Roles must be an iterable containing only strings" + ) except TypeError: raise InvalidParameterError("Roles must be an iterable containing only strings")