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.
Completely changes the way the "from _ import _" statement to use relative importing
import builtins, pathed; builtins.__import__ = pathed.new_import
Restore "from" statement
builtins.__import__ = pathed.old_import
Relative Importing
import builtins, pathed
builtins.__import__ = pathed.new_import
from ....Destkop.new import *
# 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 importing
import directory.lambda
# this uses the normal import statement because
# there's no "from" keyword in the beginning
builtins.__import__ = pathed.old_import
# use the "from" keyword normally after this
Importing files, folders, and adding to paths should be easy
from pathed import cwd, importfile, importdir
# import file or directory to variable
name = importfile(cwd/'..'/'..'/'name.py')
dirname = importdir(cwd/'..'/'..')
path = cwd/2/3+'.txt' # accepts objects that can be converted into string
cwd.find(*.txt) # lists all text files in cwd
You 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 projects
from pathed import filedir
filedir/'..'/'path'/'to'/'file.txt'
Returns your current file directory as a str-like object
from pathed import filedir
print(filedir) # prints current file directory
Returns your current working directory as a str-like object
from pathed import cwd
print(cwd) # prints current working directory
Replaces the builtins._import_ statment, this allows for normal import syntax but with relative imports
Caveats:
- runs _init_.py if folder is imported
- runs _init_.py if file is in the same folder as _init_.py
- only the "from _ import _" statement is overidden
- only *.py files are imported
- directories are not recursively added
- if directories are added in the _init_.py file, directories are added to namespace
Dot notation:
- go up n-1 folders, with n representing the number of dots
from ......spicy import *
# goes up 5 folders then down one folder called spicy
from ......spicy.file import *
# import file.py from spicy folder
from .here import *
# imports file here.py from the same directory as file
# same as:
from here import *
# name of directory or file is needed
# this is NOT possible at the moment
from .... import jalapeño
# this just imports everthing from cwd
from . import bell
# this is the right way to do it
from .pepper_file import ghost_module
Parameters:
- path: str or str-like object with path to directory
- module: module that will have attributes appended to it
Returns file functions, classes, and global variables from a python file
from pathed import importfile
hard_to_import_file = importfile(cwd/'..'/'..'/'file.py')
Parameters:
- path: str or str-like object with path to directory
- module: module that will have attributes appended to it
Imports *.py files from directory
Returns class with attributes named after *.py files
from pathed import importdir
hard_to_import_dir = importdir(cwd/'..'/'..')
Parameters:
- *args: objects that can be turned into a string
- custom: boolean if True, will append args to root if False, will append args to current file directory
from pathed import Path
Path('a') # /path/to/filedir/a
Path('a', custom=True) # /a
# dir ops
Path.isdir()
Path.mkdir()
Path.rmdir()
Path.copydir()
# file ops
Path.isfile()
Path.mkfile()
Path.rmfile()
Path.copyfile()
# path ops
Path.branch()
Path.leaf()
Path.add()
Path.ls()
Path.up()
Path.find()
Path.string()
Path.exists()
Path.splitpath()
# additional ops
Path.write()
Path.read()
Path.readfast()
Path.move()
returns True if Path is a directory
from pathed import cwd
cwd.isdir() # returns True
makes a directory called Path, throws error if Path is already a directory
from pathed import cwd
cwd.add('new_directory').mkdir()
removes Path if Path is a directory
from pathed import cwd
new_dir = cwd/'new_directory'
new_dir.mkdir()
new_dir.rmdir()
copies Path to destination if Path is a directory, returns destination as Path
from pathed import cwd
a = cwd/'a'
b = cwd/'b'
a.copydir(b/'a')
# copies directory a and places into directory b
returns True if Path is a file
from pathed import cwd
cwd.isfile() # returns false
mkfile(data) writes data to Path, throws error if Path does not exist
mkfile(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 Path
from pathed import cwd
cwd.add('new.txt').mkfile('hello world')
removes Path if Path is a file
from pathed import cwd
textfile = cwd.add('new.txt')
textfile.mkfile('goodbye world')
textfile.rmfile()
copies Path to destination if Path is a file, returns destination as Path
from pathed import cwd
textfile = 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.txt
/absolute/path/to/leaf -> returns branch
from pathed import cwd
text_file = cwd.add('blank.txt').mkfile()
text_file.branch() # returns cwd
/absolute/path/to/leaf -> returns leaf
from pathed import cwd
text_file = cwd.add('blank.txt').mkfile()
text_file.branch() # returns 'blank.txt'
does the same thing as cwd/'path'/'to'/'wonderland'
from os import cwd
# These should give the same output
cwd.add('path').add('to').add('wonderland')
cwd/'path'/'to'/'wonderland'
returns [str, str, ...] of files and directories in Path
if full=True, returns [Path, Path, ...] of absolute Paths
throws error if Path doesn't exist
from pathed import cwd
cwd.ls() # lists files and directories in cwd
goes up the directory 'num' times
returns Path
from pathed import cwd
b = cwd/'a'/b'
b.up(1) # cwd/a
b.up(2) # cwd
find('*.py') returns [Path, Path, ...] in current Path that have the .py extension
find('**.py') returns [Path, Path, ...] in current Path and subdirectories that have the .py extension
from pathed import cwd
cwd.find(*.py) # returns list of *.py files
useful for printing raw Windows paths
\this\is\a\windows\path
returns True if the Path exists
from pathed import cwd
cwd.exists() # should return True
/absolute/path/to/leaf -> returns [branch, leaf]
print(branch) # /absolute/path/to print(leaf) # leaf
if full=True, returns [absolute, path, to, leaf]
from pathed import cwd
a = cwd/'a'
a.splitpath()
# returns ['path/to/cwd', 'a']
a.splitpath(full=True)
# returns ['path','to','cwd','a']
write(data) writes data to Path, throws error if Path does not exist
write(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 Path
from pathed import cwd
cwd.add('new.txt').write('hello world')
read() returns text of Path if Path is a file
read('rb') returns text of byte file if Path is a file
from pathed import cwd
textfile = cwd.add('new.txt')
textfile.mkfile('hello world')
textfile.read() # hello world
good for reading the first few of lines of a VERY LARGE file
returns generator for reading large files one line at a time
file_text = Path.readfast() next(file_text) to get string of next file, throws StopIteration Error at end of file
from pathed import cwd
textfile = cwd/'new.txt'
textfile.mkfile(data='hello world')
file_gen = textfile.readfast()
next(file_gen) # hello world
moves Path to destination, returns destination as Path
- Better documentation
- Unit tests