from allmydata.mutable.node import MutableFileNode
from allmydata.interfaces import IMutableFileNode, IDirectoryNode,\
IURI, IFileNode, IMutableFileURI, IFilesystemNode, \
- ExistingChildError, ICheckable, IDeepCheckable
+ ExistingChildError, NoSuchChildError, ICheckable, IDeepCheckable
from allmydata.checker_results import DeepCheckResults, \
DeepCheckAndRepairResults
from allmydata.monitor import Monitor
children = self.node._unpack_contents(old_contents)
if self.name not in children:
if self.must_exist:
- raise KeyError(self.name)
+ raise NoSuchChildError(self.name)
self.old_child = None
return None
self.old_child, metadata = children[self.name]
def modify(self, old_contents):
children = self.node._unpack_contents(old_contents)
+ if self.name not in children:
+ raise NoSuchChildError(self.name)
children[self.name] = (children[self.name][0], self.metadata)
new_contents = self.node._pack_contents(children)
return new_contents
def _get(self, children, name):
child = children.get(name)
if child is None:
- raise KeyError(name)
+ raise NoSuchChildError(name)
return child[0]
def _get_with_metadata(self, children, name):
child = children.get(name)
if child is None:
- raise KeyError(name)
+ raise NoSuchChildError(name)
return child
def get(self, name):
from twisted.cred import error, portal, checkers, credentials
from twisted.web.client import getPage
-from allmydata.interfaces import IDirectoryNode, ExistingChildError
+from allmydata.interfaces import IDirectoryNode, ExistingChildError, \
+ NoSuchChildError
from allmydata.immutable.download import ConsumerAdapter
from allmydata.immutable.upload import FileHandle
from allmydata.util import base32
return defer.succeed(node)
d = node.get(path[0])
def _maybe_create(f):
- f.trap(KeyError)
+ f.trap(NoSuchChildError)
return node.create_empty_directory(path[0])
d.addErrback(_maybe_create)
d.addCallback(self._get_or_create_directories, path[1:])
return d
def _convert_error(self, f):
- if f.check(KeyError):
+ if f.check(NoSuchChildError):
childname = f.value.args[0].encode("utf-8")
msg = "'%s' doesn't exist" % childname
raise ftp.FileNotFoundError(msg)
"""A directory node was asked to add or replace a child that already
exists, and overwrite= was set to False."""
+class NoSuchChildError(Exception):
+ """A directory node was asked to fetch a child which does not exist."""
+
class IDirectoryNode(IMutableFilesystemNode):
"""I represent a name-to-child mapping, holding the tahoe equivalent of a
directory. All child names are unicode strings, and all children are some
def get(name):
"""I return a Deferred that fires with a specific named child node,
either an IFileNode or an IDirectoryNode. The child name must be a
- unicode string."""
+ unicode string. I raise NoSuchChildError if I do not have a child by
+ that name."""
def get_metadata_for(name):
"""I return a Deferred that fires with the metadata dictionary for a
specific named child node. This metadata is stored in the *edge*, not
in the child, so it is attached to the parent dirnode rather than the
- child dir-or-file-node. The child name must be a unicode string."""
+ child dir-or-file-node. The child name must be a unicode string. I
+ raise NoSuchChildError if I do not have a child by that name."""
def set_metadata_for(name, metadata):
"""I replace any existing metadata for the named child with the new
stored in the *edge*, not in the child, so it is attached to the
parent dirnode rather than the child dir-or-file-node. I return a
Deferred (that fires with this dirnode) when the operation is
- complete."""
+ complete. I raise NoSuchChildError if I do not have a child by that
+ name."""
def get_child_at_path(path):
"""Transform a child path into an IDirectoryNode or IFileNode.
I perform a recursive series of 'get' operations to find the named
descendant node. I return a Deferred that fires with the node, or
- errbacks with IndexError if the node could not be found.
+ errbacks with NoSuchChildError if the node could not be found.
The path can be either a single string (slash-separated) or a list of
path-name elements. All elements must be unicode strings.
def delete(name):
"""I remove the child at the specific name. I return a Deferred that
fires when the operation finishes. The child name must be a unicode
- string."""
+ string. I raise NoSuchChildError if I do not have a child by that
+ name."""
def create_empty_directory(name, overwrite=True):
"""I create and attach an empty directory at the given name. The
is referenced by name. On the new parent, the child will live under
'new_child_name', which defaults to 'current_child_name'. TODO: what
should we do about metadata? I return a Deferred that fires when the
- operation finishes. The child name must be a unicode string."""
+ operation finishes. The child name must be a unicode string. I raise
+ NoSuchChildError if I do not have a child by that name."""
def build_manifest():
"""Return a Monitor. The Monitor's results will be a list of (path,
from allmydata.immutable import upload
from allmydata.interfaces import IURI, IClient, IMutableFileNode, \
INewDirectoryURI, IReadonlyNewDirectoryURI, IFileNode, \
- ExistingChildError, IDeepCheckResults, IDeepCheckAndRepairResults
+ ExistingChildError, NoSuchChildError, \
+ IDeepCheckResults, IDeepCheckAndRepairResults
from allmydata.util import hashutil, testutil
from allmydata.monitor import Monitor
from allmydata.test.common import make_chk_file_uri, make_mutable_file_uri, \
self.failUnless(u"child" in children)
d.addCallback(_check1)
d.addCallback(lambda res:
- self.shouldFail(KeyError, "get bogus", None,
+ self.shouldFail(NoSuchChildError, "get bogus", None,
dn.get, u"bogus"))
def _corrupt(res):
filenode = dn._node
["ctime", "mtime"]))
d.addCallback(lambda res:
- self.shouldFail(KeyError, "gcamap-no",
- "'nope'",
+ self.shouldFail(NoSuchChildError, "gcamap-no",
+ "nope",
n.get_child_and_metadata_at_path,
u"subdir/nope"))
d.addCallback(lambda res:
from allmydata.scripts import runner
from allmydata.interfaces import IDirectoryNode, IFileNode, IFileURI, \
ICheckerResults, ICheckAndRepairResults, IDeepCheckResults, \
- IDeepCheckAndRepairResults
+ IDeepCheckAndRepairResults, NoSuchChildError
from allmydata.monitor import Monitor, OperationCancelledError
from allmydata.mutable.common import NotMutableError
from allmydata.mutable import layout as mutable_layout
d1.addCallback(lambda res: self.shouldFail2(NotMutableError, "set_uri(nope)", None, dirnode.set_uri, u"hopeless", self.uri))
- d1.addCallback(lambda res: self.shouldFail2(KeyError, "get(missing)", "'missing'", dirnode.get, u"missing"))
+ d1.addCallback(lambda res: self.shouldFail2(NoSuchChildError, "get(missing)", "missing", dirnode.get, u"missing"))
personal = self._personal_node
d1.addCallback(lambda res: self.shouldFail2(NotMutableError, "mv from readonly", None, dirnode.move_child_to, u"mydata992", personal, u"nope"))
from allmydata.util import base32
from allmydata.uri import from_string_dirnode
from allmydata.interfaces import IDirectoryNode, IFileNode, IMutableFileNode, \
- ExistingChildError
+ ExistingChildError, NoSuchChildError
from allmydata.monitor import Monitor
from allmydata.web.common import text_plain, WebError, \
IClient, IOpHandleTable, NeedOperationHandleError, \
t = get_arg(req, "t", "").strip()
if isinstance(node_or_failure, Failure):
f = node_or_failure
- f.trap(KeyError)
+ f.trap(NoSuchChildError)
# No child by this name. What should we do about it?
if DEBUG: print "no child", name
if DEBUG: print "postpath", req.postpath
return defer.succeed(node)
d = node.get(path[0])
def _maybe_create(f):
- f.trap(KeyError)
+ f.trap(NoSuchChildError)
return node.create_empty_directory(path[0])
d.addErrback(_maybe_create)
d.addCallback(self._get_or_create_directories, path[1:])
def _maybe_got_node(node_or_failure):
if isinstance(node_or_failure, Failure):
f = node_or_failure
- f.trap(KeyError)
+ f.trap(NoSuchChildError)
# create a placeholder which will see POST t=upload
return PlaceHolderNodeHandler(self.node, name)
else: