Package: pathed
Why pathed?Want to import a file that can't be accessed by "import"? Or a whole directory of files? This helps with that! Also, common path operations like find('*.txt'), rmfile, mkfile, read, and more are in the Path module. Tired of writing str(Path())? Try the Path module. Inspired by pathlib, os.path, shutil, and glob.One Liner for Relative ImportingCompletely changes the way the "from _ import _" statement to use relative importingimportbuiltins,pathed;builtins.__import__=pathed.new_importRestore "from" statementbuiltins.__import__ = pathed.old_importQuick Start On Normal ModulesRelative Importingimportbuiltins,pathedbuiltins.__import__=pathed.new_importfrom....Destkop.newimport*# imports classes, functions, and variables from new.py# new.py is up 3 directories, down 1 directory# MUST use the word "from" in order to do relative importingimportdirectory.lambda# this uses the normal import statement because# there's no "from" keyword in the beginningbuiltins.__import__=pathed.old_import# use the "from" keyword normally after thisImporting files, folders, and adding to paths should be easyfrompathedimportcwd,importfile,importdir# import file or directory to variablename=importfile(cwd/'..'/'..'/'name.py')dirname=importdir(cwd/'..'/'..')path=cwd/2/3+'.txt'# accepts objects that can be converted into stringcwd.find(*.txt)# lists all text files in cwdYou can also import an entire directory into the namespace. Convenient, but not really recommended.importfile(cwd/'..'/'..',sys.modules[__name__])importdir(cwd/'..'/'..',sys.modules[__name__])For pathing, I recommend using "filedir", the path to the current file directory, since cwd changes frequently within large projectsfrompathedimportfiledirfiledir/'..'/'path'/'to'/'file.txt'MethodsfiledirReturns your current file directory as a str-like objectfrompathedimportfiledirprint(filedir)# prints current file directorycwdReturns your current working directory as a str-like objectfrompathedimportcwdprint(cwd)# prints current working directorynew_import()Replaces the builtins._import_ statment, this allows for normal import syntax but with relative importsCaveats:runs _init_.py if folder is importedruns _init_.py if file is in the same folder as _init_.pyonly the "from _ import _" statement is overiddenonly *.py files are importeddirectories are not recursively addedif directories are added in the _init_.py file, directories are added to namespaceDot notation:go up n-1 folders, with n representing the number of dotsfrom......spicyimport*# goes up 5 folders then down one folder called spicyfrom......spicy.fileimport*# import file.py from spicy folderfrom.hereimport*# imports file here.py from the same directory as file# same as:fromhereimport*# name of directory or file is needed# this is NOT possible at the momentfrom....importjalapeño# this just imports everthing from cwdfrom.importbell# this is the right way to do itfrom.pepper_fileimportghost_moduleimportfile(path, module)Parameters:path: str or str-like object with path to directorymodule: module that will have attributes appended to itReturns file functions, classes, and global variables from a python filefrompathedimportimportfilehard_to_import_file=importfile(cwd/'..'/'..'/'file.py')importdir(path, module)Parameters:path: str or str-like object with path to directorymodule: module that will have attributes appended to itImports *.py files from directoryReturns class with attributes named after *.py filesfrompathedimportimportdirhard_to_import_dir=importdir(cwd/'..'/'..')Path(*args, custom)Parameters:*args: objects that can be turned into a stringcustom: boolean
if True, will append args to root
if False, will append args to current file directoryfrompathedimportPathPath('a')# /path/to/filedir/aPath('a',custom=True)# /aSummary of path operations# dir opsPath.isdir()Path.mkdir()Path.rmdir()Path.copydir()# file opsPath.isfile()Path.mkfile()Path.rmfile()Path.copyfile()# path opsPath.branch()Path.leaf()Path.add()Path.ls()Path.up()Path.find()Path.string()Path.exists()Path.splitpath()# additional opsPath.write()Path.read()Path.readfast()Path.move()Path.isdir()returns True if Path is a directoryfrompathedimportcwdcwd.isdir()# returns TruePath.mkdir()makes a directory called Path, throws error if Path is already a directoryfrompathedimportcwdcwd.add('new_directory').mkdir()Path.rmdir()removes Path if Path is a directoryfrompathedimportcwdnew_dir=cwd/'new_directory'new_dir.mkdir()new_dir.rmdir()Path.copydir(destination)copies Path to destination if Path is a directory, returns destination as Pathfrompathedimportcwda=cwd/'a'b=cwd/'b'a.copydir(b/'a')# copies directory a and places into directory bPath.isfile(path)returns True if Path is a filefrompathedimportcwdcwd.isfile()# returns falsePath.mkfile()mkfile(data) writes data to Path, throws error if Path does not existmkfile(data, 'w') write data, makes file if Path does not exist
mkfile(data, 'wb') writes bytes data to Path
mkfile(data, 'a') appends data to Pathfrompathedimportcwdcwd.add('new.txt').mkfile('hello world')Path.rmfile()removes Path if Path is a filefrompathedimportcwdtextfile=cwd.add('new.txt')textfile.mkfile('goodbye world')textfile.rmfile()Path.copyfile(destination)copies Path to destination if Path is a file, returns destination as Pathfrompathedimportcwdtextfile=cwd.add('a.txt')textfile.mkfile('hello world')textfile.copyfile(textfile/'..'/'b.txt')# copies a.txt and pastes it in the same directory as b.txtPath.branch()/absolute/path/to/leaf -> returns branchfrompathedimportcwdtext_file=cwd.add('blank.txt').mkfile()text_file.branch()# returns cwdPath.leaf()/absolute/path/to/leaf -> returns leaffrompathedimportcwdtext_file=cwd.add('blank.txt').mkfile()text_file.branch()# returns 'blank.txt'Path.add(*args)does the same thing as cwd/'path'/'to'/'wonderland'fromosimportcwd# These should give the same outputcwd.add('path').add('to').add('wonderland')cwd/'path'/'to'/'wonderland'Path.ls()returns [str, str, ...] of files and directories in Pathif full=True, returns [Path, Path, ...] of absolute Pathsthrows error if Path doesn't existfrompathedimportcwdcwd.ls()# lists files and directories in cwdPath.up(num)goes up the directory 'num' timesreturns Pathfrompathedimportcwdb=cwd/'a'/b'b.up(1)# cwd/ab.up(2)# cwdPath.find()find('*.py') returns [Path, Path, ...] in current Path that have the .py extensionfind('**.py') returns [Path, Path, ...] in current Path and subdirectories that have the .py extensionfrompathedimportcwdcwd.find(*.py)# returns list of *.py filesPath.string()useful for printing raw Windows paths\this\is\a\windows\pathPath.exists()returns True if the Path existsfrompathedimportcwdcwd.exists()# should return TruePath.splitpath()/absolute/path/to/leaf -> returns [branch, leaf]print(branch) # /absolute/path/to
print(leaf)   # leafif full=True, returns [absolute, path, to, leaf]frompathedimportcwda=cwd/'a'a.splitpath()# returns ['path/to/cwd', 'a']a.splitpath(full=True)# returns ['path','to','cwd','a']Path.write()write(data) writes data to Path, throws error if Path does not existwrite(data, 'w') write data, makes file if Path does not exist
write(data, 'wb') writes bytes data to Path
write(data, 'a') appends data to Pathfrompathedimportcwdcwd.add('new.txt').write('hello world')Path.read()read() returns text of Path if Path is a fileread('rb') returns text of byte file if Path is a filefrompathedimportcwdtextfile=cwd.add('new.txt')textfile.mkfile('hello world')textfile.read()# hello worldPath.readfast()good for reading the first few of lines of a VERY LARGE filereturns generator for reading large files one line at a timefile_text = Path.readfast()
next(file_text) to get string of next file, throws StopIteration Error at end of filefrompathedimportcwdtextfile=cwd/'new.txt'textfile.mkfile(data='hello world')file_gen=textfile.readfast()next(file_gen)# hello worldPath.move()moves Path to destination, returns destination as PathTODO:Better documentationUnit tests