Ejemplo n.º 1
0
def grep(item, path, debug, **kwargs):
    """
    Deep Grep Commandline

    Grep through the contents of a file and find the path to the item.
    It can read csv, tsv, json, yaml, and toml files.

    """
    kwargs['case_sensitive'] = not kwargs.pop('ignore_case')
    kwargs['match_string'] = kwargs.pop('exact_match')

    try:
        content = load_path_content(path)
    except Exception as e:  # pragma: no cover.
        if debug:  # pragma: no cover.
            raise  # pragma: no cover.
        else:  # pragma: no cover.
            sys.exit(
                str(f"Error when loading {path}: {e}"))  # pragma: no cover.

    try:
        result = DeepSearch(content, item, **kwargs)
    except Exception as e:  # pragma: no cover.
        if debug:  # pragma: no cover.
            raise  # pragma: no cover.
        else:  # pragma: no cover.
            sys.exit(str(f"Error when running deep search on {path}: {e}")
                     )  # pragma: no cover.
    pprint(result, indent=2)
Ejemplo n.º 2
0
    def _validation_context(self,
                            instance: JSON,
                            ignore_in_doc_refs: bool = False):
        """
        A context manager for building up and tearing down configuration for
        a running our custom validator on a given instance.
        """
        self._ignore_in_doc_refs = ignore_in_doc_refs
        self._in_doc_refs_cache = dict()

        # Build the in_doc_refs_cache if we're not ignoring in_doc_refs
        if not ignore_in_doc_refs:
            search = DeepSearch(self.schema, "in_doc_ref_pattern")
            if "matched_paths" in search:
                for path in search["matched_paths"]:
                    scope = {"root": self.schema}
                    exec(f"ref_path_pattern = {path}", scope)
                    ref_path_pattern = scope["ref_path_pattern"]
                    # If there are no cached values for this ref path pattern, collect them
                    if ref_path_pattern not in self._in_doc_refs_cache:
                        self._in_doc_refs_cache[
                            ref_path_pattern] = self._get_values_for_path_pattern(
                                ref_path_pattern, instance)

        # see: https://docs.python.org/3/library/contextlib.html
        try:
            yield
        finally:
            self._in_doc_refs_cache = None
Ejemplo n.º 3
0
 def test_string_in_dictionary_key_case_insensitive_partial(self):
     obj = {"SOMEWHERE here": "around"}
     result = {
         'matched_paths': {"root['SOMEWHERE here']"}
     }
     ds = DeepSearch(obj, item, verbose_level=1, case_sensitive=False)
     self.assertEqual(ds, result)
Ejemplo n.º 4
0
    def test_loop_in_lists(self):
        obj = [1, 2, 'somewhere']
        obj.append(obj)

        ds = DeepSearch(obj, item, verbose_level=1)
        result = {'matched_values': {'root[2]'}}
        assert ds == result
Ejemplo n.º 5
0
 def test_skip_path1(self):
     obj = {
         "for life": "vegan",
         "ingredients": ["no meat", "no eggs", "no dairy", "somewhere"]
     }
     ds = DeepSearch(obj, item, exclude_paths={"root['ingredients']"})
     assert ds == {}
Ejemplo n.º 6
0
def _get_uuid_path_map(ct: dict) -> dict:
    """
    Build a dictionary mapping upload placeholder UUIDs to a `deepdiff`-style
    path to that artifact in the `ct` clinical trial metadata dictionary. This
    will look something like:
    ```python
    {
        "uuuu-uuuu-iiii-dddd": "root['path']['to']['upload_placeholder']",
        ...
    }
    ```
    """
    def get_uuid_for_path(path: str):
        # Spooky stuff: `exec` executes the string provided as its first argument as
        # python code in a context populated with the global variables defined by
        # the dictionary passed as its second argument. Since `path` looks like
        # "root['path']['to']['upload_placeholder']", the following code looks up
        # the UUID associated with `path` in the `ct` dict, whose value is assigned
        # to "root" in the scope provided to `exec`, and stores that UUID in `scope['uuid']`.
        scope = {"root": ct}
        exec(f"uuid = {path}", scope)
        return scope["uuid"]

    return {
        get_uuid_for_path(path): path
        for path in DeepSearch(ct, "upload_placeholder")["matched_paths"]
    }
Ejemplo n.º 7
0
 def test_string_in_dictionary_case_insensitive(self):
     obj = {"long": "Somewhere over there!", "string": 2, 0: 0, "SOMEWHERE": "around"}
     result = {
         'matched_paths': {"root['SOMEWHERE']"},
         'matched_values': {"root['long']"}
     }
     ds = DeepSearch(obj, item, verbose_level=1, case_sensitive=False)
     self.assertEqual(ds, result)
Ejemplo n.º 8
0
    def test_bad_attribute(self):
        class Bad:
            __slots__ = ['x', 'y']

            def __getattr__(self, key):
                raise AttributeError("Bad item")

            def __str__(self):
                return "Bad Object"

        obj = Bad()

        ds = DeepSearch(obj, item, verbose_level=1)
        result = {'unprocessed': ['root']}
        assert ds == result
        ds = DeepSearch(obj, item, verbose_level=2)
        assert ds == result
Ejemplo n.º 9
0
 def test_string_in_dictionary(self):
     obj = {"long": "somewhere", "string": 2, 0: 0, "somewhere": "around"}
     result = {
         'matched_paths': {"root['somewhere']"},
         'matched_values': {"root['long']"}
     }
     ds = DeepSearch(obj, item, verbose_level=1)
     assert ds == result
Ejemplo n.º 10
0
 def test_named_tuples_verbose(self):
     from collections import namedtuple
     Point = namedtuple('Point', ['x', 'somewhere_good'])
     obj = Point(x="my keys are somewhere", somewhere_good=22)
     ds = DeepSearch(obj, item, verbose_level=2)
     result = {'matched_values': {'root.x': 'my keys are somewhere'},
               'matched_paths': {'root.somewhere_good': 22}}
     self.assertEqual(ds, result)
Ejemplo n.º 11
0
 def test_regex_in_string_in_dictionary(self):
     obj = {"long": "somewhere", "string": 2, 0: 0, "somewhere": "around"}
     result = {
         "matched_paths": {"root['somewhere']"},
         "matched_values": {"root['long']"},
     }
     item = "some.*"
     ds = DeepSearch(obj, item, verbose_level=1, use_regexp=True)
     assert ds == result
Ejemplo n.º 12
0
 def test_string_in_list_verbose3(self):
     obj = ["long somewhere", "string", 0, "somewhere great!"]
     result = {
         "matched_values": {
             'root[0]': 'long somewhere',
             'root[3]': "somewhere great!"
         }
     }
     assert DeepSearch(obj, item, verbose_level=2) == result
Ejemplo n.º 13
0
 def test_regex_in_int_in_dictionary(self):
     obj = {"long": "somewhere", "num": 232, 0: 0, "somewhere": "around"}
     item = "2.*"
     result = {"matched_values": {"root['num']"}}
     ds = DeepSearch(obj,
                     item,
                     verbose_level=1,
                     use_regexp=True,
                     strict_checking=False)
     assert ds == result
Ejemplo n.º 14
0
    def test_search_inherited_attributes(self):
        class Parent:
            a = 1

        class Child(Parent):
            b = 2

        obj = Child()
        item = 1
        result = {'matched_values': {'root.a'}}
        assert DeepSearch(obj, item, verbose_level=1) == result
Ejemplo n.º 15
0
    def test_loop(self):
        class LoopTest:
            def __init__(self, a):
                self.loop = self
                self.a = a

        obj = LoopTest("somewhere around here.")

        ds = DeepSearch(obj, item, verbose_level=1)
        result = {'matched_values': {'root.a'}}
        assert ds == result
Ejemplo n.º 16
0
    def test_keep_searching_after_obj_match(self):
        class AlwaysEqual:
            def __init__(self, recurse=True):
                if recurse:
                    self.some_attr = AlwaysEqual(recurse=False)

            def __eq__(self, other):
                return True

        obj = AlwaysEqual()
        item = AlwaysEqual()
        result = {'matched_values': {'root', 'root.some_attr'}}
        assert DeepSearch(obj, item, verbose_level=1) == result
Ejemplo n.º 17
0
    def test_regex_in_named_tuples_verbose(self):
        from collections import namedtuple

        Point = namedtuple("Point", ["x", "somewhere_good"])
        obj = Point(x="my keys are somewhere", somewhere_good=22)
        item = "some.*"
        ds = DeepSearch(obj, item, verbose_level=2, use_regexp=True)
        result = {
            "matched_values": {
                "root.x": "my keys are somewhere"
            },
            "matched_paths": {
                "root.somewhere_good": 22
            },
        }
        assert ds == result
Ejemplo n.º 18
0
 def test_int_cant_become_regex(self):
     obj = {
         "long": "somewhere",
         "num": "1123456",
         0: 0,
         "somewhere": "around"
     }
     item = CustomClass(a=10)
     with pytest.raises(TypeError) as exp:
         DeepSearch(obj,
                    item,
                    verbose_level=1,
                    use_regexp=True,
                    strict_checking=False)
     assert str(exp.value).startswith(
         "The passed item of (10, None) is not usable for regex")
Ejemplo n.º 19
0
def search_in(obj, item, **kwargs):
    if isinstance(obj, dict):
        obj = obj
    else:
        try:
            obj = json.loads(obj)
        except (JSONDecodeError, TypeError) as error:
            raise JsonCompareError(f"Only VALID JSON strings accepted! ERROR: {error}")
    logger.debug(f"OBJ: {obj}")
    logger.debug(f"ITEM: {item}")
    logger.debug(f"KWARGS: {kwargs}")

    ds = DeepSearch(obj, item, verbose_level=2, **kwargs)
    logger.debug(f"DS: {type(ds)}")
    print(ds)
    return ds
Ejemplo n.º 20
0
 def test_string_in_dictionary_in_list_verbose(self):
     obj = [
         "something somewhere", {
             "long": "somewhere",
             "string": 2,
             0: 0,
             "somewhere": "around"
         }
     ]
     result = {
         'matched_paths': {
             "root[1]['somewhere']": "around"
         },
         'matched_values': {
             "root[1]['long']": "somewhere",
             "root[0]": "something somewhere"
         }
     }
     ds = DeepSearch(obj, item, verbose_level=2)
     assert ds == result
Ejemplo n.º 21
0
 def test_none(self):
     obj = item = None
     result = {'matched_values': {'root'}}
     assert DeepSearch(obj, item, verbose_level=1) == result
Ejemplo n.º 22
0
 def test_number_in_list(self):
     obj = ["a", 10, 20]
     item = 10
     result = {"matched_values": {'root[1]'}}
     assert DeepSearch(obj, item, verbose_level=1) == result
Ejemplo n.º 23
0
 def test_int_in_dictionary(self):
     obj = {"long": "somewhere", "num": 2, 0: 0, "somewhere": "around"}
     item = 2
     result = {'matched_values': {"root['num']"}}
     ds = DeepSearch(obj, item, verbose_level=1)
     assert ds == result
Ejemplo n.º 24
0
 def test_unknown_parameters(self):
     with pytest.raises(ValueError):
         DeepSearch(1, 1, wrong_param=2)
Ejemplo n.º 25
0
 def test_string_in_list(self):
     obj = ["long", "string", 0, "somewhere"]
     result = {"matched_values": {'root[3]'}}
     assert DeepSearch(obj, item, verbose_level=1) == result
Ejemplo n.º 26
0
 def test_string_in_root_verbose(self):
     obj = "long string somewhere"
     result = {"matched_values": {'root': "long string somewhere"}}
     assert DeepSearch(obj, item, verbose_level=2) == result
Ejemplo n.º 27
0
 def test_case_sensitive_of_str_in_list(self):
     obj = ["a", "bb", "BBC", "aBbB"]
     item = "BB"
     result = {"matched_values": {'root[2]'}}
     assert DeepSearch(obj, item, verbose_level=1,
                       case_sensitive=True) == result
Ejemplo n.º 28
0
 def test_case_sensitive_of_str_in_one_liner(self):
     obj = "Hello, what's up?"
     item = "WHAT"
     result = {}
     assert DeepSearch(obj, item, verbose_level=1,
                       case_sensitive=True) == result
Ejemplo n.º 29
0
 def test_complex_obj(self):
     obj = datetime(2017, 5, 4, 1, 1, 1)
     item = datetime(2017, 5, 4, 1, 1, 1)
     result = {'matched_values': {'root'}}
     assert DeepSearch(obj, item, verbose_level=1) == result
Ejemplo n.º 30
0
 def test_case_insensitive_of_str_in_one_liner(self):
     obj = "Hello, what's up?"
     item = "WHAT"
     result = {'matched_values': {'root'}}
     assert DeepSearch(obj, item, verbose_level=1,
                       case_sensitive=False) == result