Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
606c50c
Convert docstrings to double quotes
moomoohk Sep 11, 2021
4d5fdf2
Add Python >=3.6 constraint for type hints
moomoohk Sep 11, 2021
e3dc192
Organize imports
moomoohk Sep 11, 2021
16f511a
Fix typo
moomoohk Sep 11, 2021
6f8a558
Implement merge types as an enum
moomoohk Sep 12, 2021
fa26b39
Rename __safe_path__ to _split_path
moomoohk Sep 15, 2021
d96814b
Sort out imports
moomoohk Sep 15, 2021
0796049
Remove unnecessary check
moomoohk Sep 15, 2021
b6bc7d2
Rename/remove unused variables
moomoohk Sep 15, 2021
2b73ab3
Some type hinting
moomoohk Sep 15, 2021
b16c6ad
More type hinting
moomoohk Sep 15, 2021
fdac68f
Remove parens
moomoohk Sep 16, 2021
fb77a64
Refactoring and type hinting
moomoohk Sep 18, 2021
474ba6d
Documentation
moomoohk Sep 18, 2021
43554c2
Use fstrings
moomoohk Sep 18, 2021
0218ea6
Remove redundant parentheses
moomoohk Sep 28, 2021
74fa52d
Remove unicode literal
moomoohk Sep 28, 2021
7eadc11
Some type hints and name improvements
moomoohk Feb 1, 2022
92b604d
Merge branch 'master' into feature/cleanup
moomoohk Feb 2, 2022
b2f052e
Small refactor in deletion code
moomoohk Feb 2, 2022
f9c142b
Move custom type definitions to dedicated file
moomoohk Feb 2, 2022
86fce61
Use MutableMapping instead of dict
moomoohk Feb 2, 2022
a00adc3
Catch specific exceptions
moomoohk Nov 23, 2022
8d3a36f
Add exports
moomoohk Nov 23, 2022
3198c54
Move utils functions to top level
moomoohk Nov 23, 2022
c9859dd
Merge branch 'master' into feature/refactor
moomoohk Nov 23, 2022
605a756
Fix tests
moomoohk Nov 23, 2022
9ef4bde
Mock correct function
moomoohk Nov 24, 2022
9f06f02
PEP8 change
moomoohk Nov 24, 2022
b068120
Enable DeprecationWarnings in tests
moomoohk Nov 24, 2022
eceb8cb
Run flake8 separately from tests
moomoohk Nov 24, 2022
ddf81a8
Working flake8 with annotations
moomoohk Nov 24, 2022
29d344e
Style fixes
moomoohk Nov 24, 2022
b49e823
Reorder tasks in workflow
moomoohk Nov 24, 2022
6460b64
Set minor version
moomoohk Nov 24, 2022
1c8fa84
Remove references to dpath.util in tests
moomoohk Nov 25, 2022
17eab50
PEP8 fix
moomoohk Nov 25, 2022
36a6f5f
Add note regarding 3.6
moomoohk Nov 25, 2022
7a565ee
Type hint improvements and exports
moomoohk Nov 27, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 23 additions & 1 deletion .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,28 @@ on:

# A workflow run is made up of one or more jobs that can run sequentially or in parallel
jobs:

# Run flake8 linter
flake8:
runs-on: ubuntu-latest

steps:
- name: Check out code
uses: actions/checkout@main

- name: Set up Python 3.10
uses: actions/setup-python@main
with:
python-version: "3.10"

- name: Setup flake8 annotations
uses: rbialon/[email protected]

- name: Lint with flake8
run: |
pip install flake8
flake8 setup.py dpath/ tests/

# Generate a common hashseed for all tests
generate-hashseed:
runs-on: ubuntu-latest
Expand All @@ -43,7 +65,7 @@ jobs:
# The type of runner that the job will run on
runs-on: ubuntu-latest

needs: generate-hashseed
needs: [generate-hashseed, flake8]

strategy:
matrix:
Expand Down
67 changes: 33 additions & 34 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ Using Dpath

.. code-block:: python

import dpath.util
import dpath

Separators
==========
Expand Down Expand Up @@ -63,8 +63,8 @@ key '43' in the 'b' hash which is in the 'a' hash". That's easy.

.. code-block:: pycon

>>> help(dpath.util.get)
Help on function get in module dpath.util:
>>> help(dpath.get)
Help on function get in module dpath:

get(obj, glob, separator='/')
Given an object which contains only one possible match for the given glob,
Expand All @@ -73,16 +73,16 @@ key '43' in the 'b' hash which is in the 'a' hash". That's easy.
If more than one leaf matches the glob, ValueError is raised. If the glob is
not found, KeyError is raised.

>>> dpath.util.get(x, '/a/b/43')
>>> dpath.get(x, '/a/b/43')
30

Or you could say "Give me a new dictionary with the values of all
elements in ``x['a']['b']`` where the key is equal to the glob ``'[cd]'``. Okay.

.. code-block:: pycon

>>> help(dpath.util.search)
Help on function search in module dpath.util:
>>> help(dpath.search)
Help on function search in module dpath:

search(obj, glob, yielded=False)
Given a path glob, return a dictionary containing all keys
Expand All @@ -96,7 +96,7 @@ elements in ``x['a']['b']`` where the key is equal to the glob ``'[cd]'``. Okay.

.. code-block:: pycon

>>> result = dpath.util.search(x, "a/b/[cd]")
>>> result = dpath.search(x, "a/b/[cd]")
>>> print(json.dumps(result, indent=4, sort_keys=True))
{
"a": {
Expand All @@ -116,7 +116,7 @@ not get a merged view?

.. code-block:: pycon

>>> for x in dpath.util.search(x, "a/b/[cd]", yielded=True): print(x)
>>> for x in dpath.search(x, "a/b/[cd]", yielded=True): print(x)
...
('a/b/c', [])
('a/b/d', ['red', 'buggy', 'bumpers'])
Expand All @@ -126,16 +126,16 @@ don't care about the paths they were found at:

.. code-block:: pycon

>>> help(dpath.util.values)
Help on function values in module dpath.util:
>>> help(dpath.values)
Help on function values in module dpath:

values(obj, glob, separator='/', afilter=None, dirs=True)
Given an object and a path glob, return an array of all values which match
the glob. The arguments to this function are identical to those of search(),
and it is primarily a shorthand for a list comprehension over a yielded
search call.

>>> dpath.util.values(x, '/a/b/d/*')
>>> dpath.values(x, '/a/b/d/*')
['red', 'buggy', 'bumpers']

Example: Setting existing keys
Expand All @@ -146,14 +146,14 @@ value 'Waffles'.

.. code-block:: pycon

>>> help(dpath.util.set)
Help on function set in module dpath.util:
>>> help(dpath.set)
Help on function set in module dpath:

set(obj, glob, value)
Given a path glob, set all existing elements in the document
to the given value. Returns the number of elements changed.

>>> dpath.util.set(x, 'a/b/[cd]', 'Waffles')
>>> dpath.set(x, 'a/b/[cd]', 'Waffles')
2
>>> print(json.dumps(x, indent=4, sort_keys=True))
{
Expand All @@ -176,8 +176,8 @@ necessary to get to the terminus.

.. code-block:: pycon

>>> help(dpath.util.new)
Help on function new in module dpath.util:
>>> help(dpath.new)
Help on function new in module dpath:

new(obj, path, value)
Set the element at the terminus of path to value, and create
Expand All @@ -188,7 +188,7 @@ necessary to get to the terminus.
characters in it, they will become part of the resulting
keys

>>> dpath.util.new(x, 'a/b/e/f/g', "Roffle")
>>> dpath.new(x, 'a/b/e/f/g', "Roffle")
>>> print(json.dumps(x, indent=4, sort_keys=True))
{
"a": {
Expand All @@ -212,8 +212,8 @@ object with None entries in order to make it big enough:

.. code-block:: pycon

>>> dpath.util.new(x, 'a/b/e/f/h', [])
>>> dpath.util.new(x, 'a/b/e/f/h/13', 'Wow this is a big array, it sure is lonely in here by myself')
>>> dpath.new(x, 'a/b/e/f/h', [])
>>> dpath.new(x, 'a/b/e/f/h/13', 'Wow this is a big array, it sure is lonely in here by myself')
>>> print(json.dumps(x, indent=4, sort_keys=True))
{
"a": {
Expand Down Expand Up @@ -252,11 +252,11 @@ Handy!
Example: Deleting Existing Keys
===============================

To delete keys in an object, use dpath.util.delete, which accepts the same globbing syntax as the other methods.
To delete keys in an object, use dpath.delete, which accepts the same globbing syntax as the other methods.

.. code-block:: pycon

>>> help(dpath.util.delete)
>>> help(dpath.delete)

delete(obj, glob, separator='/', afilter=None):
Given a path glob, delete all elements that match the glob.
Expand All @@ -267,27 +267,26 @@ To delete keys in an object, use dpath.util.delete, which accepts the same globb
Example: Merging
================

Also, check out dpath.util.merge. The python dict update() method is
Also, check out dpath.merge. The python dict update() method is
great and all but doesn't handle merging dictionaries deeply. This one
does.

.. code-block:: pycon

>>> help(dpath.util.merge)
Help on function merge in module dpath.util:
>>> help(dpath.merge)
Help on function merge in module dpath:

merge(dst, src, afilter=None, flags=4, _path='')
Merge source into destination. Like dict.update() but performs
deep merging.

flags is an OR'ed combination of MERGE_ADDITIVE, MERGE_REPLACE
MERGE_TYPESAFE.
* MERGE_ADDITIVE : List objects are combined onto one long
flags is an OR'ed combination of MergeType enum members.
* ADDITIVE : List objects are combined onto one long
list (NOT a set). This is the default flag.
* MERGE_REPLACE : Instead of combining list objects, when
* REPLACE : Instead of combining list objects, when
2 list objects are at an equal depth of merge, replace
the destination with the source.
* MERGE_TYPESAFE : When 2 keys at equal levels are of different
* TYPESAFE : When 2 keys at equal levels are of different
types, raise a TypeError exception. By default, the source
replaces the destination in this situation.

Expand All @@ -312,7 +311,7 @@ does.
"c": "RoffleWaffles"
}
}
>>> dpath.util.merge(x, y)
>>> dpath.merge(x, y)
>>> print(json.dumps(x, indent=4, sort_keys=True))
{
"a": {
Expand Down Expand Up @@ -392,7 +391,7 @@ them:
... return True
... return False
...
>>> result = dpath.util.search(x, '**', afilter=afilter)
>>> result = dpath.search(x, '**', afilter=afilter)
>>> print(json.dumps(result, indent=4, sort_keys=True))
{
"a": {
Expand Down Expand Up @@ -431,18 +430,18 @@ Separator got you down? Use lists as paths

The default behavior in dpath is to assume that the path given is a string, which must be tokenized by splitting at the separator to yield a distinct set of path components against which dictionary keys can be individually glob tested. However, this presents a problem when you want to use paths that have a separator in their name; the tokenizer cannot properly understand what you mean by '/a/b/c' if it is possible for '/' to exist as a valid character in a key name.

To get around this, you can sidestep the whole "filesystem path" style, and abandon the separator entirely, by using lists as paths. All of the methods in dpath.util.* support the use of a list instead of a string as a path. So for example:
To get around this, you can sidestep the whole "filesystem path" style, and abandon the separator entirely, by using lists as paths. All of the methods in dpath.* support the use of a list instead of a string as a path. So for example:

.. code-block:: python

>>> x = { 'a': {'b/c': 0}}
>>> dpath.util.get(['a', 'b/c'])
>>> dpath.get(['a', 'b/c'])
0

dpath.segments : The Low-Level Backend
======================================

dpath.util is where you want to spend your time: this library has the friendly
dpath is where you want to spend your time: this library has the friendly
functions that will understand simple string globs, afilter functions, etc.

dpath.segments is the backend pathing library. It passes around tuples of path
Expand Down
Loading