Other things to make your life easier

Photons provides some other utilities inside photons_app.helpers. It is a Photons convention to import this module with the alias hp and access functionality from that:

from photons_app import helpers as hp


with hp.a_temp_file() as fle:
    fle.write(b"hello")
    fle.flush()

    with open(fle.name, "rb") as reopened:
        assert reopened.read() == b"hello"
photons_app.helpers.add_error(catcher, error)

Adds an error to an error_catcher.

This means if it’s callable we call it with the error and if it’s a list or set we add the error to it.

photons_app.helpers.a_temp_file()

Yield the name of a temporary file and ensure it’s removed after use

with hp.a_temp_file() as fle:
    fle.write("hello")
    fle.flush()
    os.system("cat {0}".format(fle.name))
photons_app.helpers.nested_dict_retrieve(data, keys, dflt)

Used to get a value deep in a nested dictionary structure

For example

data = {"one": {"two": {"three": "four"}}}

nested_dict_retrieve(data, ["one", "two", "three"], 6) == "four"

nested_dict_retrieve(data, ["one", "two"], 6) == {"three": "four"}

nested_dict_retrieve(data, ["one", "four"], 6) == 6
class photons_app.helpers.memoized_property(func)

Decorator to make a descriptor that memoizes it’s value

from photons_app import helpers as hp


class MyClass:
    @hp.memoized_property
    def thing(self):
        return expensive_operation()

obj = MyClass()

# Get us the result of expensive operation
print(obj.thing)

# And we get the result again but minus the expensive operation
print(obj.thing)

# We can set our own value
object.thing = "overridden"
assert object.thing == "overridden"

# And we can delete what is cached
del object.thing
assert object.thing == "<result from calling expensive_operation() again>"