[Python-Dev] Unipath package
Michael Foord
fuzzyman at voidspace.org.uk
Sun Jan 28 17:07:32 CET 2007
Mike Orr wrote:
> I finally finished my path package (Unipath) and put it in the Cheeseshop.
> http://sluggo.scrapping.cc/python/unipath/
>
Hello Mike,
Looking through the docs it looks like a great package. However, didn't
Guido (on this list anyway) rule that he wouldn't accept a solution
which subclassed a string type?
Michael Foord
> There's a Path class for pathname calculations, and a FSPath subclass
> for filesystem calls. I'm hoping Path -- or something resembling it
> -- will find its way into os.path in Python 2.6 or 3.0. FSPath is
> full of convenience methods so it may not be everybody's cup of tea,
> but perhaps something similar can go into Python in the farther future
>
> Unipath is an early alpha release so the API may change as it gets
> more real-world use. There's an extensive unittest suite, which
> passes on Python 2.5 and 2.4.4 on Linux. Windows and Macintosh
> testers are needed.
>
> Following are highlights from the python-3000 discussion and deviations from it:
>
> - Path subclasses unicode, or str if the platform can't handle
> Unicode pathnames.
>
> - FSPath subclasses Path. This allows you to do "from unipath import
> FSPath as Path" and pretend there's only one class. I find this much
> more convenient in applications, so you don't have to cast objects
> back and forth between the classes. Also, it just became infeasable
> not to let them inherit, because so many methods call other methods.
>
> - Nevertheless, you can use Path alone and rest assured it will never
> touch the filesystem. You can even use Path objects with os.*
> functions if you are so heretically inclined. If Path is accepted
> into the stdlib, FSPath will inherit it from there.
>
> - I tried splitting FSPath into several mixins according to type of
> operation, but the need for methods to call other methods in a
> different category sabotaged that too. So FSPath proudly has about
> fifty methods. (Path has 10 public methods and 4 properties.)
>
> - The dirname property is called .parent. The basename property is
> .name. The extension property is .ext. The name without extension is
> .stem.
>
> - .components() returns a list of directory components. The first
> component is "/", a Windows drive root, a UNC share, or "" for a
> relative path. .split_root() returns the root and the rest.
>
> - PosixPath, NTPath, and MacPath are Path subclasses using a specific
> path library. This allows you to express non-native paths and convert
> paths. Passing a relative foreign path to a *Path constructor
> converts it to the destination type. Passing an absolute foreign path
> is an error, because there's no sane way to interpret "C:\\" on Posix
> or "/" on Windows. I'm skeptical whether this non-native support is
> really worth it, because .norm() and .norm_case() already convert
> slashes to backslashes (which is what Talin really wanted to do --
> have Posix paths in a config file and automatically convert them to
> the native format). And if Python is going to drop Mac OS 9 soon then
> MacPath is obsolete. So maybe this non-native path code will prove
> less than useful and will be deleted. On the other hand, if someone
> is burning to write a zippath or ftppath library, you can use it with
> this.
>
> - Setting Path.auto_norm to true will automatically normalize all
> paths on construction. I'm not sure if this should be the default,
> because normalizing may produce the wrong path (e.g., if it contains a
> symlink). You can always pass norm=True or norm=False to the
> constructor to enable/disable it.
>
> - p.child("subdir", "grandkid") is Glyph's favorite "safe join" method
> that prevents creating a path pointing above 'p'. You can use it as a
> .joinpath if you don't mind this restriction. The constructor allows
> multiple positional arguments, which are joined using os.path.join().
>
> - Listing is p.listdir(pattern=None, filter=None, names_only=False).
> This returns a non-recursive list of paths. If 'names_only' is true
> it returns the same as os.listdir(). p.walk(pattern=None,
> filter=None, top_down=True) is the recursive counterpart, yielding
> paths. In both cases 'pattern' is a glob pattern, and 'filter' is one
> of the constants (FILES, DIRS, LINKS, FILES_NO_LINKS, DIRS_NO_LINKS,
> DEAD_LINKS) or a custom boolean function. I spent a lot of time going
> back and forth between Orendorff's six listing methods and Raphael's
> one, and finally decided on this, partly because I'm not satisfied
> with how either Orendorff's class or Raphael's or os.walk() handle
> symlinks -- sometimes you want to ignore the links and then iterate
> them separately.
>
> - .read_file(mode) and .write_file(content, mode) are a compromise
> between Orendorff's seven methods and purists' desire for zero
> methods.
>
> - .mkdir(), .rmdir(), .rmtree(), .copy(), .copy_stat(), .copy_tree(),
> and .move() are more fancy than their stdlib/Orendorff counterparts.
> They silently succeed if the operation is already done, and have
> arguments to smartly create/delete intermediate directories, etc.
>
> - Two extra functions are in 'unipath.tools'. 'dict2dir' creates a
> directory hierarchy modeled after a dict. 'dump_path' displays an
> ASCII tree of a directory hierarchy, with file sizes and symlink
> targets showing.
>
> Enjoy! and please provide feedback.
>
> --Mike Orr <sluggoster at gmail.com>
> _______________________________________________
> Python-Dev mailing list
> Python-Dev at python.org
> http://mail.python.org/mailman/listinfo/python-dev
> Unsubscribe: http://mail.python.org/mailman/options/python-dev/fuzzyman%40voidspace.org.uk
>
>
More information about the Python-Dev
mailing list