Closed
Show file tree
Hide file tree
Changes from all commits
Commits
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
56 changes: 56 additions & 0 deletions .github/workflows/linterTest.yml
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
name: LinterTest
# ------------------------------------------------------------
# (C) Alain Lichnewsky, 2021, 2022
#
# For running under Github's Actions
#
# Script performs basic static test of the package under Python-3,
# including added functionality.
# ------------------------------------------------------------

# Controls when the action will run.
on:
#
## Not enabled, would triggers the workflow on push or pull request events but
## only for the AL-addRegexp branch.
#push:
# branches: [ AL-addRegexp ]

# Allows to run this workflow manually from the Github Actions tab
workflow_dispatch:

# A workflow run is made up of one or more jobs that can run sequentially or in
# parallel
jobs:
# This workflow contains a single job called "super-lint"
super-lint:
# Steps represent a sequence of tasks that will be executed by the job
# Name the Job
name: Lint code base
# Set the type of machine to run on
runs-on: ubuntu-latest

steps:
# Checks out a copy of your repository on the ubuntu-latest machine
- name: Checkout code
uses: actions/checkout@v2

# Runs a single command using the runners shell, in practice it is useful
# to figure out some of the environment setup
- name: Use shell to figure out environment
run: echo Hello from Github Actions !!;
bash --version | head -1 ;
echo LANG=${LANG} SHELL=${SHELL} ;
echo PATH=${PATH} ;
pwd;
ls -ltha;

# Runs the Super-Linter action
- name: Run Super-Linter
uses: github/super-linter@latest
#
# this script requires some environment variables
#
env:
DEFAULT_BRANCH: AL-master4merge
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
121 changes: 121 additions & 0 deletions .github/workflows/python3-pypy-Test.yml
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
name: Test python package dpath-python with regexp ext and pypy
# ------------------------------------------------------------
# (C) Alain Lichnewsky, 2021, 2022
#
# For running under Github's Actions
#
# Here the idea is to use tox for testing and test on python 3.8 and
# pypy-3.7.
#
# ------------------------------------------------------------

on:
# manual dispatch, this script will not be started automagically
workflow_dispatch:

jobs:
test-python3:

timeout-minutes: 60

runs-on: ubuntu-latest

steps:
- name: Checkout code
uses: actions/checkout@main

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

- name: Set up Pypy
uses: actions/setup-python@main
with:
python-version: 'pypy3.9'
architecture: 'x64'


- name: Ascertain configuration
shell: bash
#
# Collect information concerning $HOME and the location of
# file(s) loaded from Github/
run: |
echo Working dir: $(pwd)
echo Files at this location:
ls -ltha
echo HOME: ${HOME}
echo LANG: ${LANG} SHELL: ${SHELL}
which python
echo LD_LIBRARY_PATH: ${LD_LIBRARY_PATH}
echo PYTHONPATH: \'${PYTHONPATH}\'

# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# ** here (it is expected that) **
# pythonLocation: /opt/hostedtoolcache/Python/3.8.8/x64
# LD_LIBRARY_PATH: /opt/hostedtoolcache/Python/3.8.8/x64/lib
# Working dir /home/runner/work/dpath-python/dpath-python
# HOME: /home/runner
# LANG: C.UTF-8
# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

- name: Install dependencies

# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# requirements install the test framework, which is not
# required by the package in setup.py
# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
shell: bash
run: |
python -m pip install --upgrade pip setuptools wheel
if [ -f requirements.txt ]; then
pip install -r requirements.txt;
fi
python -m pip install --upgrade nose2 hypothesis
python setup.py install
echo which nose :$(which nose)
echo which nose2: $(which nose2)
echo which nose2-3.6: $(which nose2-3.6)
echo which nose2-3.8: $(which nose2-3.8)

- name: Check path preparing for pypy (1)
shell: bash
if: always()
run: |
test-utils/py_path_checker -M nose2 -U

- name: Check path preparing for pypy (2)
shell: bash
if: always()
run: |
pypy3 test-utils/py_path_checker -M nose2 -U

- name: Perform python tests
shell: bash
if: always()
run: |
PYTHONPATH="." test-utils/nose_runner -E -s tests

- name: Perform pypy tests
shell: bash
if: always()
run: |
PYTHONPATH=".:/usr/local/lib/python3.10/dist-packages/" \
pypy3 test-utils/nose_runner -E -s tests


- name: Tox testing

# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# move to tox testing, otherwise will have to parametrize
# nose in more details; here tox.ini will apply
# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
shell: bash
if: always()
run: |
pip install tox
echo "Installed tox"
tox
echo "Ran tox"
98 changes: 98 additions & 0 deletions .github/workflows/python3Test.yml
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
name: Test python package dpath-python with regexp extension
# ------------------------------------------------------------
# (C) Alain Lichnewsky, 2021, 2022
#
# For running under Github's Actions
#
# Script performs basic test of the Python-3 version of the package
# including added functionality (regexp in search paths).
# ------------------------------------------------------------

on:
workflow_dispatch:
# Allows manual dispatch from the Actions tab

jobs:
test-python3:

timeout-minutes: 60

runs-on: ubuntu-latest

strategy:
matrix:
# Match versions specified in tox.ini
python-version: ['3.10', 'pypy3.9']

steps:
- name: Checkout code
uses: actions/checkout@main

- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@main
with:
python-version: ${{ matrix.python-version }}
architecture: 'x64'

- name: Ascertain configuration
#
# Collect information concerning $HOME and the location of
# file(s) loaded from Github/
run: |
echo Working dir: $(pwd)
echo Files at this location:
ls -ltha
echo HOME: ${HOME}
echo LANG: ${LANG} SHELL: ${SHELL}
which python
echo LD_LIBRARY_PATH: ${LD_LIBRARY_PATH}
echo PYTHONPATH: \'${PYTHONPATH}\'

# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# ** here (it is expected that) **
# pythonLocation: /opt/hostedtoolcache/Python/3.8.8/x64
# LD_LIBRARY_PATH: /opt/hostedtoolcache/Python/3.8.8/x64/lib
# Working dir /home/runner/work/dpath-python/dpath-python
# HOME: /home/runner
# LANG: C.UTF-8
# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

- name: Install dependencies

# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# requirements install the test framework, which is not
# required by the package in setup.py
# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
run: |
python -m pip install --upgrade pip setuptools wheel \
nose2 hypothesis
if [ -f requirements.txt ]; then
pip install -r requirements.txt;
fi
python setup.py install
echo which nose :$(which nose)
echo which nose2: $(which nose2)
echo which nose2-3.6: $(which nose2-3.6)
echo which nose2-3.8: $(which nose2-3.8)

- name: nose_runner testing

# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# This is the nose2 wrapper that allows to set pgm. parms
# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

run: |
echo running the nose2 wrapper
PYTHONPATH="." test-utils/nose_runner -E -s tests

- name: Tox testing

# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# move to tox testing, otherwise will have to parametrize
# nose in more details; here tox.ini will apply
# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
run: |
pip install tox
echo "Installed tox"
tox
echo "Ran tox"
12 changes: 11 additions & 1 deletion .gitignore
Original file line numberDiff line numberDiff line change
Expand Up@@ -9,4 +9,14 @@ venv_39
.idea/
dpath.egg-info/
dist/
tests/.hypothesis
tests/.hypothesis

# Github logs
.githubLogs

# Test etc
.coverage

# Editor temporaries
*~

74 changes: 74 additions & 0 deletions README.rst
Original file line numberDiff line numberDiff line change
Expand Up@@ -111,6 +111,9 @@ elements in ``x['a']['b']`` where the key is equal to the glob ``'[cd]'``. Okay.
}
}

**Note** : Using Python's `re` regular expressions instead of globs is explained
below re_regexp_.

... Wow that was easy. What if I want to iterate over the results, and
not get a merged view?

Expand DownExpand Up@@ -438,6 +441,77 @@ To get around this, you can sidestep the whole "filesystem path" style, and aban
>>> dpath.get(['a', 'b/c'])
0

.. _re_regexp:

Globs too imprecise? Use Python's `re` Regular Expressions
==========================================================

Python's `re` regular expressions PythonRe_ may be used as follows:

.. _PythonRe: https://docs.python.org/3/library/re.html

- This facility must be enabled (for backwards compatibility):

.. code-block:: python

>>> import dpath
>>> dpath.options.DPATH_ACCEPT_RE_REGEXP = True

- Now a path component may also be specified :

- in a path expression, as {<re.regexpr>} where `<re.regexpr>` is a regular expression
accepted by the standard Python module `re`. For example:

.. code-block:: python

>>> selPath = 'Config/{(Env|Cmd)}'
>>> x = dpath.util.search(js.lod, selPath)

.. code-block:: python

>>> selPath = '{(Config|Graph)}/{(Env|Cmd|Data)}'
>>> x = dpath.util.search(js.lod, selPath)

- When using the list form for a path, a list element can also
be expressed as

- a string as above
- the output of :: `re.compile( args )``

An example:

.. code-block:: python

>>> selPath = [ re.compile('(Config|Graph)') , re.compile('(Env|Cmd|Data)') ]
>>> x = dpath.util.search(js.lod, selPath)

More examples from a realistic json context:

+-----------------------------------------+--------------------------------------+
+ **Extended path glob** | **Designates** +
+-----------------------------------------+--------------------------------------+
+ "\*\*/{[^A-Za-z]{2}$}" | "Id" +
+-----------------------------------------+--------------------------------------+
+ r"\*/{[A-Z][A-Za-z\\d]*$}" | "Name","Id","Created", "Scope",... +
+-----------------------------------------+--------------------------------------+
+ r"\*\*/{[A-Z][A-Za-z\\d]*\d$}" | EnableIPv6" +
+-----------------------------------------+--------------------------------------+
+ r"\*\*/{[A-Z][A-Za-z\\d]*Address$}" | "Containers/199c5/MacAddress" +
+-----------------------------------------+--------------------------------------+

With Python's chararcter string conventions, required backslashes in the `re` syntax
can be entered either in raw strings or using double backslashes, thus
the following are equivalent:

+-----------------------------------------+----------------------------------------+
+ *with raw strings* | *equivalent* with double backslash +
+-----------------------------------------+----------------------------------------+
+ r"\*\*/{[A-Z][A-Za-z\\d]*\\d$}" | "\*\*/{[A-Z][A-Za-z\\\\d]*\\\\d$}" +
+-----------------------------------------+----------------------------------------+
+ r"\*\*/{[A-Z][A-Za-z\\d]*Address$}" | "\*\*/{[A-Z][A-Za-z\\\\d]*Address$}" +
+-----------------------------------------+----------------------------------------+


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

Expand Down
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
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
56 changes: 56 additions & 0 deletions .github/workflows/linterTest.yml
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
name: LinterTest
# ------------------------------------------------------------
# (C) Alain Lichnewsky, 2021, 2022
#
# For running under Github's Actions
#
# Script performs basic static test of the package under Python-3,
# including added functionality.
# ------------------------------------------------------------

# Controls when the action will run.
on:
#
## Not enabled, would triggers the workflow on push or pull request events but
## only for the AL-addRegexp branch.
#push:
# branches: [ AL-addRegexp ]

# Allows to run this workflow manually from the Github Actions tab
workflow_dispatch:

# A workflow run is made up of one or more jobs that can run sequentially or in
# parallel
jobs:
# This workflow contains a single job called "super-lint"
super-lint:
# Steps represent a sequence of tasks that will be executed by the job
# Name the Job
name: Lint code base
# Set the type of machine to run on
runs-on: ubuntu-latest

steps:
# Checks out a copy of your repository on the ubuntu-latest machine
- name: Checkout code
uses: actions/checkout@v2

# Runs a single command using the runners shell, in practice it is useful
# to figure out some of the environment setup
- name: Use shell to figure out environment
run: echo Hello from Github Actions !!;
bash --version | head -1 ;
echo LANG=${LANG} SHELL=${SHELL} ;
echo PATH=${PATH} ;
pwd;
ls -ltha;

# Runs the Super-Linter action
- name: Run Super-Linter
uses: github/super-linter@latest
#
# this script requires some environment variables
#
env:
DEFAULT_BRANCH: AL-master4merge
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
121 changes: 121 additions & 0 deletions .github/workflows/python3-pypy-Test.yml
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
name: Test python package dpath-python with regexp ext and pypy
# ------------------------------------------------------------
# (C) Alain Lichnewsky, 2021, 2022
#
# For running under Github's Actions
#
# Here the idea is to use tox for testing and test on python 3.8 and
# pypy-3.7.
#
# ------------------------------------------------------------

on:
# manual dispatch, this script will not be started automagically
workflow_dispatch:

jobs:
test-python3:

timeout-minutes: 60

runs-on: ubuntu-latest

steps:
- name: Checkout code
uses: actions/checkout@main

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

- name: Set up Pypy
uses: actions/setup-python@main
with:
python-version: 'pypy3.9'
architecture: 'x64'


- name: Ascertain configuration
shell: bash
#
# Collect information concerning $HOME and the location of
# file(s) loaded from Github/
run: |
echo Working dir: $(pwd)
echo Files at this location:
ls -ltha
echo HOME: ${HOME}
echo LANG: ${LANG} SHELL: ${SHELL}
which python
echo LD_LIBRARY_PATH: ${LD_LIBRARY_PATH}
echo PYTHONPATH: \'${PYTHONPATH}\'

# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# ** here (it is expected that) **
# pythonLocation: /opt/hostedtoolcache/Python/3.8.8/x64
# LD_LIBRARY_PATH: /opt/hostedtoolcache/Python/3.8.8/x64/lib
# Working dir /home/runner/work/dpath-python/dpath-python
# HOME: /home/runner
# LANG: C.UTF-8
# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

- name: Install dependencies

# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# requirements install the test framework, which is not
# required by the package in setup.py
# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
shell: bash
run: |
python -m pip install --upgrade pip setuptools wheel
if [ -f requirements.txt ]; then
pip install -r requirements.txt;
fi
python -m pip install --upgrade nose2 hypothesis
python setup.py install
echo which nose :$(which nose)
echo which nose2: $(which nose2)
echo which nose2-3.6: $(which nose2-3.6)
echo which nose2-3.8: $(which nose2-3.8)

- name: Check path preparing for pypy (1)
shell: bash
if: always()
run: |
test-utils/py_path_checker -M nose2 -U

- name: Check path preparing for pypy (2)
shell: bash
if: always()
run: |
pypy3 test-utils/py_path_checker -M nose2 -U

- name: Perform python tests
shell: bash
if: always()
run: |
PYTHONPATH="." test-utils/nose_runner -E -s tests

- name: Perform pypy tests
shell: bash
if: always()
run: |
PYTHONPATH=".:/usr/local/lib/python3.10/dist-packages/" \
pypy3 test-utils/nose_runner -E -s tests


- name: Tox testing

# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# move to tox testing, otherwise will have to parametrize
# nose in more details; here tox.ini will apply
# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
shell: bash
if: always()
run: |
pip install tox
echo "Installed tox"
tox
echo "Ran tox"
98 changes: 98 additions & 0 deletions .github/workflows/python3Test.yml
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
name: Test python package dpath-python with regexp extension
# ------------------------------------------------------------
# (C) Alain Lichnewsky, 2021, 2022
#
# For running under Github's Actions
#
# Script performs basic test of the Python-3 version of the package
# including added functionality (regexp in search paths).
# ------------------------------------------------------------

on:
workflow_dispatch:
# Allows manual dispatch from the Actions tab

jobs:
test-python3:

timeout-minutes: 60

runs-on: ubuntu-latest

strategy:
matrix:
# Match versions specified in tox.ini
python-version: ['3.10', 'pypy3.9']

steps:
- name: Checkout code
uses: actions/checkout@main

- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@main
with:
python-version: ${{ matrix.python-version }}
architecture: 'x64'

- name: Ascertain configuration
#
# Collect information concerning $HOME and the location of
# file(s) loaded from Github/
run: |
echo Working dir: $(pwd)
echo Files at this location:
ls -ltha
echo HOME: ${HOME}
echo LANG: ${LANG} SHELL: ${SHELL}
which python
echo LD_LIBRARY_PATH: ${LD_LIBRARY_PATH}
echo PYTHONPATH: \'${PYTHONPATH}\'

# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# ** here (it is expected that) **
# pythonLocation: /opt/hostedtoolcache/Python/3.8.8/x64
# LD_LIBRARY_PATH: /opt/hostedtoolcache/Python/3.8.8/x64/lib
# Working dir /home/runner/work/dpath-python/dpath-python
# HOME: /home/runner
# LANG: C.UTF-8
# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

- name: Install dependencies

# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# requirements install the test framework, which is not
# required by the package in setup.py
# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
run: |
python -m pip install --upgrade pip setuptools wheel \
nose2 hypothesis
if [ -f requirements.txt ]; then
pip install -r requirements.txt;
fi
python setup.py install
echo which nose :$(which nose)
echo which nose2: $(which nose2)
echo which nose2-3.6: $(which nose2-3.6)
echo which nose2-3.8: $(which nose2-3.8)

- name: nose_runner testing

# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# This is the nose2 wrapper that allows to set pgm. parms
# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

run: |
echo running the nose2 wrapper
PYTHONPATH="." test-utils/nose_runner -E -s tests

- name: Tox testing

# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# move to tox testing, otherwise will have to parametrize
# nose in more details; here tox.ini will apply
# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
run: |
pip install tox
echo "Installed tox"
tox
echo "Ran tox"
12 changes: 11 additions & 1 deletion .gitignore
Original file line numberDiff line numberDiff line change
Expand Up@@ -9,4 +9,14 @@ venv_39
.idea/
dpath.egg-info/
dist/
tests/.hypothesis
tests/.hypothesis

# Github logs
.githubLogs

# Test etc
.coverage

# Editor temporaries
*~

74 changes: 74 additions & 0 deletions README.rst
Original file line numberDiff line numberDiff line change
Expand Up@@ -111,6 +111,9 @@ elements in ``x['a']['b']`` where the key is equal to the glob ``'[cd]'``. Okay.
}
}

**Note** : Using Python's `re` regular expressions instead of globs is explained
below re_regexp_.

... Wow that was easy. What if I want to iterate over the results, and
not get a merged view?

Expand DownExpand Up@@ -438,6 +441,77 @@ To get around this, you can sidestep the whole "filesystem path" style, and aban
>>> dpath.get(['a', 'b/c'])
0

.. _re_regexp:

Globs too imprecise? Use Python's `re` Regular Expressions
==========================================================

Python's `re` regular expressions PythonRe_ may be used as follows:

.. _PythonRe: https://docs.python.org/3/library/re.html

- This facility must be enabled (for backwards compatibility):

.. code-block:: python

>>> import dpath
>>> dpath.options.DPATH_ACCEPT_RE_REGEXP = True

- Now a path component may also be specified :

- in a path expression, as {<re.regexpr>} where `<re.regexpr>` is a regular expression
accepted by the standard Python module `re`. For example:

.. code-block:: python

>>> selPath = 'Config/{(Env|Cmd)}'
>>> x = dpath.util.search(js.lod, selPath)

.. code-block:: python

>>> selPath = '{(Config|Graph)}/{(Env|Cmd|Data)}'
>>> x = dpath.util.search(js.lod, selPath)

- When using the list form for a path, a list element can also
be expressed as

- a string as above
- the output of :: `re.compile( args )``

An example:

.. code-block:: python

>>> selPath = [ re.compile('(Config|Graph)') , re.compile('(Env|Cmd|Data)') ]
>>> x = dpath.util.search(js.lod, selPath)

More examples from a realistic json context:

+-----------------------------------------+--------------------------------------+
+ **Extended path glob** | **Designates** +
+-----------------------------------------+--------------------------------------+
+ "\*\*/{[^A-Za-z]{2}$}" | "Id" +
+-----------------------------------------+--------------------------------------+
+ r"\*/{[A-Z][A-Za-z\\d]*$}" | "Name","Id","Created", "Scope",... +
+-----------------------------------------+--------------------------------------+
+ r"\*\*/{[A-Z][A-Za-z\\d]*\d$}" | EnableIPv6" +
+-----------------------------------------+--------------------------------------+
+ r"\*\*/{[A-Z][A-Za-z\\d]*Address$}" | "Containers/199c5/MacAddress" +
+-----------------------------------------+--------------------------------------+

With Python's chararcter string conventions, required backslashes in the `re` syntax
can be entered either in raw strings or using double backslashes, thus
the following are equivalent:

+-----------------------------------------+----------------------------------------+
+ *with raw strings* | *equivalent* with double backslash +
+-----------------------------------------+----------------------------------------+
+ r"\*\*/{[A-Z][A-Za-z\\d]*\\d$}" | "\*\*/{[A-Z][A-Za-z\\\\d]*\\\\d$}" +
+-----------------------------------------+----------------------------------------+
+ r"\*\*/{[A-Z][A-Za-z\\d]*Address$}" | "\*\*/{[A-Z][A-Za-z\\\\d]*Address$}" +
+-----------------------------------------+----------------------------------------+


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

Expand Down
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
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
56 changes: 56 additions & 0 deletions .github/workflows/linterTest.yml
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
name: LinterTest
# ------------------------------------------------------------
# (C) Alain Lichnewsky, 2021, 2022
#
# For running under Github's Actions
#
# Script performs basic static test of the package under Python-3,
# including added functionality.
# ------------------------------------------------------------

# Controls when the action will run.
on:
#
## Not enabled, would triggers the workflow on push or pull request events but
## only for the AL-addRegexp branch.
#push:
# branches: [ AL-addRegexp ]

# Allows to run this workflow manually from the Github Actions tab
workflow_dispatch:

# A workflow run is made up of one or more jobs that can run sequentially or in
# parallel
jobs:
# This workflow contains a single job called "super-lint"
super-lint:
# Steps represent a sequence of tasks that will be executed by the job
# Name the Job
name: Lint code base
# Set the type of machine to run on
runs-on: ubuntu-latest

steps:
# Checks out a copy of your repository on the ubuntu-latest machine
- name: Checkout code
uses: actions/checkout@v2

# Runs a single command using the runners shell, in practice it is useful
# to figure out some of the environment setup
- name: Use shell to figure out environment
run: echo Hello from Github Actions !!;
bash --version | head -1 ;
echo LANG=${LANG} SHELL=${SHELL} ;
echo PATH=${PATH} ;
pwd;
ls -ltha;

# Runs the Super-Linter action
- name: Run Super-Linter
uses: github/super-linter@latest
#
# this script requires some environment variables
#
env:
DEFAULT_BRANCH: AL-master4merge
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
121 changes: 121 additions & 0 deletions .github/workflows/python3-pypy-Test.yml
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
name: Test python package dpath-python with regexp ext and pypy
# ------------------------------------------------------------
# (C) Alain Lichnewsky, 2021, 2022
#
# For running under Github's Actions
#
# Here the idea is to use tox for testing and test on python 3.8 and
# pypy-3.7.
#
# ------------------------------------------------------------

on:
# manual dispatch, this script will not be started automagically
workflow_dispatch:

jobs:
test-python3:

timeout-minutes: 60

runs-on: ubuntu-latest

steps:
- name: Checkout code
uses: actions/checkout@main

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

- name: Set up Pypy
uses: actions/setup-python@main
with:
python-version: 'pypy3.9'
architecture: 'x64'


- name: Ascertain configuration
shell: bash
#
# Collect information concerning $HOME and the location of
# file(s) loaded from Github/
run: |
echo Working dir: $(pwd)
echo Files at this location:
ls -ltha
echo HOME: ${HOME}
echo LANG: ${LANG} SHELL: ${SHELL}
which python
echo LD_LIBRARY_PATH: ${LD_LIBRARY_PATH}
echo PYTHONPATH: \'${PYTHONPATH}\'

# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# ** here (it is expected that) **
# pythonLocation: /opt/hostedtoolcache/Python/3.8.8/x64
# LD_LIBRARY_PATH: /opt/hostedtoolcache/Python/3.8.8/x64/lib
# Working dir /home/runner/work/dpath-python/dpath-python
# HOME: /home/runner
# LANG: C.UTF-8
# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

- name: Install dependencies

# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# requirements install the test framework, which is not
# required by the package in setup.py
# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
shell: bash
run: |
python -m pip install --upgrade pip setuptools wheel
if [ -f requirements.txt ]; then
pip install -r requirements.txt;
fi
python -m pip install --upgrade nose2 hypothesis
python setup.py install
echo which nose :$(which nose)
echo which nose2: $(which nose2)
echo which nose2-3.6: $(which nose2-3.6)
echo which nose2-3.8: $(which nose2-3.8)

- name: Check path preparing for pypy (1)
shell: bash
if: always()
run: |
test-utils/py_path_checker -M nose2 -U

- name: Check path preparing for pypy (2)
shell: bash
if: always()
run: |
pypy3 test-utils/py_path_checker -M nose2 -U

- name: Perform python tests
shell: bash
if: always()
run: |
PYTHONPATH="." test-utils/nose_runner -E -s tests

- name: Perform pypy tests
shell: bash
if: always()
run: |
PYTHONPATH=".:/usr/local/lib/python3.10/dist-packages/" \
pypy3 test-utils/nose_runner -E -s tests


- name: Tox testing

# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# move to tox testing, otherwise will have to parametrize
# nose in more details; here tox.ini will apply
# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
shell: bash
if: always()
run: |
pip install tox
echo "Installed tox"
tox
echo "Ran tox"
98 changes: 98 additions & 0 deletions .github/workflows/python3Test.yml
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
name: Test python package dpath-python with regexp extension
# ------------------------------------------------------------
# (C) Alain Lichnewsky, 2021, 2022
#
# For running under Github's Actions
#
# Script performs basic test of the Python-3 version of the package
# including added functionality (regexp in search paths).
# ------------------------------------------------------------

on:
workflow_dispatch:
# Allows manual dispatch from the Actions tab

jobs:
test-python3:

timeout-minutes: 60

runs-on: ubuntu-latest

strategy:
matrix:
# Match versions specified in tox.ini
python-version: ['3.10', 'pypy3.9']

steps:
- name: Checkout code
uses: actions/checkout@main

- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@main
with:
python-version: ${{ matrix.python-version }}
architecture: 'x64'

- name: Ascertain configuration
#
# Collect information concerning $HOME and the location of
# file(s) loaded from Github/
run: |
echo Working dir: $(pwd)
echo Files at this location:
ls -ltha
echo HOME: ${HOME}
echo LANG: ${LANG} SHELL: ${SHELL}
which python
echo LD_LIBRARY_PATH: ${LD_LIBRARY_PATH}
echo PYTHONPATH: \'${PYTHONPATH}\'

# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# ** here (it is expected that) **
# pythonLocation: /opt/hostedtoolcache/Python/3.8.8/x64
# LD_LIBRARY_PATH: /opt/hostedtoolcache/Python/3.8.8/x64/lib
# Working dir /home/runner/work/dpath-python/dpath-python
# HOME: /home/runner
# LANG: C.UTF-8
# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

- name: Install dependencies

# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# requirements install the test framework, which is not
# required by the package in setup.py
# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
run: |
python -m pip install --upgrade pip setuptools wheel \
nose2 hypothesis
if [ -f requirements.txt ]; then
pip install -r requirements.txt;
fi
python setup.py install
echo which nose :$(which nose)
echo which nose2: $(which nose2)
echo which nose2-3.6: $(which nose2-3.6)
echo which nose2-3.8: $(which nose2-3.8)

- name: nose_runner testing

# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# This is the nose2 wrapper that allows to set pgm. parms
# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

run: |
echo running the nose2 wrapper
PYTHONPATH="." test-utils/nose_runner -E -s tests

- name: Tox testing

# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# move to tox testing, otherwise will have to parametrize
# nose in more details; here tox.ini will apply
# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
run: |
pip install tox
echo "Installed tox"
tox
echo "Ran tox"
12 changes: 11 additions & 1 deletion .gitignore
Original file line numberDiff line numberDiff line change
Expand Up@@ -9,4 +9,14 @@ venv_39
.idea/
dpath.egg-info/
dist/
tests/.hypothesis
tests/.hypothesis

# Github logs
.githubLogs

# Test etc
.coverage

# Editor temporaries
*~

74 changes: 74 additions & 0 deletions README.rst
Original file line numberDiff line numberDiff line change
Expand Up@@ -111,6 +111,9 @@ elements in ``x['a']['b']`` where the key is equal to the glob ``'[cd]'``. Okay.
}
}

**Note** : Using Python's `re` regular expressions instead of globs is explained
below re_regexp_.

... Wow that was easy. What if I want to iterate over the results, and
not get a merged view?

Expand DownExpand Up@@ -438,6 +441,77 @@ To get around this, you can sidestep the whole "filesystem path" style, and aban
>>> dpath.get(['a', 'b/c'])
0

.. _re_regexp:

Globs too imprecise? Use Python's `re` Regular Expressions
==========================================================

Python's `re` regular expressions PythonRe_ may be used as follows:

.. _PythonRe: https://docs.python.org/3/library/re.html

- This facility must be enabled (for backwards compatibility):

.. code-block:: python

>>> import dpath
>>> dpath.options.DPATH_ACCEPT_RE_REGEXP = True

- Now a path component may also be specified :

- in a path expression, as {<re.regexpr>} where `<re.regexpr>` is a regular expression
accepted by the standard Python module `re`. For example:

.. code-block:: python

>>> selPath = 'Config/{(Env|Cmd)}'
>>> x = dpath.util.search(js.lod, selPath)

.. code-block:: python

>>> selPath = '{(Config|Graph)}/{(Env|Cmd|Data)}'
>>> x = dpath.util.search(js.lod, selPath)

- When using the list form for a path, a list element can also
be expressed as

- a string as above
- the output of :: `re.compile( args )``

An example:

.. code-block:: python

>>> selPath = [ re.compile('(Config|Graph)') , re.compile('(Env|Cmd|Data)') ]
>>> x = dpath.util.search(js.lod, selPath)

More examples from a realistic json context:

+-----------------------------------------+--------------------------------------+
+ **Extended path glob** | **Designates** +
+-----------------------------------------+--------------------------------------+
+ "\*\*/{[^A-Za-z]{2}$}" | "Id" +
+-----------------------------------------+--------------------------------------+
+ r"\*/{[A-Z][A-Za-z\\d]*$}" | "Name","Id","Created", "Scope",... +
+-----------------------------------------+--------------------------------------+
+ r"\*\*/{[A-Z][A-Za-z\\d]*\d$}" | EnableIPv6" +
+-----------------------------------------+--------------------------------------+
+ r"\*\*/{[A-Z][A-Za-z\\d]*Address$}" | "Containers/199c5/MacAddress" +
+-----------------------------------------+--------------------------------------+

With Python's chararcter string conventions, required backslashes in the `re` syntax
can be entered either in raw strings or using double backslashes, thus
the following are equivalent:

+-----------------------------------------+----------------------------------------+
+ *with raw strings* | *equivalent* with double backslash +
+-----------------------------------------+----------------------------------------+
+ r"\*\*/{[A-Z][A-Za-z\\d]*\\d$}" | "\*\*/{[A-Z][A-Za-z\\\\d]*\\\\d$}" +
+-----------------------------------------+----------------------------------------+
+ r"\*\*/{[A-Z][A-Za-z\\d]*Address$}" | "\*\*/{[A-Z][A-Za-z\\\\d]*Address$}" +
+-----------------------------------------+----------------------------------------+


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

Expand Down
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
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
56 changes: 56 additions & 0 deletions .github/workflows/linterTest.yml
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
name: LinterTest
# ------------------------------------------------------------
# (C) Alain Lichnewsky, 2021, 2022
#
# For running under Github's Actions
#
# Script performs basic static test of the package under Python-3,
# including added functionality.
# ------------------------------------------------------------

# Controls when the action will run.
on:
#
## Not enabled, would triggers the workflow on push or pull request events but
## only for the AL-addRegexp branch.
#push:
# branches: [ AL-addRegexp ]

# Allows to run this workflow manually from the Github Actions tab
workflow_dispatch:

# A workflow run is made up of one or more jobs that can run sequentially or in
# parallel
jobs:
# This workflow contains a single job called "super-lint"
super-lint:
# Steps represent a sequence of tasks that will be executed by the job
# Name the Job
name: Lint code base
# Set the type of machine to run on
runs-on: ubuntu-latest

steps:
# Checks out a copy of your repository on the ubuntu-latest machine
- name: Checkout code
uses: actions/checkout@v2

# Runs a single command using the runners shell, in practice it is useful
# to figure out some of the environment setup
- name: Use shell to figure out environment
run: echo Hello from Github Actions !!;
bash --version | head -1 ;
echo LANG=${LANG} SHELL=${SHELL} ;
echo PATH=${PATH} ;
pwd;
ls -ltha;

# Runs the Super-Linter action
- name: Run Super-Linter
uses: github/super-linter@latest
#
# this script requires some environment variables
#
env:
DEFAULT_BRANCH: AL-master4merge
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
121 changes: 121 additions & 0 deletions .github/workflows/python3-pypy-Test.yml
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
name: Test python package dpath-python with regexp ext and pypy
# ------------------------------------------------------------
# (C) Alain Lichnewsky, 2021, 2022
#
# For running under Github's Actions
#
# Here the idea is to use tox for testing and test on python 3.8 and
# pypy-3.7.
#
# ------------------------------------------------------------

on:
# manual dispatch, this script will not be started automagically
workflow_dispatch:

jobs:
test-python3:

timeout-minutes: 60

runs-on: ubuntu-latest

steps:
- name: Checkout code
uses: actions/checkout@main

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

- name: Set up Pypy
uses: actions/setup-python@main
with:
python-version: 'pypy3.9'
architecture: 'x64'


- name: Ascertain configuration
shell: bash
#
# Collect information concerning $HOME and the location of
# file(s) loaded from Github/
run: |
echo Working dir: $(pwd)
echo Files at this location:
ls -ltha
echo HOME: ${HOME}
echo LANG: ${LANG} SHELL: ${SHELL}
which python
echo LD_LIBRARY_PATH: ${LD_LIBRARY_PATH}
echo PYTHONPATH: \'${PYTHONPATH}\'

# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# ** here (it is expected that) **
# pythonLocation: /opt/hostedtoolcache/Python/3.8.8/x64
# LD_LIBRARY_PATH: /opt/hostedtoolcache/Python/3.8.8/x64/lib
# Working dir /home/runner/work/dpath-python/dpath-python
# HOME: /home/runner
# LANG: C.UTF-8
# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

- name: Install dependencies

# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# requirements install the test framework, which is not
# required by the package in setup.py
# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
shell: bash
run: |
python -m pip install --upgrade pip setuptools wheel
if [ -f requirements.txt ]; then
pip install -r requirements.txt;
fi
python -m pip install --upgrade nose2 hypothesis
python setup.py install
echo which nose :$(which nose)
echo which nose2: $(which nose2)
echo which nose2-3.6: $(which nose2-3.6)
echo which nose2-3.8: $(which nose2-3.8)

- name: Check path preparing for pypy (1)
shell: bash
if: always()
run: |
test-utils/py_path_checker -M nose2 -U

- name: Check path preparing for pypy (2)
shell: bash
if: always()
run: |
pypy3 test-utils/py_path_checker -M nose2 -U

- name: Perform python tests
shell: bash
if: always()
run: |
PYTHONPATH="." test-utils/nose_runner -E -s tests

- name: Perform pypy tests
shell: bash
if: always()
run: |
PYTHONPATH=".:/usr/local/lib/python3.10/dist-packages/" \
pypy3 test-utils/nose_runner -E -s tests


- name: Tox testing

# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# move to tox testing, otherwise will have to parametrize
# nose in more details; here tox.ini will apply
# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
shell: bash
if: always()
run: |
pip install tox
echo "Installed tox"
tox
echo "Ran tox"
98 changes: 98 additions & 0 deletions .github/workflows/python3Test.yml
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
name: Test python package dpath-python with regexp extension
# ------------------------------------------------------------
# (C) Alain Lichnewsky, 2021, 2022
#
# For running under Github's Actions
#
# Script performs basic test of the Python-3 version of the package
# including added functionality (regexp in search paths).
# ------------------------------------------------------------

on:
workflow_dispatch:
# Allows manual dispatch from the Actions tab

jobs:
test-python3:

timeout-minutes: 60

runs-on: ubuntu-latest

strategy:
matrix:
# Match versions specified in tox.ini
python-version: ['3.10', 'pypy3.9']

steps:
- name: Checkout code
uses: actions/checkout@main

- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@main
with:
python-version: ${{ matrix.python-version }}
architecture: 'x64'

- name: Ascertain configuration
#
# Collect information concerning $HOME and the location of
# file(s) loaded from Github/
run: |
echo Working dir: $(pwd)
echo Files at this location:
ls -ltha
echo HOME: ${HOME}
echo LANG: ${LANG} SHELL: ${SHELL}
which python
echo LD_LIBRARY_PATH: ${LD_LIBRARY_PATH}
echo PYTHONPATH: \'${PYTHONPATH}\'

# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# ** here (it is expected that) **
# pythonLocation: /opt/hostedtoolcache/Python/3.8.8/x64
# LD_LIBRARY_PATH: /opt/hostedtoolcache/Python/3.8.8/x64/lib
# Working dir /home/runner/work/dpath-python/dpath-python
# HOME: /home/runner
# LANG: C.UTF-8
# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

- name: Install dependencies

# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# requirements install the test framework, which is not
# required by the package in setup.py
# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
run: |
python -m pip install --upgrade pip setuptools wheel \
nose2 hypothesis
if [ -f requirements.txt ]; then
pip install -r requirements.txt;
fi
python setup.py install
echo which nose :$(which nose)
echo which nose2: $(which nose2)
echo which nose2-3.6: $(which nose2-3.6)
echo which nose2-3.8: $(which nose2-3.8)

- name: nose_runner testing

# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# This is the nose2 wrapper that allows to set pgm. parms
# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

run: |
echo running the nose2 wrapper
PYTHONPATH="." test-utils/nose_runner -E -s tests

- name: Tox testing

# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# move to tox testing, otherwise will have to parametrize
# nose in more details; here tox.ini will apply
# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
run: |
pip install tox
echo "Installed tox"
tox
echo "Ran tox"
12 changes: 11 additions & 1 deletion .gitignore
Original file line numberDiff line numberDiff line change
Expand Up@@ -9,4 +9,14 @@ venv_39
.idea/
dpath.egg-info/
dist/
tests/.hypothesis
tests/.hypothesis

# Github logs
.githubLogs

# Test etc
.coverage

# Editor temporaries
*~

74 changes: 74 additions & 0 deletions README.rst
Original file line numberDiff line numberDiff line change
Expand Up@@ -111,6 +111,9 @@ elements in ``x['a']['b']`` where the key is equal to the glob ``'[cd]'``. Okay.
}
}

**Note** : Using Python's `re` regular expressions instead of globs is explained
below re_regexp_.

... Wow that was easy. What if I want to iterate over the results, and
not get a merged view?

Expand DownExpand Up@@ -438,6 +441,77 @@ To get around this, you can sidestep the whole "filesystem path" style, and aban
>>> dpath.get(['a', 'b/c'])
0

.. _re_regexp:

Globs too imprecise? Use Python's `re` Regular Expressions
==========================================================

Python's `re` regular expressions PythonRe_ may be used as follows:

.. _PythonRe: https://docs.python.org/3/library/re.html

- This facility must be enabled (for backwards compatibility):

.. code-block:: python

>>> import dpath
>>> dpath.options.DPATH_ACCEPT_RE_REGEXP = True

- Now a path component may also be specified :

- in a path expression, as {<re.regexpr>} where `<re.regexpr>` is a regular expression
accepted by the standard Python module `re`. For example:

.. code-block:: python

>>> selPath = 'Config/{(Env|Cmd)}'
>>> x = dpath.util.search(js.lod, selPath)

.. code-block:: python

>>> selPath = '{(Config|Graph)}/{(Env|Cmd|Data)}'
>>> x = dpath.util.search(js.lod, selPath)

- When using the list form for a path, a list element can also
be expressed as

- a string as above
- the output of :: `re.compile( args )``

An example:

.. code-block:: python

>>> selPath = [ re.compile('(Config|Graph)') , re.compile('(Env|Cmd|Data)') ]
>>> x = dpath.util.search(js.lod, selPath)

More examples from a realistic json context:

+-----------------------------------------+--------------------------------------+
+ **Extended path glob** | **Designates** +
+-----------------------------------------+--------------------------------------+
+ "\*\*/{[^A-Za-z]{2}$}" | "Id" +
+-----------------------------------------+--------------------------------------+
+ r"\*/{[A-Z][A-Za-z\\d]*$}" | "Name","Id","Created", "Scope",... +
+-----------------------------------------+--------------------------------------+
+ r"\*\*/{[A-Z][A-Za-z\\d]*\d$}" | EnableIPv6" +
+-----------------------------------------+--------------------------------------+
+ r"\*\*/{[A-Z][A-Za-z\\d]*Address$}" | "Containers/199c5/MacAddress" +
+-----------------------------------------+--------------------------------------+

With Python's chararcter string conventions, required backslashes in the `re` syntax
can be entered either in raw strings or using double backslashes, thus
the following are equivalent:

+-----------------------------------------+----------------------------------------+
+ *with raw strings* | *equivalent* with double backslash +
+-----------------------------------------+----------------------------------------+
+ r"\*\*/{[A-Z][A-Za-z\\d]*\\d$}" | "\*\*/{[A-Z][A-Za-z\\\\d]*\\\\d$}" +
+-----------------------------------------+----------------------------------------+
+ r"\*\*/{[A-Z][A-Za-z\\d]*Address$}" | "\*\*/{[A-Z][A-Za-z\\\\d]*Address$}" +
+-----------------------------------------+----------------------------------------+


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

Expand Down
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
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
56 changes: 56 additions & 0 deletions .github/workflows/linterTest.yml
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
name: LinterTest
# ------------------------------------------------------------
# (C) Alain Lichnewsky, 2021, 2022
#
# For running under Github's Actions
#
# Script performs basic static test of the package under Python-3,
# including added functionality.
# ------------------------------------------------------------

# Controls when the action will run.
on:
#
## Not enabled, would triggers the workflow on push or pull request events but
## only for the AL-addRegexp branch.
#push:
# branches: [ AL-addRegexp ]

# Allows to run this workflow manually from the Github Actions tab
workflow_dispatch:

# A workflow run is made up of one or more jobs that can run sequentially or in
# parallel
jobs:
# This workflow contains a single job called "super-lint"
super-lint:
# Steps represent a sequence of tasks that will be executed by the job
# Name the Job
name: Lint code base
# Set the type of machine to run on
runs-on: ubuntu-latest

steps:
# Checks out a copy of your repository on the ubuntu-latest machine
- name: Checkout code
uses: actions/checkout@v2

# Runs a single command using the runners shell, in practice it is useful
# to figure out some of the environment setup
- name: Use shell to figure out environment
run: echo Hello from Github Actions !!;
bash --version | head -1 ;
echo LANG=${LANG} SHELL=${SHELL} ;
echo PATH=${PATH} ;
pwd;
ls -ltha;

# Runs the Super-Linter action
- name: Run Super-Linter
uses: github/super-linter@latest
#
# this script requires some environment variables
#
env:
DEFAULT_BRANCH: AL-master4merge
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
121 changes: 121 additions & 0 deletions .github/workflows/python3-pypy-Test.yml
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
name: Test python package dpath-python with regexp ext and pypy
# ------------------------------------------------------------
# (C) Alain Lichnewsky, 2021, 2022
#
# For running under Github's Actions
#
# Here the idea is to use tox for testing and test on python 3.8 and
# pypy-3.7.
#
# ------------------------------------------------------------

on:
# manual dispatch, this script will not be started automagically
workflow_dispatch:

jobs:
test-python3:

timeout-minutes: 60

runs-on: ubuntu-latest

steps:
- name: Checkout code
uses: actions/checkout@main

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

- name: Set up Pypy
uses: actions/setup-python@main
with:
python-version: 'pypy3.9'
architecture: 'x64'


- name: Ascertain configuration
shell: bash
#
# Collect information concerning $HOME and the location of
# file(s) loaded from Github/
run: |
echo Working dir: $(pwd)
echo Files at this location:
ls -ltha
echo HOME: ${HOME}
echo LANG: ${LANG} SHELL: ${SHELL}
which python
echo LD_LIBRARY_PATH: ${LD_LIBRARY_PATH}
echo PYTHONPATH: \'${PYTHONPATH}\'

# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# ** here (it is expected that) **
# pythonLocation: /opt/hostedtoolcache/Python/3.8.8/x64
# LD_LIBRARY_PATH: /opt/hostedtoolcache/Python/3.8.8/x64/lib
# Working dir /home/runner/work/dpath-python/dpath-python
# HOME: /home/runner
# LANG: C.UTF-8
# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

- name: Install dependencies

# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# requirements install the test framework, which is not
# required by the package in setup.py
# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
shell: bash
run: |
python -m pip install --upgrade pip setuptools wheel
if [ -f requirements.txt ]; then
pip install -r requirements.txt;
fi
python -m pip install --upgrade nose2 hypothesis
python setup.py install
echo which nose :$(which nose)
echo which nose2: $(which nose2)
echo which nose2-3.6: $(which nose2-3.6)
echo which nose2-3.8: $(which nose2-3.8)

- name: Check path preparing for pypy (1)
shell: bash
if: always()
run: |
test-utils/py_path_checker -M nose2 -U

- name: Check path preparing for pypy (2)
shell: bash
if: always()
run: |
pypy3 test-utils/py_path_checker -M nose2 -U

- name: Perform python tests
shell: bash
if: always()
run: |
PYTHONPATH="." test-utils/nose_runner -E -s tests

- name: Perform pypy tests
shell: bash
if: always()
run: |
PYTHONPATH=".:/usr/local/lib/python3.10/dist-packages/" \
pypy3 test-utils/nose_runner -E -s tests


- name: Tox testing

# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# move to tox testing, otherwise will have to parametrize
# nose in more details; here tox.ini will apply
# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
shell: bash
if: always()
run: |
pip install tox
echo "Installed tox"
tox
echo "Ran tox"
98 changes: 98 additions & 0 deletions .github/workflows/python3Test.yml
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
name: Test python package dpath-python with regexp extension
# ------------------------------------------------------------
# (C) Alain Lichnewsky, 2021, 2022
#
# For running under Github's Actions
#
# Script performs basic test of the Python-3 version of the package
# including added functionality (regexp in search paths).
# ------------------------------------------------------------

on:
workflow_dispatch:
# Allows manual dispatch from the Actions tab

jobs:
test-python3:

timeout-minutes: 60

runs-on: ubuntu-latest

strategy:
matrix:
# Match versions specified in tox.ini
python-version: ['3.10', 'pypy3.9']

steps:
- name: Checkout code
uses: actions/checkout@main

- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@main
with:
python-version: ${{ matrix.python-version }}
architecture: 'x64'

- name: Ascertain configuration
#
# Collect information concerning $HOME and the location of
# file(s) loaded from Github/
run: |
echo Working dir: $(pwd)
echo Files at this location:
ls -ltha
echo HOME: ${HOME}
echo LANG: ${LANG} SHELL: ${SHELL}
which python
echo LD_LIBRARY_PATH: ${LD_LIBRARY_PATH}
echo PYTHONPATH: \'${PYTHONPATH}\'

# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# ** here (it is expected that) **
# pythonLocation: /opt/hostedtoolcache/Python/3.8.8/x64
# LD_LIBRARY_PATH: /opt/hostedtoolcache/Python/3.8.8/x64/lib
# Working dir /home/runner/work/dpath-python/dpath-python
# HOME: /home/runner
# LANG: C.UTF-8
# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

- name: Install dependencies

# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# requirements install the test framework, which is not
# required by the package in setup.py
# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
run: |
python -m pip install --upgrade pip setuptools wheel \
nose2 hypothesis
if [ -f requirements.txt ]; then
pip install -r requirements.txt;
fi
python setup.py install
echo which nose :$(which nose)
echo which nose2: $(which nose2)
echo which nose2-3.6: $(which nose2-3.6)
echo which nose2-3.8: $(which nose2-3.8)

- name: nose_runner testing

# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# This is the nose2 wrapper that allows to set pgm. parms
# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

run: |
echo running the nose2 wrapper
PYTHONPATH="." test-utils/nose_runner -E -s tests

- name: Tox testing

# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# move to tox testing, otherwise will have to parametrize
# nose in more details; here tox.ini will apply
# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
run: |
pip install tox
echo "Installed tox"
tox
echo "Ran tox"
12 changes: 11 additions & 1 deletion .gitignore
Original file line numberDiff line numberDiff line change
Expand Up@@ -9,4 +9,14 @@ venv_39
.idea/
dpath.egg-info/
dist/
tests/.hypothesis
tests/.hypothesis

# Github logs
.githubLogs

# Test etc
.coverage

# Editor temporaries
*~

74 changes: 74 additions & 0 deletions README.rst
Original file line numberDiff line numberDiff line change
Expand Up@@ -111,6 +111,9 @@ elements in ``x['a']['b']`` where the key is equal to the glob ``'[cd]'``. Okay.
}
}

**Note** : Using Python's `re` regular expressions instead of globs is explained
below re_regexp_.

... Wow that was easy. What if I want to iterate over the results, and
not get a merged view?

Expand DownExpand Up@@ -438,6 +441,77 @@ To get around this, you can sidestep the whole "filesystem path" style, and aban
>>> dpath.get(['a', 'b/c'])
0

.. _re_regexp:

Globs too imprecise? Use Python's `re` Regular Expressions
==========================================================

Python's `re` regular expressions PythonRe_ may be used as follows:

.. _PythonRe: https://docs.python.org/3/library/re.html

- This facility must be enabled (for backwards compatibility):

.. code-block:: python

>>> import dpath
>>> dpath.options.DPATH_ACCEPT_RE_REGEXP = True

- Now a path component may also be specified :

- in a path expression, as {<re.regexpr>} where `<re.regexpr>` is a regular expression
accepted by the standard Python module `re`. For example:

.. code-block:: python

>>> selPath = 'Config/{(Env|Cmd)}'
>>> x = dpath.util.search(js.lod, selPath)

.. code-block:: python

>>> selPath = '{(Config|Graph)}/{(Env|Cmd|Data)}'
>>> x = dpath.util.search(js.lod, selPath)

- When using the list form for a path, a list element can also
be expressed as

- a string as above
- the output of :: `re.compile( args )``

An example:

.. code-block:: python

>>> selPath = [ re.compile('(Config|Graph)') , re.compile('(Env|Cmd|Data)') ]
>>> x = dpath.util.search(js.lod, selPath)

More examples from a realistic json context:

+-----------------------------------------+--------------------------------------+
+ **Extended path glob** | **Designates** +
+-----------------------------------------+--------------------------------------+
+ "\*\*/{[^A-Za-z]{2}$}" | "Id" +
+-----------------------------------------+--------------------------------------+
+ r"\*/{[A-Z][A-Za-z\\d]*$}" | "Name","Id","Created", "Scope",... +
+-----------------------------------------+--------------------------------------+
+ r"\*\*/{[A-Z][A-Za-z\\d]*\d$}" | EnableIPv6" +
+-----------------------------------------+--------------------------------------+
+ r"\*\*/{[A-Z][A-Za-z\\d]*Address$}" | "Containers/199c5/MacAddress" +
+-----------------------------------------+--------------------------------------+

With Python's chararcter string conventions, required backslashes in the `re` syntax
can be entered either in raw strings or using double backslashes, thus
the following are equivalent:

+-----------------------------------------+----------------------------------------+
+ *with raw strings* | *equivalent* with double backslash +
+-----------------------------------------+----------------------------------------+
+ r"\*\*/{[A-Z][A-Za-z\\d]*\\d$}" | "\*\*/{[A-Z][A-Za-z\\\\d]*\\\\d$}" +
+-----------------------------------------+----------------------------------------+
+ r"\*\*/{[A-Z][A-Za-z\\d]*Address$}" | "\*\*/{[A-Z][A-Za-z\\\\d]*Address$}" +
+-----------------------------------------+----------------------------------------+


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

Expand Down
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
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
56 changes: 56 additions & 0 deletions .github/workflows/linterTest.yml
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
name: LinterTest
# ------------------------------------------------------------
# (C) Alain Lichnewsky, 2021, 2022
#
# For running under Github's Actions
#
# Script performs basic static test of the package under Python-3,
# including added functionality.
# ------------------------------------------------------------

# Controls when the action will run.
on:
#
## Not enabled, would triggers the workflow on push or pull request events but
## only for the AL-addRegexp branch.
#push:
# branches: [ AL-addRegexp ]

# Allows to run this workflow manually from the Github Actions tab
workflow_dispatch:

# A workflow run is made up of one or more jobs that can run sequentially or in
# parallel
jobs:
# This workflow contains a single job called "super-lint"
super-lint:
# Steps represent a sequence of tasks that will be executed by the job
# Name the Job
name: Lint code base
# Set the type of machine to run on
runs-on: ubuntu-latest

steps:
# Checks out a copy of your repository on the ubuntu-latest machine
- name: Checkout code
uses: actions/checkout@v2

# Runs a single command using the runners shell, in practice it is useful
# to figure out some of the environment setup
- name: Use shell to figure out environment
run: echo Hello from Github Actions !!;
bash --version | head -1 ;
echo LANG=${LANG} SHELL=${SHELL} ;
echo PATH=${PATH} ;
pwd;
ls -ltha;

# Runs the Super-Linter action
- name: Run Super-Linter
uses: github/super-linter@latest
#
# this script requires some environment variables
#
env:
DEFAULT_BRANCH: AL-master4merge
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
121 changes: 121 additions & 0 deletions .github/workflows/python3-pypy-Test.yml
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
name: Test python package dpath-python with regexp ext and pypy
# ------------------------------------------------------------
# (C) Alain Lichnewsky, 2021, 2022
#
# For running under Github's Actions
#
# Here the idea is to use tox for testing and test on python 3.8 and
# pypy-3.7.
#
# ------------------------------------------------------------

on:
# manual dispatch, this script will not be started automagically
workflow_dispatch:

jobs:
test-python3:

timeout-minutes: 60

runs-on: ubuntu-latest

steps:
- name: Checkout code
uses: actions/checkout@main

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

- name: Set up Pypy
uses: actions/setup-python@main
with:
python-version: 'pypy3.9'
architecture: 'x64'


- name: Ascertain configuration
shell: bash
#
# Collect information concerning $HOME and the location of
# file(s) loaded from Github/
run: |
echo Working dir: $(pwd)
echo Files at this location:
ls -ltha
echo HOME: ${HOME}
echo LANG: ${LANG} SHELL: ${SHELL}
which python
echo LD_LIBRARY_PATH: ${LD_LIBRARY_PATH}
echo PYTHONPATH: \'${PYTHONPATH}\'

# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# ** here (it is expected that) **
# pythonLocation: /opt/hostedtoolcache/Python/3.8.8/x64
# LD_LIBRARY_PATH: /opt/hostedtoolcache/Python/3.8.8/x64/lib
# Working dir /home/runner/work/dpath-python/dpath-python
# HOME: /home/runner
# LANG: C.UTF-8
# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

- name: Install dependencies

# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# requirements install the test framework, which is not
# required by the package in setup.py
# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
shell: bash
run: |
python -m pip install --upgrade pip setuptools wheel
if [ -f requirements.txt ]; then
pip install -r requirements.txt;
fi
python -m pip install --upgrade nose2 hypothesis
python setup.py install
echo which nose :$(which nose)
echo which nose2: $(which nose2)
echo which nose2-3.6: $(which nose2-3.6)
echo which nose2-3.8: $(which nose2-3.8)

- name: Check path preparing for pypy (1)
shell: bash
if: always()
run: |
test-utils/py_path_checker -M nose2 -U

- name: Check path preparing for pypy (2)
shell: bash
if: always()
run: |
pypy3 test-utils/py_path_checker -M nose2 -U

- name: Perform python tests
shell: bash
if: always()
run: |
PYTHONPATH="." test-utils/nose_runner -E -s tests

- name: Perform pypy tests
shell: bash
if: always()
run: |
PYTHONPATH=".:/usr/local/lib/python3.10/dist-packages/" \
pypy3 test-utils/nose_runner -E -s tests


- name: Tox testing

# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# move to tox testing, otherwise will have to parametrize
# nose in more details; here tox.ini will apply
# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
shell: bash
if: always()
run: |
pip install tox
echo "Installed tox"
tox
echo "Ran tox"
98 changes: 98 additions & 0 deletions .github/workflows/python3Test.yml
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
name: Test python package dpath-python with regexp extension
# ------------------------------------------------------------
# (C) Alain Lichnewsky, 2021, 2022
#
# For running under Github's Actions
#
# Script performs basic test of the Python-3 version of the package
# including added functionality (regexp in search paths).
# ------------------------------------------------------------

on:
workflow_dispatch:
# Allows manual dispatch from the Actions tab

jobs:
test-python3:

timeout-minutes: 60

runs-on: ubuntu-latest

strategy:
matrix:
# Match versions specified in tox.ini
python-version: ['3.10', 'pypy3.9']

steps:
- name: Checkout code
uses: actions/checkout@main

- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@main
with:
python-version: ${{ matrix.python-version }}
architecture: 'x64'

- name: Ascertain configuration
#
# Collect information concerning $HOME and the location of
# file(s) loaded from Github/
run: |
echo Working dir: $(pwd)
echo Files at this location:
ls -ltha
echo HOME: ${HOME}
echo LANG: ${LANG} SHELL: ${SHELL}
which python
echo LD_LIBRARY_PATH: ${LD_LIBRARY_PATH}
echo PYTHONPATH: \'${PYTHONPATH}\'

# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# ** here (it is expected that) **
# pythonLocation: /opt/hostedtoolcache/Python/3.8.8/x64
# LD_LIBRARY_PATH: /opt/hostedtoolcache/Python/3.8.8/x64/lib
# Working dir /home/runner/work/dpath-python/dpath-python
# HOME: /home/runner
# LANG: C.UTF-8
# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

- name: Install dependencies

# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# requirements install the test framework, which is not
# required by the package in setup.py
# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
run: |
python -m pip install --upgrade pip setuptools wheel \
nose2 hypothesis
if [ -f requirements.txt ]; then
pip install -r requirements.txt;
fi
python setup.py install
echo which nose :$(which nose)
echo which nose2: $(which nose2)
echo which nose2-3.6: $(which nose2-3.6)
echo which nose2-3.8: $(which nose2-3.8)

- name: nose_runner testing

# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# This is the nose2 wrapper that allows to set pgm. parms
# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

run: |
echo running the nose2 wrapper
PYTHONPATH="." test-utils/nose_runner -E -s tests

- name: Tox testing

# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# move to tox testing, otherwise will have to parametrize
# nose in more details; here tox.ini will apply
# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
run: |
pip install tox
echo "Installed tox"
tox
echo "Ran tox"
12 changes: 11 additions & 1 deletion .gitignore
Original file line numberDiff line numberDiff line change
Expand Up@@ -9,4 +9,14 @@ venv_39
.idea/
dpath.egg-info/
dist/
tests/.hypothesis
tests/.hypothesis

# Github logs
.githubLogs

# Test etc
.coverage

# Editor temporaries
*~

74 changes: 74 additions & 0 deletions README.rst
Original file line numberDiff line numberDiff line change
Expand Up@@ -111,6 +111,9 @@ elements in ``x['a']['b']`` where the key is equal to the glob ``'[cd]'``. Okay.
}
}

**Note** : Using Python's `re` regular expressions instead of globs is explained
below re_regexp_.

... Wow that was easy. What if I want to iterate over the results, and
not get a merged view?

Expand DownExpand Up@@ -438,6 +441,77 @@ To get around this, you can sidestep the whole "filesystem path" style, and aban
>>> dpath.get(['a', 'b/c'])
0

.. _re_regexp:

Globs too imprecise? Use Python's `re` Regular Expressions
==========================================================

Python's `re` regular expressions PythonRe_ may be used as follows:

.. _PythonRe: https://docs.python.org/3/library/re.html

- This facility must be enabled (for backwards compatibility):

.. code-block:: python

>>> import dpath
>>> dpath.options.DPATH_ACCEPT_RE_REGEXP = True

- Now a path component may also be specified :

- in a path expression, as {<re.regexpr>} where `<re.regexpr>` is a regular expression
accepted by the standard Python module `re`. For example:

.. code-block:: python

>>> selPath = 'Config/{(Env|Cmd)}'
>>> x = dpath.util.search(js.lod, selPath)

.. code-block:: python

>>> selPath = '{(Config|Graph)}/{(Env|Cmd|Data)}'
>>> x = dpath.util.search(js.lod, selPath)

- When using the list form for a path, a list element can also
be expressed as

- a string as above
- the output of :: `re.compile( args )``

An example:

.. code-block:: python

>>> selPath = [ re.compile('(Config|Graph)') , re.compile('(Env|Cmd|Data)') ]
>>> x = dpath.util.search(js.lod, selPath)

More examples from a realistic json context:

+-----------------------------------------+--------------------------------------+
+ **Extended path glob** | **Designates** +
+-----------------------------------------+--------------------------------------+
+ "\*\*/{[^A-Za-z]{2}$}" | "Id" +
+-----------------------------------------+--------------------------------------+
+ r"\*/{[A-Z][A-Za-z\\d]*$}" | "Name","Id","Created", "Scope",... +
+-----------------------------------------+--------------------------------------+
+ r"\*\*/{[A-Z][A-Za-z\\d]*\d$}" | EnableIPv6" +
+-----------------------------------------+--------------------------------------+
+ r"\*\*/{[A-Z][A-Za-z\\d]*Address$}" | "Containers/199c5/MacAddress" +
+-----------------------------------------+--------------------------------------+

With Python's chararcter string conventions, required backslashes in the `re` syntax
can be entered either in raw strings or using double backslashes, thus
the following are equivalent:

+-----------------------------------------+----------------------------------------+
+ *with raw strings* | *equivalent* with double backslash +
+-----------------------------------------+----------------------------------------+
+ r"\*\*/{[A-Z][A-Za-z\\d]*\\d$}" | "\*\*/{[A-Z][A-Za-z\\\\d]*\\\\d$}" +
+-----------------------------------------+----------------------------------------+
+ r"\*\*/{[A-Z][A-Za-z\\d]*Address$}" | "\*\*/{[A-Z][A-Za-z\\\\d]*Address$}" +
+-----------------------------------------+----------------------------------------+


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

Expand Down
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
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
56 changes: 56 additions & 0 deletions .github/workflows/linterTest.yml
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
name: LinterTest
# ------------------------------------------------------------
# (C) Alain Lichnewsky, 2021, 2022
#
# For running under Github's Actions
#
# Script performs basic static test of the package under Python-3,
# including added functionality.
# ------------------------------------------------------------

# Controls when the action will run.
on:
#
## Not enabled, would triggers the workflow on push or pull request events but
## only for the AL-addRegexp branch.
#push:
# branches: [ AL-addRegexp ]

# Allows to run this workflow manually from the Github Actions tab
workflow_dispatch:

# A workflow run is made up of one or more jobs that can run sequentially or in
# parallel
jobs:
# This workflow contains a single job called "super-lint"
super-lint:
# Steps represent a sequence of tasks that will be executed by the job
# Name the Job
name: Lint code base
# Set the type of machine to run on
runs-on: ubuntu-latest

steps:
# Checks out a copy of your repository on the ubuntu-latest machine
- name: Checkout code
uses: actions/checkout@v2

# Runs a single command using the runners shell, in practice it is useful
# to figure out some of the environment setup
- name: Use shell to figure out environment
run: echo Hello from Github Actions !!;
bash --version | head -1 ;
echo LANG=${LANG} SHELL=${SHELL} ;
echo PATH=${PATH} ;
pwd;
ls -ltha;

# Runs the Super-Linter action
- name: Run Super-Linter
uses: github/super-linter@latest
#
# this script requires some environment variables
#
env:
DEFAULT_BRANCH: AL-master4merge
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
121 changes: 121 additions & 0 deletions .github/workflows/python3-pypy-Test.yml
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
name: Test python package dpath-python with regexp ext and pypy
# ------------------------------------------------------------
# (C) Alain Lichnewsky, 2021, 2022
#
# For running under Github's Actions
#
# Here the idea is to use tox for testing and test on python 3.8 and
# pypy-3.7.
#
# ------------------------------------------------------------

on:
# manual dispatch, this script will not be started automagically
workflow_dispatch:

jobs:
test-python3:

timeout-minutes: 60

runs-on: ubuntu-latest

steps:
- name: Checkout code
uses: actions/checkout@main

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

- name: Set up Pypy
uses: actions/setup-python@main
with:
python-version: 'pypy3.9'
architecture: 'x64'


- name: Ascertain configuration
shell: bash
#
# Collect information concerning $HOME and the location of
# file(s) loaded from Github/
run: |
echo Working dir: $(pwd)
echo Files at this location:
ls -ltha
echo HOME: ${HOME}
echo LANG: ${LANG} SHELL: ${SHELL}
which python
echo LD_LIBRARY_PATH: ${LD_LIBRARY_PATH}
echo PYTHONPATH: \'${PYTHONPATH}\'

# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# ** here (it is expected that) **
# pythonLocation: /opt/hostedtoolcache/Python/3.8.8/x64
# LD_LIBRARY_PATH: /opt/hostedtoolcache/Python/3.8.8/x64/lib
# Working dir /home/runner/work/dpath-python/dpath-python
# HOME: /home/runner
# LANG: C.UTF-8
# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

- name: Install dependencies

# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# requirements install the test framework, which is not
# required by the package in setup.py
# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
shell: bash
run: |
python -m pip install --upgrade pip setuptools wheel
if [ -f requirements.txt ]; then
pip install -r requirements.txt;
fi
python -m pip install --upgrade nose2 hypothesis
python setup.py install
echo which nose :$(which nose)
echo which nose2: $(which nose2)
echo which nose2-3.6: $(which nose2-3.6)
echo which nose2-3.8: $(which nose2-3.8)

- name: Check path preparing for pypy (1)
shell: bash
if: always()
run: |
test-utils/py_path_checker -M nose2 -U

- name: Check path preparing for pypy (2)
shell: bash
if: always()
run: |
pypy3 test-utils/py_path_checker -M nose2 -U

- name: Perform python tests
shell: bash
if: always()
run: |
PYTHONPATH="." test-utils/nose_runner -E -s tests

- name: Perform pypy tests
shell: bash
if: always()
run: |
PYTHONPATH=".:/usr/local/lib/python3.10/dist-packages/" \
pypy3 test-utils/nose_runner -E -s tests


- name: Tox testing

# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# move to tox testing, otherwise will have to parametrize
# nose in more details; here tox.ini will apply
# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
shell: bash
if: always()
run: |
pip install tox
echo "Installed tox"
tox
echo "Ran tox"
98 changes: 98 additions & 0 deletions .github/workflows/python3Test.yml
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
name: Test python package dpath-python with regexp extension
# ------------------------------------------------------------
# (C) Alain Lichnewsky, 2021, 2022
#
# For running under Github's Actions
#
# Script performs basic test of the Python-3 version of the package
# including added functionality (regexp in search paths).
# ------------------------------------------------------------

on:
workflow_dispatch:
# Allows manual dispatch from the Actions tab

jobs:
test-python3:

timeout-minutes: 60

runs-on: ubuntu-latest

strategy:
matrix:
# Match versions specified in tox.ini
python-version: ['3.10', 'pypy3.9']

steps:
- name: Checkout code
uses: actions/checkout@main

- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@main
with:
python-version: ${{ matrix.python-version }}
architecture: 'x64'

- name: Ascertain configuration
#
# Collect information concerning $HOME and the location of
# file(s) loaded from Github/
run: |
echo Working dir: $(pwd)
echo Files at this location:
ls -ltha
echo HOME: ${HOME}
echo LANG: ${LANG} SHELL: ${SHELL}
which python
echo LD_LIBRARY_PATH: ${LD_LIBRARY_PATH}
echo PYTHONPATH: \'${PYTHONPATH}\'

# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# ** here (it is expected that) **
# pythonLocation: /opt/hostedtoolcache/Python/3.8.8/x64
# LD_LIBRARY_PATH: /opt/hostedtoolcache/Python/3.8.8/x64/lib
# Working dir /home/runner/work/dpath-python/dpath-python
# HOME: /home/runner
# LANG: C.UTF-8
# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

- name: Install dependencies

# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# requirements install the test framework, which is not
# required by the package in setup.py
# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
run: |
python -m pip install --upgrade pip setuptools wheel \
nose2 hypothesis
if [ -f requirements.txt ]; then
pip install -r requirements.txt;
fi
python setup.py install
echo which nose :$(which nose)
echo which nose2: $(which nose2)
echo which nose2-3.6: $(which nose2-3.6)
echo which nose2-3.8: $(which nose2-3.8)

- name: nose_runner testing

# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# This is the nose2 wrapper that allows to set pgm. parms
# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

run: |
echo running the nose2 wrapper
PYTHONPATH="." test-utils/nose_runner -E -s tests

- name: Tox testing

# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# move to tox testing, otherwise will have to parametrize
# nose in more details; here tox.ini will apply
# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
run: |
pip install tox
echo "Installed tox"
tox
echo "Ran tox"
12 changes: 11 additions & 1 deletion .gitignore
Original file line numberDiff line numberDiff line change
Expand Up@@ -9,4 +9,14 @@ venv_39
.idea/
dpath.egg-info/
dist/
tests/.hypothesis
tests/.hypothesis

# Github logs
.githubLogs

# Test etc
.coverage

# Editor temporaries
*~

74 changes: 74 additions & 0 deletions README.rst
Original file line numberDiff line numberDiff line change
Expand Up@@ -111,6 +111,9 @@ elements in ``x['a']['b']`` where the key is equal to the glob ``'[cd]'``. Okay.
}
}

**Note** : Using Python's `re` regular expressions instead of globs is explained
below re_regexp_.

... Wow that was easy. What if I want to iterate over the results, and
not get a merged view?

Expand DownExpand Up@@ -438,6 +441,77 @@ To get around this, you can sidestep the whole "filesystem path" style, and aban
>>> dpath.get(['a', 'b/c'])
0

.. _re_regexp:

Globs too imprecise? Use Python's `re` Regular Expressions
==========================================================

Python's `re` regular expressions PythonRe_ may be used as follows:

.. _PythonRe: https://docs.python.org/3/library/re.html

- This facility must be enabled (for backwards compatibility):

.. code-block:: python

>>> import dpath
>>> dpath.options.DPATH_ACCEPT_RE_REGEXP = True

- Now a path component may also be specified :

- in a path expression, as {<re.regexpr>} where `<re.regexpr>` is a regular expression
accepted by the standard Python module `re`. For example:

.. code-block:: python

>>> selPath = 'Config/{(Env|Cmd)}'
>>> x = dpath.util.search(js.lod, selPath)

.. code-block:: python

>>> selPath = '{(Config|Graph)}/{(Env|Cmd|Data)}'
>>> x = dpath.util.search(js.lod, selPath)

- When using the list form for a path, a list element can also
be expressed as

- a string as above
- the output of :: `re.compile( args )``

An example:

.. code-block:: python

>>> selPath = [ re.compile('(Config|Graph)') , re.compile('(Env|Cmd|Data)') ]
>>> x = dpath.util.search(js.lod, selPath)

More examples from a realistic json context:

+-----------------------------------------+--------------------------------------+
+ **Extended path glob** | **Designates** +
+-----------------------------------------+--------------------------------------+
+ "\*\*/{[^A-Za-z]{2}$}" | "Id" +
+-----------------------------------------+--------------------------------------+
+ r"\*/{[A-Z][A-Za-z\\d]*$}" | "Name","Id","Created", "Scope",... +
+-----------------------------------------+--------------------------------------+
+ r"\*\*/{[A-Z][A-Za-z\\d]*\d$}" | EnableIPv6" +
+-----------------------------------------+--------------------------------------+
+ r"\*\*/{[A-Z][A-Za-z\\d]*Address$}" | "Containers/199c5/MacAddress" +
+-----------------------------------------+--------------------------------------+

With Python's chararcter string conventions, required backslashes in the `re` syntax
can be entered either in raw strings or using double backslashes, thus
the following are equivalent:

+-----------------------------------------+----------------------------------------+
+ *with raw strings* | *equivalent* with double backslash +
+-----------------------------------------+----------------------------------------+
+ r"\*\*/{[A-Z][A-Za-z\\d]*\\d$}" | "\*\*/{[A-Z][A-Za-z\\\\d]*\\\\d$}" +
+-----------------------------------------+----------------------------------------+
+ r"\*\*/{[A-Z][A-Za-z\\d]*Address$}" | "\*\*/{[A-Z][A-Za-z\\\\d]*Address$}" +
+-----------------------------------------+----------------------------------------+


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

Expand Down
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
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
56 changes: 56 additions & 0 deletions .github/workflows/linterTest.yml
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
name: LinterTest
# ------------------------------------------------------------
# (C) Alain Lichnewsky, 2021, 2022
#
# For running under Github's Actions
#
# Script performs basic static test of the package under Python-3,
# including added functionality.
# ------------------------------------------------------------

# Controls when the action will run.
on:
#
## Not enabled, would triggers the workflow on push or pull request events but
## only for the AL-addRegexp branch.
#push:
# branches: [ AL-addRegexp ]

# Allows to run this workflow manually from the Github Actions tab
workflow_dispatch:

# A workflow run is made up of one or more jobs that can run sequentially or in
# parallel
jobs:
# This workflow contains a single job called "super-lint"
super-lint:
# Steps represent a sequence of tasks that will be executed by the job
# Name the Job
name: Lint code base
# Set the type of machine to run on
runs-on: ubuntu-latest

steps:
# Checks out a copy of your repository on the ubuntu-latest machine
- name: Checkout code
uses: actions/checkout@v2

# Runs a single command using the runners shell, in practice it is useful
# to figure out some of the environment setup
- name: Use shell to figure out environment
run: echo Hello from Github Actions !!;
bash --version | head -1 ;
echo LANG=${LANG} SHELL=${SHELL} ;
echo PATH=${PATH} ;
pwd;
ls -ltha;

# Runs the Super-Linter action
- name: Run Super-Linter
uses: github/super-linter@latest
#
# this script requires some environment variables
#
env:
DEFAULT_BRANCH: AL-master4merge
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
121 changes: 121 additions & 0 deletions .github/workflows/python3-pypy-Test.yml
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
name: Test python package dpath-python with regexp ext and pypy
# ------------------------------------------------------------
# (C) Alain Lichnewsky, 2021, 2022
#
# For running under Github's Actions
#
# Here the idea is to use tox for testing and test on python 3.8 and
# pypy-3.7.
#
# ------------------------------------------------------------

on:
# manual dispatch, this script will not be started automagically
workflow_dispatch:

jobs:
test-python3:

timeout-minutes: 60

runs-on: ubuntu-latest

steps:
- name: Checkout code
uses: actions/checkout@main

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

- name: Set up Pypy
uses: actions/setup-python@main
with:
python-version: 'pypy3.9'
architecture: 'x64'


- name: Ascertain configuration
shell: bash
#
# Collect information concerning $HOME and the location of
# file(s) loaded from Github/
run: |
echo Working dir: $(pwd)
echo Files at this location:
ls -ltha
echo HOME: ${HOME}
echo LANG: ${LANG} SHELL: ${SHELL}
which python
echo LD_LIBRARY_PATH: ${LD_LIBRARY_PATH}
echo PYTHONPATH: \'${PYTHONPATH}\'

# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# ** here (it is expected that) **
# pythonLocation: /opt/hostedtoolcache/Python/3.8.8/x64
# LD_LIBRARY_PATH: /opt/hostedtoolcache/Python/3.8.8/x64/lib
# Working dir /home/runner/work/dpath-python/dpath-python
# HOME: /home/runner
# LANG: C.UTF-8
# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

- name: Install dependencies

# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# requirements install the test framework, which is not
# required by the package in setup.py
# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
shell: bash
run: |
python -m pip install --upgrade pip setuptools wheel
if [ -f requirements.txt ]; then
pip install -r requirements.txt;
fi
python -m pip install --upgrade nose2 hypothesis
python setup.py install
echo which nose :$(which nose)
echo which nose2: $(which nose2)
echo which nose2-3.6: $(which nose2-3.6)
echo which nose2-3.8: $(which nose2-3.8)

- name: Check path preparing for pypy (1)
shell: bash
if: always()
run: |
test-utils/py_path_checker -M nose2 -U

- name: Check path preparing for pypy (2)
shell: bash
if: always()
run: |
pypy3 test-utils/py_path_checker -M nose2 -U

- name: Perform python tests
shell: bash
if: always()
run: |
PYTHONPATH="." test-utils/nose_runner -E -s tests

- name: Perform pypy tests
shell: bash
if: always()
run: |
PYTHONPATH=".:/usr/local/lib/python3.10/dist-packages/" \
pypy3 test-utils/nose_runner -E -s tests


- name: Tox testing

# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# move to tox testing, otherwise will have to parametrize
# nose in more details; here tox.ini will apply
# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
shell: bash
if: always()
run: |
pip install tox
echo "Installed tox"
tox
echo "Ran tox"
98 changes: 98 additions & 0 deletions .github/workflows/python3Test.yml
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
name: Test python package dpath-python with regexp extension
# ------------------------------------------------------------
# (C) Alain Lichnewsky, 2021, 2022
#
# For running under Github's Actions
#
# Script performs basic test of the Python-3 version of the package
# including added functionality (regexp in search paths).
# ------------------------------------------------------------

on:
workflow_dispatch:
# Allows manual dispatch from the Actions tab

jobs:
test-python3:

timeout-minutes: 60

runs-on: ubuntu-latest

strategy:
matrix:
# Match versions specified in tox.ini
python-version: ['3.10', 'pypy3.9']

steps:
- name: Checkout code
uses: actions/checkout@main

- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@main
with:
python-version: ${{ matrix.python-version }}
architecture: 'x64'

- name: Ascertain configuration
#
# Collect information concerning $HOME and the location of
# file(s) loaded from Github/
run: |
echo Working dir: $(pwd)
echo Files at this location:
ls -ltha
echo HOME: ${HOME}
echo LANG: ${LANG} SHELL: ${SHELL}
which python
echo LD_LIBRARY_PATH: ${LD_LIBRARY_PATH}
echo PYTHONPATH: \'${PYTHONPATH}\'

# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# ** here (it is expected that) **
# pythonLocation: /opt/hostedtoolcache/Python/3.8.8/x64
# LD_LIBRARY_PATH: /opt/hostedtoolcache/Python/3.8.8/x64/lib
# Working dir /home/runner/work/dpath-python/dpath-python
# HOME: /home/runner
# LANG: C.UTF-8
# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

- name: Install dependencies

# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# requirements install the test framework, which is not
# required by the package in setup.py
# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
run: |
python -m pip install --upgrade pip setuptools wheel \
nose2 hypothesis
if [ -f requirements.txt ]; then
pip install -r requirements.txt;
fi
python setup.py install
echo which nose :$(which nose)
echo which nose2: $(which nose2)
echo which nose2-3.6: $(which nose2-3.6)
echo which nose2-3.8: $(which nose2-3.8)

- name: nose_runner testing

# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# This is the nose2 wrapper that allows to set pgm. parms
# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

run: |
echo running the nose2 wrapper
PYTHONPATH="." test-utils/nose_runner -E -s tests

- name: Tox testing

# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# move to tox testing, otherwise will have to parametrize
# nose in more details; here tox.ini will apply
# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
run: |
pip install tox
echo "Installed tox"
tox
echo "Ran tox"
12 changes: 11 additions & 1 deletion .gitignore
Original file line numberDiff line numberDiff line change
Expand Up@@ -9,4 +9,14 @@ venv_39
.idea/
dpath.egg-info/
dist/
tests/.hypothesis
tests/.hypothesis

# Github logs
.githubLogs

# Test etc
.coverage

# Editor temporaries
*~

74 changes: 74 additions & 0 deletions README.rst
Original file line numberDiff line numberDiff line change
Expand Up@@ -111,6 +111,9 @@ elements in ``x['a']['b']`` where the key is equal to the glob ``'[cd]'``. Okay.
}
}

**Note** : Using Python's `re` regular expressions instead of globs is explained
below re_regexp_.

... Wow that was easy. What if I want to iterate over the results, and
not get a merged view?

Expand DownExpand Up@@ -438,6 +441,77 @@ To get around this, you can sidestep the whole "filesystem path" style, and aban
>>> dpath.get(['a', 'b/c'])
0

.. _re_regexp:

Globs too imprecise? Use Python's `re` Regular Expressions
==========================================================

Python's `re` regular expressions PythonRe_ may be used as follows:

.. _PythonRe: https://docs.python.org/3/library/re.html

- This facility must be enabled (for backwards compatibility):

.. code-block:: python

>>> import dpath
>>> dpath.options.DPATH_ACCEPT_RE_REGEXP = True

- Now a path component may also be specified :

- in a path expression, as {<re.regexpr>} where `<re.regexpr>` is a regular expression
accepted by the standard Python module `re`. For example:

.. code-block:: python

>>> selPath = 'Config/{(Env|Cmd)}'
>>> x = dpath.util.search(js.lod, selPath)

.. code-block:: python

>>> selPath = '{(Config|Graph)}/{(Env|Cmd|Data)}'
>>> x = dpath.util.search(js.lod, selPath)

- When using the list form for a path, a list element can also
be expressed as

- a string as above
- the output of :: `re.compile( args )``

An example:

.. code-block:: python

>>> selPath = [ re.compile('(Config|Graph)') , re.compile('(Env|Cmd|Data)') ]
>>> x = dpath.util.search(js.lod, selPath)

More examples from a realistic json context:

+-----------------------------------------+--------------------------------------+
+ **Extended path glob** | **Designates** +
+-----------------------------------------+--------------------------------------+
+ "\*\*/{[^A-Za-z]{2}$}" | "Id" +
+-----------------------------------------+--------------------------------------+
+ r"\*/{[A-Z][A-Za-z\\d]*$}" | "Name","Id","Created", "Scope",... +
+-----------------------------------------+--------------------------------------+
+ r"\*\*/{[A-Z][A-Za-z\\d]*\d$}" | EnableIPv6" +
+-----------------------------------------+--------------------------------------+
+ r"\*\*/{[A-Z][A-Za-z\\d]*Address$}" | "Containers/199c5/MacAddress" +
+-----------------------------------------+--------------------------------------+

With Python's chararcter string conventions, required backslashes in the `re` syntax
can be entered either in raw strings or using double backslashes, thus
the following are equivalent:

+-----------------------------------------+----------------------------------------+
+ *with raw strings* | *equivalent* with double backslash +
+-----------------------------------------+----------------------------------------+
+ r"\*\*/{[A-Z][A-Za-z\\d]*\\d$}" | "\*\*/{[A-Z][A-Za-z\\\\d]*\\\\d$}" +
+-----------------------------------------+----------------------------------------+
+ r"\*\*/{[A-Z][A-Za-z\\d]*Address$}" | "\*\*/{[A-Z][A-Za-z\\\\d]*Address$}" +
+-----------------------------------------+----------------------------------------+


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

Expand Down
Loading