Here's this, which IIRC I never wrote tests for, which is what needs to be done to specify the correct behavior:

```python
def pathjoin(*args, **kwargs):
    """
    Arguments:
        args (list): *args list of paths
            if len(args) == 1, args[0] is not a string, and args[0] is iterable,
            set args to args[0].

    Basically::

        joined_path = u'/'.join(
            [args[0].rstrip('/')] +
            [a.strip('/') for a in args[1:-1]] +
            [args[-1].lstrip('/')])
    """
    log.debug('pathjoin: %r' % list(args))


    def _pathjoin(*args, **kwargs):
        len_ = len(args) - 1
        if len_ < 0:
            raise Exception('no args specified')
        elif len_ == 0:
            if not isinstance(args, basestring):
                if hasattr(args, '__iter__'):
                    _args = args
                    _args
                    args = args[0]
        for i, arg in enumerate(args):
            if not i:
                yield arg.rstrip('/')
            elif i == len_:
                yield arg.lstrip('/')
            else:
                yield arg.strip('/')
    joined_path = u'/'.join(_pathjoin(*args))
    return sanitize_path(joined_path)


def sanitize_path(path):
    # XXX TODO FIXME
    if '/../' in path:
        raise Exception()
    return path
```

 https://github.com/westurner/pgs/blob/master/pgs/app.py#L60-L95


On Mon, Jun 28, 2021, 04:09 Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl> wrote:
On Sun, Jun 27, 2021 at 09:55:34PM -0400, Wes Turner wrote:
> "[Python-ideas] Sanitize filename (path part) 2nd try"
> https://mail.python.org/archives/list/python-ideas@python.org/thread/LRIKMG3G4I4YQNK6BTU7MICHT7X67MEF/
>
> "[Python-ideas] Sanitize filename (path part)"
> https://mail.python.org/archives/list/python-ideas@python.org/thread/SQH4LPERFLKBLXPDUOVJMV24JBCBUCYO/
>
> ```quote
> What does sanitizepart do with a leading slash?
>
> assert os.path.join("a", "/b") == "/b"
>
> A new safejoin() or joinsafe() or join(safe='True') could call
> sanitizepart() such that:
>
> assert joinsafe("a\n", "/b") == "a\n/b"
> ```

Thanks for the links. "sanitizepart()" seems to be about *constructing*
a safe filename. It's a different problem and there's a thousand ways to
do it.

I think the idea with joinsafe() is similar to my idea... But I think
the req to disallow '..' is crucial. If we set the requirements as:

1. the resulting path must not be above the lhs arg
2. the operation must be done without actually accessing the fs

right now I see the proposed operation that rejects '..' as the best
approach.

Zbyszek