Skip to content

Idea: allow traversing with pathlib semantics #1200

Description

@gforcada

In Zope/Plone we use traversal for almost everything:

root = somehow_get_root()
content = root.restrictedTraverse('and/now/get/some/content')

Wouldn't it be cool to be able to do instead:

root = somehow_get_root()
content = root / 'and' / 'now' / 'get' / 'some' / 'content'

✨

Activity

  1. davisagli commented on Mar 13, 2024

    @davisagli
    Member

    How is that better than root['and']['now']['get']['some']['content']? It's for sure less obvious.

  2. ale-rt commented on Mar 13, 2024

    @ale-rt
    Member

    Cool :)

    BTW it will be more convenient to do it like this:

    content = root / "and/now/get/some/content"

    See what we have in pathlib:

    >>> from pathlib import Path
    >>> Path("foo") / "bar/baz"
    PosixPath('foo/bar/baz')

    However, using restrictedTraverse and unrestrictedTraverse makes it clear the security implications.

    Will the / operator traverse the object in a restricted or unrestricted way?

    Theoretically, you could do:

    content_path = root / "and/now/get/some/content"
    content_path.restricted_get()
    content_path.unrestricted_get()

    With this it already starts to be less cool :D

  3. gforcada commented on Mar 14, 2024

    @gforcada
    MemberAuthor

    @davisagli less obvious is you already know that you can do dictionary-like traversing, but with all the rage of using pathlib everywhere (maybe I'm biased here 😓 ) and that Zope/Plone always use the metaphor of storing objects like folders and files, well, it makes it easier for onboarding IMHO

    @ale-rt good point on the (un)restricted that's not obvious at first sight... but maybe it could be a method of the object itself, i.e.:

    obj_path = root / 'my/deep/nested/obj'
    obj = obj_path.resolve()
    # vs
    obj = obj_path.unrestricted_resolve()

    So one thing could be constructing the path to the object, and once you have that you need to decide how you want to use it.

    Overriding the resolve method from upstream Python.

    If I keep dreaming about this, Pathlib already has the idea of pure paths (objects with everything but I/O operations) and specific paths that have the I/O operations.

    So, it would be a """"""matter"""""" of creating one such specific path meant for traversing a ZODB storage ✨

    I don't have any specific need to implement it myself, but I thought that as an idea it would be worth sharing it here 😊

  4. d-maurer commented on Mar 14, 2024

    @d-maurer
    Contributor
  5. davisagli commented on Mar 14, 2024

    @davisagli
    Member

    I like @d-maurer's idea best of the ones listed here, but I'm not sure that I would actually use it much. It's already pretty convenient to construct string paths using f-strings.

    Different topic, but something that I would use is an easier way to get the string path of a Zope object, instead of doing "/".join(obj.getPhysicalPath())

  6. d-maurer commented on Mar 14, 2024

    @d-maurer
    Contributor
  7. davisagli commented on Mar 14, 2024

    @davisagli
    Member

    @d-maurer Yep, absolute_url_path looks like what I want. I either wasn't aware of it or forgot. Thanks.

  8. gforcada commented on Apr 28, 2025

    @gforcada
    MemberAuthor

    As I got bitten by it:

    • getPhysicalPath() returns the path with the Plone id
    • absolute_url_path() returns the path without the Plone id

    So mind the difference if you want to compare paths to avoid duplicates as it happened to us 🤦🏾 😅

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions