Skip to main content

File Or Name

Project description

File Or Name

PyPi Version Actions Status Code style: black

Transparently handle input parameters that are either strings or pre-opened file objects.

Why?

when writing a function that reads or writes data to a file you often end up with something that looks like this

def read_my_cool_file(file_name):
    with open(file_name) as f:
        # Process file object f
        ...

This has some problems.

  1. It couples your data processing code and the opening of the file. This makes it harder to test. You only want to test your code that processes the data but with functions like this you need to coordinate the opening of the file during you test, either creating fake data on disk or patching the open call.
  2. It can't handle special files. If you have file in your special format but it uses latin-1 encoding instead of ascii how can you use that file? You can't because you are opening the file in function instead of passing the file object in you are forced to open it in one way.

For maximum flexibility and easy testability you probably actually want a function that looks like this

def read_my_cool_file(f):
    # Process file object f
    ...

This is nice because when testing you can use things like the io.StringIO objects to dynamically create test data. You can also open files with different encodings and pass them in to get processed just like normal. There is a usability draw back though. This way of processing files is onerous on the user. It turns single function calls into multi-line calls. This

data = read_my_cool_file("/path/to/my/imporant/data")

into this

with open("/path/to/my/important/data") as f:
    data = read_my_cool_file(f)

It also is a divergence from a lot of other functions they probably use, forcing the user to do things differently for your library is hard for them and could result in them not using your code.

We need a way to accept both file paths (as strings) and file objects without having to write code to check which it is for every io function we write.

What?

Enter file_or_name.

file_or_name introduces a decorator file_or_name that solves this issue.

By decorating a function with @file_or_name we can accept both strings and file objects. Our example above becomes

@file_or_name
def read_my_cool_file(f):
    # Process file object f
    ...

As writer of the function we can write functions that assume they get a file object and input. This means we can stop opening files as functions it makes it easier to test.

As a user we can pass in either a string making the function easy to call or we can pass in a file object which lets us handle files with other encodings.

Usage

The @file_or_name decorator will open and close files automatically for you when your function takes a file. If you use the decorator with no arguments it will open the first argument as a file in read mode.

@file_or_name
def read_json(f):
    return json.load(f)

In order to handle multiple files as well as writing use keyword arguments to the decorator in the form parameter=mode. This will open a file using the value of parameter as a file in the specified mode.

Writing to file example:

@file_or_name(wf='w')
def write_json(data, wf):
    json.dumps(data, wf, indent=2)

Reading and writing example:

@file_or_name(rf='r', wf='w')
def convert_jsonl_to_yaml(rf, wf):
    for line in rf:
        wf.write(yaml.dump(json.loads(line)) + "\n")

File or Name lets you the library develop write function that operate on files object making code cleaner and more testable while letting your users interact with your code using simple file path string arguments.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

file-or-name-1.0.0.tar.gz (5.2 kB view details)

Uploaded Source

File details

Details for the file file-or-name-1.0.0.tar.gz.

File metadata

  • Download URL: file-or-name-1.0.0.tar.gz
  • Upload date:
  • Size: 5.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.1.1 pkginfo/1.5.0.1 requests/2.22.0 setuptools/42.0.2 requests-toolbelt/0.9.1 tqdm/4.41.0 CPython/3.7.6

File hashes

Hashes for file-or-name-1.0.0.tar.gz
Algorithm Hash digest
SHA256 504869c26dbd7f2b2388e5cbf839ae67ff6f7a1902521e73508111744b9573bc
MD5 00437e82223ea8fc9e52f70eb52abcec
BLAKE2b-256 0e1a49e84f206448301bfc6ad9185b10adf0645ac08e89b68276ae8eadc70c80

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page