def load(self, filename, create_if_missing=True):
        filename = Path(filename)
        if not filename.exists() and create_if_missing:
            self.load_pip_requirements()
            with filename.open("w") as f:
                f.write(yaml.dump(self.serialized, default_flow_style=False,
                                  encoding=None))
            self.filename = filename
            return self.save(filename)
        with filename.open() as f:
            for group, requirements in yaml.load(f.read()).items():
                for requirement in requirements:
                    self[group].add(Requirement.coerce(requirement))
        self.filename = filename
def cell_edited_callback(self, text_cell, path, new_text):
        """If a backend name is changed, it saves the changes in the Backend

        @param text_cell: not used. The Gtk.CellRendererText that emitted the
                          signal. Only here because it's passed by the signal
        @param path: the Gtk.TreePath of the edited cell
        @param new_text: the new name of the backend
        """
        # we strip everything not permitted in backend names
        new_text = ''.join(c for c in new_text if (c.isalnum() or c in [" ", "-", "_"]))
        selected_iter = self.liststore.get_iter(path)
        # update the backend name
        backend_id = self.liststore.get_value(selected_iter,
                                              self.COLUMN_BACKEND_ID)
        backend = self.dialog.get_requester().get_backend(backend_id)
        if backend:
            backend.set_human_name(new_text)
            # update the text in the liststore
            self.liststore.set(selected_iter, self.COLUMN_TEXT, new_text)