def upload_tree(self, src, dst, ignore=None):
names = os.listdir(src)<EOL>if ignore is not None:<EOL><INDENT>ignored_names = ignore(src, names)<EOL><DEDENT>else:<EOL><INDENT>ignored_names = set()<EOL><DEDENT>try:<EOL><INDENT>self.conn.mkd(dst)<EOL><DEDENT>except error_perm:<EOL><INDENT>pass<EOL><DEDENT>errors = []<EOL>for name in names:<EOL><INDENT>if name in ignored_names:<EOL><INDENT>continue<EOL><DEDENT>src_name = os.path.join(src, name)<EOL>dst_name = os.path.join(dst, name)<EOL>try:<EOL><INDENT>if os.path.islink(src_name):<EOL><INDENT>pass<EOL><DEDENT>elif os.path.isdir(src_name):<EOL><INDENT>self.upload_tree(src_name, dst_name, ignore)<EOL><DEDENT>else:<EOL><INDENT>self.put(src_name, dst_name)<EOL><DEDENT><DEDENT>except Exception as why:<EOL><INDENT>errors.append((src_name, dst_name, str(why)))<EOL><DEDENT><DEDENT>return dst<EOL>
Recursively upload a directory tree.

        Although similar to shutil.copytree we don't follow symlinks.