Fixed existing doctests, added some new ones, enabled doctests in nosetests

(cherry picked from commit 02c3bf8)
This commit is contained in:
Gina Häußge 2015-10-22 12:34:53 +02:00
parent 2a8e084b51
commit 91163dc4f4
4 changed files with 40 additions and 69 deletions

View file

@ -6,4 +6,4 @@ python:
install:
- pip install -e .[develop]
script:
- nosetests tests/
- nosetests --with-doctest

View file

@ -584,24 +584,6 @@ class LocalFileStorage(StorageInterface):
Note that for a ``path`` without a trailing slash the last part will be considered a file name and
hence be returned at second position. If you only need to convert a folder path, be sure to
include a trailing slash for a string ``path`` or an empty last element for a list ``path``.
Examples::
>>> storage = LocalFileStorage("/some/base/folder")
>>> storage.sanitize("some/folder/and/some file.gco")
("/some/base/folder/some/folder/and", "some_file.gco")
>>> storage.sanitize(("some", "folder", "and", "some file.gco"))
("/some/base/folder/some/folder/and", "some_file.gco")
>>> storage.sanitize("some file.gco")
("/some/base/folder", "some_file.gco")
>>> storage.sanitize(("some file.gco",))
("/some/base/folder", "some_file.gco")
>>> storage.sanitize("")
("/some/base/folder", "")
>>> storage.sanitize("some/folder/with/trailing/slash/")
("/some/base/folder/some/folder/with/trailing/slash", "")
>>> storage.sanitize("some", "folder", "")
("/some/base/folder/some/folder", "")
"""
name = None
if isinstance(path, (str, unicode, basestring)):
@ -628,24 +610,6 @@ class LocalFileStorage(StorageInterface):
Raises a :class:`ValueError` for a ``name`` containing ``/`` or ``\``. Otherwise strips any characters from the
given ``name`` that are not any of the ASCII characters, digits, ``-``, ``_``, ``.``, ``(``, ``)`` or space and
replaces and spaces with ``_``.
Examples::
>>> storage = LocalFileStorage("/some/base/folder")
>>> storage.sanitize_name("some_file.gco")
"some_file.gco"
>>> storage.sanitize_name("some_file with (parentheses) and ümläuts and digits 123.gco")
"some_file_with_(parentheses)_and_mluts_and_digits_123.gco"
>>> storage.sanitize_name("pengüino pequeño.stl")
"pengino_pequeo.stl"
>>> storage.sanitize_name("some/folder/still/left.gco")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: name must not contain / or \
>>> storage.sanitize_name("also\\no\\backslashes.gco")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: name must not contain / or \
"""
if name is None:
return None
@ -664,22 +628,6 @@ class LocalFileStorage(StorageInterface):
Ensures that the on disk representation of ``path`` is located under the configured basefolder. Resolves all
relative path elements (e.g. ``..``) and sanitizes folder names using :func:`sanitize_name`. Final path is the
absolute path including leading ``basefolder`` path.
Examples::
>>> storage = LocalFileStorage("/some/base/folder")
>>> storage.sanitize_path("folder/with/subfolder")
"/some/base/folder/folder/with/subfolder"
>>> storage.sanitize_path("folder/with/subfolder/../other/folder")
"/some/base/folder/folder/with/other/folder"
>>> storage.sanitize_path("/folder/with/leading/slash")
"/some/base/folder/folder/with/leading/slash"
>>> storage.sanitize_path(".folder/with/leading/dot")
"/some/base/folder/folder/with/leading/dot
>>> storage.sanitize_path("../../folder/out/of/the/basefolder")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: path not contained in base folder: /some/folder/out/of/the/basefolder
"""
if path[0] == "/" or path[0] == ".":
path = path[1:]

View file

@ -12,7 +12,7 @@ import re
import logging
from octoprint.settings import settings
from octoprint.util import dict_merge, dict_clean, dict_contains_keys
from octoprint.util import dict_merge, dict_sanitize, dict_contains_keys
class SaveError(Exception):
pass
@ -214,7 +214,7 @@ class PrinterProfileManager(object):
identifier = self._sanitize(identifier)
profile["id"] = identifier
profile = dict_clean(profile, self.__class__.default)
profile = dict_sanitize(profile, self.__class__.default)
if identifier == "_default":
default_profile = dict_merge(self._load_default(), profile)

View file

@ -378,6 +378,14 @@ def dict_merge(a, b):
Taken from https://www.xormedia.com/recursively-merge-dictionaries-in-python/
Example::
>>> a = dict(foo="foo", bar="bar", fnord=dict(a=1))
>>> b = dict(foo="other foo", fnord=dict(b=2, l=["some", "list"]))
>>> expected = dict(foo="other foo", bar="bar", fnord=dict(a=1, b=2, l=["some", "list"]))
>>> dict_merge(a, b) == expected
True
Arguments:
a (dict): The dictionary to merge ``b`` into
b (dict): The dictionary to merge into ``a``
@ -399,14 +407,24 @@ def dict_merge(a, b):
return result
def dict_clean(a, b):
def dict_sanitize(a, b):
"""
Recursively deep-cleans ``b`` from ``a``, removing all keys and corresponding values from ``a`` that appear in
``b``.
Recursively deep-sanitizes ``a`` based on ``b``, removing all keys (and
associated values) from ``a`` that do not appear in ``b``.
Example::
>>> a = dict(foo="foo", bar="bar", fnord=dict(a=1, b=2, l=["some", "list"]))
>>> b = dict(foo=None, fnord=dict(a=None, b=None))
>>> expected = dict(foo="foo", fnord=dict(a=1, b=2))
>>> dict_sanitize(a, b) == expected
True
>>> dict_clean(a, b) == expected
True
Arguments:
a (dict): The dictionary to clean from ``b``.
b (dict): The dictionary to clean ``b`` from.
a (dict): The dictionary to clean against ``b``.
b (dict): The dictionary containing the key structure to clean from ``a``.
Results:
dict: A new dict based on ``a`` with all keys (and corresponding values) found in ``b`` removed.
@ -421,21 +439,26 @@ def dict_clean(a, b):
if not k in b:
del result[k]
elif isinstance(v, dict):
result[k] = dict_clean(v, b[k])
result[k] = dict_sanitize(v, b[k])
else:
result[k] = deepcopy(v)
return result
dict_clean = deprecated("dict_clean has been renamed to dict_sanitize",
includedoc="Replaced by :func:`dict_sanitize`")(dict_sanitize)
def dict_contains_keys(a, b):
def dict_contains_keys(keys, dictionary):
"""
Recursively deep-checks if ``a`` contains all keys found in ``b``.
Recursively deep-checks if ``dictionary`` contains all keys found in ``keys``.
Example::
>>> dict_contains_keys(dict(foo="bar", fnord=dict(a=1, b=2, c=3)), dict(foo="some_other_bar", fnord=dict(b=100)))
>>> positive = dict(foo="some_other_bar", fnord=dict(b=100))
>>> negative = dict(foo="some_other_bar", fnord=dict(b=100, d=20))
>>> dictionary = dict(foo="bar", fnord=dict(a=1, b=2, c=3))
>>> dict_contains_keys(positive, dictionary)
True
>>> dict_contains_keys(dict(foo="bar", fnord=dict(a=1, b=2, c=3)), dict(foo="some_other_bar", fnord=dict(b=100, d=20)))
>>> dict_contains_keys(negative, dictionary)
False
Arguments:
@ -446,14 +469,14 @@ def dict_contains_keys(a, b):
boolean: True if all keys found in ``b`` are also present in ``a``, False otherwise.
"""
if not isinstance(a, dict) or not isinstance(b, dict):
if not isinstance(keys, dict) or not isinstance(dictionary, dict):
return False
for k, v in a.iteritems():
if not k in b:
for k, v in keys.iteritems():
if not k in dictionary:
return False
elif isinstance(v, dict):
if not dict_contains_keys(v, b[k]):
if not dict_contains_keys(v, dictionary[k]):
return False
return True