<86>Jul 25 07:52:41 userdel[436755]: delete user 'rooter' <86>Jul 25 07:52:41 userdel[436755]: removed group 'rooter' owned by 'rooter' <86>Jul 25 07:52:41 userdel[436755]: removed shadow group 'rooter' owned by 'rooter' <86>Jul 25 07:52:41 groupadd[436854]: group added to /etc/group: name=rooter, GID=2855 <86>Jul 25 07:52:41 groupadd[436854]: group added to /etc/gshadow: name=rooter <86>Jul 25 07:52:41 groupadd[436854]: new group: name=rooter, GID=2855 <86>Jul 25 07:52:41 useradd[436916]: new user: name=rooter, UID=2855, GID=2855, home=/root, shell=/bin/bash, from=none <86>Jul 25 07:52:41 userdel[437030]: delete user 'builder' <86>Jul 25 07:52:41 userdel[437030]: removed group 'builder' owned by 'builder' <86>Jul 25 07:52:41 userdel[437030]: removed shadow group 'builder' owned by 'builder' <86>Jul 25 07:52:41 groupadd[437096]: group added to /etc/group: name=builder, GID=2856 <86>Jul 25 07:52:41 groupadd[437096]: group added to /etc/gshadow: name=builder <86>Jul 25 07:52:41 groupadd[437096]: new group: name=builder, GID=2856 <86>Jul 25 07:52:41 useradd[437167]: new user: name=builder, UID=2856, GID=2856, home=/usr/src, shell=/bin/bash, from=none <13>Jul 25 07:52:43 rpmi: libgdbm6-1.26-alt1 sisyphus+418729.200.2.1 1779276077 installed <13>Jul 25 07:52:43 rpmi: libgdbm_compat4-1.26-alt1 sisyphus+418729.200.2.1 1779276077 installed <13>Jul 25 07:52:43 rpmi: libsqlite3-3.50.4-alt1 sisyphus+391668.100.1.1 1754321138 installed <13>Jul 25 07:52:43 rpmi: libmpdec3-2.5.1-alt3 sisyphus+314490.500.5.1 1675432033 installed <13>Jul 25 07:52:43 rpmi: libexpat-2.7.4-alt1 sisyphus+407132.100.1.1 1770196717 installed <13>Jul 25 07:52:43 rpmi: openssl-config-3.5.0-alt1 sisyphus+399237.100.1.1 1762346864 installed <13>Jul 25 07:52:43 rpmi: libp11-kit-1:0.26.2-alt3.g0eedd4d sisyphus+424637.100.1.1 1783530782 installed <13>Jul 25 07:52:43 rpmi: libtasn1-4.21.0-alt2 sisyphus+420751.100.1.1 1781163748 installed <13>Jul 25 07:52:43 rpmi: rpm-macros-alternatives-0.5.3-alt1 sisyphus+371878.100.1.1 1737988822 installed <13>Jul 25 07:52:43 rpmi: alternatives-0.5.3-alt1 sisyphus+371878.100.1.1 1737988822 installed <13>Jul 25 07:52:43 rpmi: ca-certificates-2026.04.22-alt1 sisyphus+415942.100.6.1 1777316293 installed <13>Jul 25 07:52:43 rpmi: ca-trust-0.2.0-alt1 sisyphus+344843.100.1.1 1712743326 installed <13>Jul 25 07:52:43 rpmi: p11-kit-trust-1:0.26.2-alt3.g0eedd4d sisyphus+424637.100.1.1 1783530782 installed <13>Jul 25 07:52:43 rpmi: libcrypto3-3.5.7-alt1 sisyphus+425332.100.3.1 1784733668 installed <13>Jul 25 07:52:43 rpmi: libssl3-3.5.7-alt1 sisyphus+425332.100.3.1 1784733668 installed <13>Jul 25 07:52:43 rpmi: python3-modules-sqlite3-3.14.6-alt1 sisyphus+423624.100.33.1 1784227742 installed <13>Jul 25 07:52:43 rpmi: python3-3.14.6-alt1 sisyphus+423624.100.33.1 1784227742 installed <13>Jul 25 07:52:43 rpmi: python3-base-3.14.6-alt1 sisyphus+423624.100.33.1 1784227742 installed <13>Jul 25 07:52:43 rpmi: python3-module-py3dephell-0.3.1-alt1 sisyphus+365261.200.1.1 1734463433 installed <13>Jul 25 07:52:43 rpmi: tests-for-installed-python3-pkgs-0.1.29-alt1 sisyphus+398029.2500.12.1 1762716341 installed <13>Jul 25 07:52:43 rpmi: rpm-build-python3-0.1.29-alt1 sisyphus+398029.2500.12.1 1762716341 installed <13>Jul 25 07:52:45 rpmi: python3-module-packaging-26.2-alt1 sisyphus+416502.100.2.1 1777385153 installed <13>Jul 25 07:52:45 rpmi: python3-module-platformdirs-4.10.0-alt1 sisyphus+419460.100.1.1 1779982322 installed <13>Jul 25 07:52:45 rpmi: python3-module-system-seed-wheels-0.0.2-alt1 sisyphus+384227.200.3.1 1747487299 installed <13>Jul 25 07:52:45 rpmi: python3-module-more-itertools-11.1.0-alt1 sisyphus+419223.100.2.1 1779891386 installed <13>Jul 25 07:52:45 rpmi: python3-module-jaraco.functools-4.6.0-alt1 sisyphus+425293.100.1.2 1784631981 installed <13>Jul 25 07:52:45 rpmi: python3-module-shellingham-1.5.4-alt1 sisyphus+332574.100.1.1 1698135363 installed <13>Jul 25 07:52:45 rpmi: python3-module-filelock-3.25.2-alt1.1 sisyphus+413497.1200.2.1 1774829675 installed <13>Jul 25 07:52:45 rpmi: python3-module-fastjsonschema-2.21.2-alt1 sisyphus+393815.100.1.1 1756817231 installed <13>Jul 25 07:52:45 rpmi: python3-module-urllib3-2:2.7.0-alt2 sisyphus+423624.121100.34.1 1784353520 installed <13>Jul 25 07:52:45 rpmi: python3-module-idna-3.18-alt1 sisyphus+420750.100.1.1 1781166339 installed <13>Jul 25 07:52:45 rpmi: python3-module-propcache-0.5.2-alt1 sisyphus+423624.3300.33.1 1784229893 installed <13>Jul 25 07:52:45 rpmi: python3-module-multidict-6.7.1-alt1 sisyphus+423624.3200.33.1 1784229862 installed <13>Jul 25 07:52:45 rpmi: python3-module-typing_extensions-4.15.0-alt2 sisyphus+399838.100.1.1 1762946472 installed <13>Jul 25 07:52:45 rpmi: python3-module-frozenlist-1.8.0-alt1 sisyphus+423624.3000.33.1 1784229800 installed <13>Jul 25 07:52:45 rpmi: python3-module-Pygments-2.20.0-alt1 sisyphus+413985.100.1.1 1775208360 installed <13>Jul 25 07:52:45 rpmi: python3-module-aiosignal-1.4.0-alt1 sisyphus+389519.40.2.1 1752483607 installed <13>Jul 25 07:52:45 rpmi: python3-module-yarl-1.24.2-alt1 sisyphus+423624.3500.33.1 1784230065 installed <13>Jul 25 07:52:45 rpmi: python3-module-python-discovery-1.4.4-alt1 sisyphus+424706.100.1.1 1783598324 installed <13>Jul 25 07:52:45 rpmi: python3-module-pip-wheel-26.1.2-alt1 sisyphus+419707.100.2.1 1780313939 installed <13>Jul 25 07:52:45 rpmi: python3-module-setuptools-wheel-1:83.0.0-alt1 sisyphus+424341.100.2.1 1783427124 installed <13>Jul 25 07:52:45 rpmi: python3-module-system-seed-wheels-wheels-0.0.2-alt1 sisyphus+384227.200.3.1 1747487299 installed <13>Jul 25 07:52:45 rpmi: python3-module-findpython-0.7.1-alt1 sisyphus+415217.400.1.1 1776350955 installed <13>Jul 25 07:52:45 rpmi: python3-module-wheel-0.47.0-alt1 sisyphus+416101.100.1.1 1776938753 installed <13>Jul 25 07:52:45 rpmi: python3-module-tomlkit-0.14.0-alt1 sisyphus+407344.100.1.1 1770368823 installed <13>Jul 25 07:52:45 rpmi: python3-module-tomli-2.4.1-alt1.1 sisyphus+413490.300.2.1 1774831804 installed <13>Jul 25 07:52:45 rpmi: python3-module-poetry-alt-namespace-0.0.1-alt1 sisyphus+306728.100.1.1 1663083685 installed <13>Jul 25 07:52:45 rpmi: python3-module-pluggy-1.6.0-alt1.1 sisyphus+413474.300.2.1 1774829688 installed <13>Jul 25 07:52:45 rpmi: python3-module-pkginfo-1.12.1.2-alt2.1 sisyphus+413484.200.1.2 1774825432 installed <13>Jul 25 07:52:45 rpmi: python3-module-pbs-installer-2026.04.07-alt1 sisyphus+415217.600.1.1 1776351039 installed <13>Jul 25 07:52:45 rpmi: python3-module-lark-1.3.1-alt2 sisyphus+413685.100.1.1 1774947082 installed <13>Jul 25 07:52:45 rpmi: python3-module-poetry-core-2.4.1-alt1 sisyphus+419127.100.2.1 1779717398 installed <13>Jul 25 07:52:45 rpmi: python3-module-markupsafe-1:3.0.3-alt1 sisyphus+423624.700.33.1 1784228296 installed <13>Jul 25 07:52:45 rpmi: python3-module-uc-micro-py-2.0.0-alt1 sisyphus+411114.100.1.1 1773327270 installed <13>Jul 25 07:52:45 rpmi: python3-module-linkify-it-py-2.1.0-alt1.1 sisyphus+413476.100.1.1 1774817789 installed <13>Jul 25 07:52:45 rpmi: python3-module-mdurl-0.1.2-alt1 sisyphus+318894.1000.3.1 1682420700 installed <13>Jul 25 07:52:45 rpmi: python3-module-markdown-it-4.0.0-alt1 sisyphus+394327.100.1.1 1757330325 installed <13>Jul 25 07:52:45 rpmi: python3-module-rich-15.0.0-alt1 sisyphus+415092.100.2.1 1776162196 installed <13>Jul 25 07:52:45 rpmi: python3-module-jaraco.context-6.1.2-alt1 sisyphus+412384.100.1.1 1774283927 installed <13>Jul 25 07:52:45 rpmi: python3-module-installer-1.0.1-alt1 sisyphus+418210.100.1.1 1778834707 installed <13>Jul 25 07:52:45 rpmi: python3-module-iniconfig-2.3.0-alt1 sisyphus+397749.100.2.1 1761040670 installed <13>Jul 25 07:52:45 rpmi: python3-module-et_xmlfile-1.1.0-alt1 sisyphus+300537.100.1.1 1653384154 installed <13>Jul 25 07:52:45 rpmi: python3-module-fastimport-0.9.16-alt1 sisyphus+399246.100.1.1 1762354708 installed <13>Jul 25 07:52:45 rpmi: python3-module-dns-1:2.8.0-alt1 sisyphus+410244.100.2.1 1772799795 installed <13>Jul 25 07:52:45 rpmi: python3-module-ttp-0.9.5-alt2 sisyphus+334469.100.2.1 1700146901 installed <13>Jul 25 07:52:45 rpmi: python3-module-distlib-0.4.3-alt1 sisyphus+421408.100.1.1 1781515263 installed <13>Jul 25 07:52:45 rpmi: python3-module-virtualenv-21.6.1-alt1 sisyphus+425273.100.2.2 1784633155 installed <13>Jul 25 07:52:45 rpmi: python3-module-orderly-set-5.5.0-alt1 sisyphus+395806.100.1.1 1758823641 installed <13>Jul 25 07:52:45 rpmi: python3-module-click-8.4.2-alt1 sisyphus+422757.100.2.1 1782720497 installed <13>Jul 25 07:52:45 rpmi: python3-module-cleo-2.2.1-alt1 sisyphus+362876.200.1.1 1731956909 installed <13>Jul 25 07:52:45 rpmi: python3-module-pycparser-2.23-alt1 sisyphus+410417.100.1.1 1772989663 installed <13>Jul 25 07:52:45 rpmi: python3-module-cffi-2.1.0-alt1 sisyphus+423624.540.33.1 1784228272 installed <13>Jul 25 07:52:45 rpmi: python3-module-cryptography-49.0.0-alt1 sisyphus+423624.1000.33.1 1784228350 installed <13>Jul 25 07:52:45 rpmi: python3-module-openssl-26.3.0-alt1 sisyphus+422651.200.1.1 1782380583 installed <13>Jul 25 07:52:45 rpmi: python3-module-charset-normalizer-3.4.9-alt1 sisyphus+424623.100.1.1 1783521675 installed <13>Jul 25 07:52:45 rpmi: python3-module-requests-2.34.2-alt1 sisyphus+418161.200.3.1 1779090568 installed <13>Jul 25 07:52:45 rpmi: python3-module-requests_toolbelt-1.0.0-alt3 sisyphus+338996.100.1.1 1706201427 installed <13>Jul 25 07:52:45 rpmi: python3-module-msgpack-1.1.2-alt1 sisyphus+423624.2260.33.1 1784229029 installed <13>Jul 25 07:52:45 rpmi: python3-module-cachecontrol-0.14.4-alt1.1 sisyphus+407625.300.1.1 1770565054 installed <13>Jul 25 07:52:45 rpmi: python3-module-pyproject_hooks-1.2.0-alt1 sisyphus+386406.100.1.1 1749203250 installed <13>Jul 25 07:52:45 rpmi: python3-module-build-1.5.1-alt1 sisyphus+424770.100.1.1 1783674248 installed <13>Jul 25 07:52:45 rpmi: python3-module-annotated_doc-0.0.4-alt1 sisyphus+401429.100.1.1 1764433640 installed <13>Jul 25 07:52:45 rpmi: python3-module-typer-0.27.0-alt1 sisyphus+426477.440.2.1 1784895769 installed <13>Jul 25 07:52:45 rpmi: python3-module-typer-slim-0.27.0-alt1 sisyphus+426477.440.2.1 1784895769 installed <13>Jul 25 07:52:45 rpmi: python3-module-jaraco.text-4.2.0-alt1 sisyphus+408107.100.3.1 1771429608 installed <13>Jul 25 07:52:45 rpmi: python3-module-pkg-resources-1:80.10.2-alt2.1 sisyphus+413485.1000.2.3 1774838477 installed <13>Jul 25 07:52:45 rpmi: python3-module-attrs-26.1.0-alt1 sisyphus+414432.100.1.1 1775561563 installed <13>Jul 25 07:52:45 rpmi: python3-module-aiohappyeyeballs-2.7.1-alt1 sisyphus+426561.100.1.1 1784892115 installed <13>Jul 25 07:52:45 rpmi: libyaml2-6.0.2-alt1 sisyphus+393301.100.1.1 1756210811 installed <13>Jul 25 07:52:46 rpmi: libpython3-3.14.6-alt1 sisyphus+423624.100.33.1 1784227742 installed <13>Jul 25 07:52:46 rpmi: python3-dev-3.14.6-alt1 sisyphus+423624.100.33.1 1784227742 installed <13>Jul 25 07:52:46 rpmi: libopenblas-0.3.34-alt1 sisyphus+425559.100.2.2 1784643580 installed <13>Jul 25 07:52:46 rpmi: libllhttp-9.4.2-alt1 sisyphus+421860.100.1.1 1781867203 installed <13>Jul 25 07:52:46 rpmi: python3-module-aiohttp-3.14.1-alt2 sisyphus+423624.4700.33.1 1784230460 installed <13>Jul 25 07:52:46 rpmi: python3-module-dulwich-1.2.12-alt1 sisyphus+425297.200.2.1 1784717431 installed <13>Jul 25 07:52:46 rpmi: libquadmath0-15.2.1-alt2 sisyphus+416693.300.3.1 1777480577 installed <13>Jul 25 07:52:46 rpmi: libgfortran5-15.2.1-alt2 sisyphus+416693.300.3.1 1777480577 installed <13>Jul 25 07:52:47 rpmi: libblas-2:3.12.1-alt2 sisyphus+426308.100.1.2 1784758707 installed <13>Jul 25 07:52:47 rpmi: liblapack-2:3.12.1-alt2 sisyphus+426308.100.1.2 1784758707 installed <13>Jul 25 07:52:47 rpmi: python3-module-numpy-1:2.4.2-alt2 sisyphus+423624.2400.33.1 1784229649 installed <13>Jul 25 07:52:47 rpmi: python3-module-openpyxl-3.1.5-alt1 sisyphus+367462.100.1.1 1735668246 installed <13>Jul 25 07:52:47 rpmi: python3-module-poetry-2.4.1-alt1 sisyphus+418102.100.1.1 1778752274 installed <13>Jul 25 07:52:47 rpmi: python3-module-setuptools-1:83.0.0-alt1 sisyphus+424341.100.2.1 1783427124 installed <13>Jul 25 07:52:47 rpmi: python3-module-yaml-6.0.3-alt1 sisyphus+423624.2274.33.1 1784229099 installed <13>Jul 25 07:52:47 rpmi: python3-module-deepdiff-8.6.1-alt1 sisyphus+395806.200.1.1 1758823684 installed <13>Jul 25 07:52:47 rpmi: python3-module-ttp_templates-0.3.6-alt1 sisyphus+337664.2500.3.1 1704822682 installed <13>Jul 25 07:52:47 rpmi: python3-module-pytest-9.0.3-alt1 sisyphus+414567.100.1.1 1775647126 installed <13>Jul 25 07:52:47 rpmi: python3-module-jinja2-3.1.6-alt2 sisyphus+413629.100.1.1 1774945546 installed <13>Jul 25 07:52:47 rpmi: python3-module-tabulate-0.10.0-alt1.1 sisyphus+413479.1200.1.3 1774822957 installed <13>Jul 25 07:52:47 rpmi: python3-module-cerberus-1.3.8-alt1 sisyphus+406242.100.1.1 1769411599 installed Building target platforms: i586 Building for target i586 Wrote: /usr/src/in/nosrpm/python3-module-ttp-0.9.5-alt2.nosrc.rpm (w1.gzdio) <13>Jul 25 07:52:48 rpmi: python3-module-pyproject-installer-0.6.0-alt1 sisyphus+424779.100.1.1 1783678406 installed Installing python3-module-ttp-0.9.5-alt2.src.rpm Building target platforms: i586 Building for target i586 Executing(%prep): /bin/sh -e /usr/src/tmp/rpmb-tmp.lH6j76 + umask 022 + /bin/mkdir -p /usr/src/RPM/BUILD + cd /usr/src/RPM/BUILD + cd /usr/src/RPM/BUILD + rm -rf ttp-0.9.5 + echo 'Source #0 (ttp-0.9.5.tar):' Source #0 (ttp-0.9.5.tar): + /bin/tar -xf /usr/src/RPM/SOURCES/ttp-0.9.5.tar + cd ttp-0.9.5 + /bin/chmod -c -Rf u+rwX,go-w . + rm -f ttp/utils/load_python_exec_py2.py + echo 'Patch #1 (fix-broken-tests.patch):' Patch #1 (fix-broken-tests.patch): + /usr/bin/patch -p1 patching file test/pytest/test_output_formatters.py + exit 0 Executing(%build): /bin/sh -e /usr/src/tmp/rpmb-tmp.zbfiyv + umask 022 + /bin/mkdir -p /usr/src/RPM/BUILD + cd /usr/src/RPM/BUILD + cd ttp-0.9.5 + export 'CFLAGS=-pipe -frecord-gcc-switches -Wall -g -O2 -flto=auto -march=i586 -mtune=generic' + CFLAGS='-pipe -frecord-gcc-switches -Wall -g -O2 -flto=auto -march=i586 -mtune=generic' + export 'CXXFLAGS=-pipe -frecord-gcc-switches -Wall -g -O2 -flto=auto -march=i586 -mtune=generic' + CXXFLAGS='-pipe -frecord-gcc-switches -Wall -g -O2 -flto=auto -march=i586 -mtune=generic' + export 'FFLAGS=-pipe -frecord-gcc-switches -Wall -g -O2 -flto=auto -march=i586 -mtune=generic' + FFLAGS='-pipe -frecord-gcc-switches -Wall -g -O2 -flto=auto -march=i586 -mtune=generic' + /usr/bin/python3 -m pyproject_installer -v build INFO : pyproject_installer.build_cmd._build : Building wheel INFO : pyproject_installer.build_cmd._build : Source tree: /usr/src/RPM/BUILD/ttp-0.9.5 INFO : pyproject_installer.build_cmd._build : Output dir: /usr/src/RPM/BUILD/ttp-0.9.5/dist DEBUG : pyproject_installer.lib.build_backend : Validating source path DEBUG : pyproject_installer.lib.build_backend : Checking for PEP517 spec DEBUG : pyproject_installer.lib.build_backend : Parsing configuration file: /usr/src/RPM/BUILD/ttp-0.9.5/pyproject.toml INFO : backend_caller.py : Calling hook build_wheel in subprocess INFO : backend_caller.py : Build backend: poetry.core.masonry.api INFO : backend_caller.py : Hook args: ['/usr/src/RPM/BUILD/ttp-0.9.5/dist'] INFO : backend_caller.py : Hook kwargs: {'config_settings': None} WARNING : poetry.core.factory : The "poetry.dev-dependencies" section is deprecated and will be removed in a future version. Use "poetry.group.dev.dependencies" instead. INFO : poetry.core.masonry.builders.wheel : Building wheel DEBUG : poetry.core.masonry.builders.builder : Adding: /usr/src/RPM/BUILD/ttp-0.9.5/ttp/__init__.py DEBUG : poetry.core.masonry.builders.builder : Adding: /usr/src/RPM/BUILD/ttp-0.9.5/ttp/formatters/__init__.py DEBUG : poetry.core.masonry.builders.builder : Adding: /usr/src/RPM/BUILD/ttp-0.9.5/ttp/formatters/csv_formatter.py DEBUG : poetry.core.masonry.builders.builder : Adding: /usr/src/RPM/BUILD/ttp-0.9.5/ttp/formatters/excel_formatter.py DEBUG : poetry.core.masonry.builders.builder : Adding: /usr/src/RPM/BUILD/ttp-0.9.5/ttp/formatters/jinja2_formatter.py DEBUG : poetry.core.masonry.builders.builder : Adding: /usr/src/RPM/BUILD/ttp-0.9.5/ttp/formatters/json_formatter.py DEBUG : poetry.core.masonry.builders.builder : Adding: /usr/src/RPM/BUILD/ttp-0.9.5/ttp/formatters/n2g_formatter.py DEBUG : poetry.core.masonry.builders.builder : Adding: /usr/src/RPM/BUILD/ttp-0.9.5/ttp/formatters/pprint_formatter.py DEBUG : poetry.core.masonry.builders.builder : Adding: /usr/src/RPM/BUILD/ttp-0.9.5/ttp/formatters/raw_formatter.py DEBUG : poetry.core.masonry.builders.builder : Adding: /usr/src/RPM/BUILD/ttp-0.9.5/ttp/formatters/table_formatter.py DEBUG : poetry.core.masonry.builders.builder : Adding: /usr/src/RPM/BUILD/ttp-0.9.5/ttp/formatters/tabulate_formatter.py DEBUG : poetry.core.masonry.builders.builder : Adding: /usr/src/RPM/BUILD/ttp-0.9.5/ttp/formatters/yaml_formatter.py DEBUG : poetry.core.masonry.builders.builder : Adding: /usr/src/RPM/BUILD/ttp-0.9.5/ttp/group/__init__.py DEBUG : poetry.core.masonry.builders.builder : Adding: /usr/src/RPM/BUILD/ttp-0.9.5/ttp/group/contains.py DEBUG : poetry.core.masonry.builders.builder : Adding: /usr/src/RPM/BUILD/ttp-0.9.5/ttp/group/contains_val.py DEBUG : poetry.core.masonry.builders.builder : Adding: /usr/src/RPM/BUILD/ttp-0.9.5/ttp/group/containsall.py DEBUG : poetry.core.masonry.builders.builder : Adding: /usr/src/RPM/BUILD/ttp-0.9.5/ttp/group/delete.py DEBUG : poetry.core.masonry.builders.builder : Adding: /usr/src/RPM/BUILD/ttp-0.9.5/ttp/group/equal.py DEBUG : poetry.core.masonry.builders.builder : Adding: /usr/src/RPM/BUILD/ttp-0.9.5/ttp/group/exclude.py DEBUG : poetry.core.masonry.builders.builder : Adding: /usr/src/RPM/BUILD/ttp-0.9.5/ttp/group/exclude_val.py DEBUG : poetry.core.masonry.builders.builder : Adding: /usr/src/RPM/BUILD/ttp-0.9.5/ttp/group/excludeall.py DEBUG : poetry.core.masonry.builders.builder : Adding: /usr/src/RPM/BUILD/ttp-0.9.5/ttp/group/expand.py DEBUG : poetry.core.masonry.builders.builder : Adding: /usr/src/RPM/BUILD/ttp-0.9.5/ttp/group/itemize.py DEBUG : poetry.core.masonry.builders.builder : Adding: /usr/src/RPM/BUILD/ttp-0.9.5/ttp/group/items2dict.py DEBUG : poetry.core.masonry.builders.builder : Adding: /usr/src/RPM/BUILD/ttp-0.9.5/ttp/group/lookup.py DEBUG : poetry.core.masonry.builders.builder : Adding: /usr/src/RPM/BUILD/ttp-0.9.5/ttp/group/macro.py DEBUG : poetry.core.masonry.builders.builder : Adding: /usr/src/RPM/BUILD/ttp-0.9.5/ttp/group/record.py DEBUG : poetry.core.masonry.builders.builder : Adding: /usr/src/RPM/BUILD/ttp-0.9.5/ttp/group/set_.py DEBUG : poetry.core.masonry.builders.builder : Adding: /usr/src/RPM/BUILD/ttp-0.9.5/ttp/group/sformat.py DEBUG : poetry.core.masonry.builders.builder : Adding: /usr/src/RPM/BUILD/ttp-0.9.5/ttp/group/to_converters.py DEBUG : poetry.core.masonry.builders.builder : Adding: /usr/src/RPM/BUILD/ttp-0.9.5/ttp/group/to_ip.py DEBUG : poetry.core.masonry.builders.builder : Adding: /usr/src/RPM/BUILD/ttp-0.9.5/ttp/group/validate_cerberus.py DEBUG : poetry.core.masonry.builders.builder : Adding: /usr/src/RPM/BUILD/ttp-0.9.5/ttp/group/void.py DEBUG : poetry.core.masonry.builders.builder : Adding: /usr/src/RPM/BUILD/ttp-0.9.5/ttp/input/__init__.py DEBUG : poetry.core.masonry.builders.builder : Adding: /usr/src/RPM/BUILD/ttp-0.9.5/ttp/input/commands.py DEBUG : poetry.core.masonry.builders.builder : Adding: /usr/src/RPM/BUILD/ttp-0.9.5/ttp/input/macro.py DEBUG : poetry.core.masonry.builders.builder : Adding: /usr/src/RPM/BUILD/ttp-0.9.5/ttp/input/test.py DEBUG : poetry.core.masonry.builders.builder : Adding: /usr/src/RPM/BUILD/ttp-0.9.5/ttp/lookup/__init__.py DEBUG : poetry.core.masonry.builders.builder : Adding: /usr/src/RPM/BUILD/ttp-0.9.5/ttp/lookup/geoip2.py DEBUG : poetry.core.masonry.builders.builder : Adding: /usr/src/RPM/BUILD/ttp-0.9.5/ttp/match/__init__.py DEBUG : poetry.core.masonry.builders.builder : Adding: /usr/src/RPM/BUILD/ttp-0.9.5/ttp/match/copy_.py DEBUG : poetry.core.masonry.builders.builder : Adding: /usr/src/RPM/BUILD/ttp-0.9.5/ttp/match/count.py DEBUG : poetry.core.masonry.builders.builder : Adding: /usr/src/RPM/BUILD/ttp-0.9.5/ttp/match/dns_lookups.py DEBUG : poetry.core.masonry.builders.builder : Adding: /usr/src/RPM/BUILD/ttp-0.9.5/ttp/match/geoip_lookup.py DEBUG : poetry.core.masonry.builders.builder : Adding: /usr/src/RPM/BUILD/ttp-0.9.5/ttp/match/ip.py DEBUG : poetry.core.masonry.builders.builder : Adding: /usr/src/RPM/BUILD/ttp-0.9.5/ttp/match/item.py DEBUG : poetry.core.masonry.builders.builder : Adding: /usr/src/RPM/BUILD/ttp-0.9.5/ttp/match/joinmatches.py DEBUG : poetry.core.masonry.builders.builder : Adding: /usr/src/RPM/BUILD/ttp-0.9.5/ttp/match/let.py DEBUG : poetry.core.masonry.builders.builder : Adding: /usr/src/RPM/BUILD/ttp-0.9.5/ttp/match/lookup.py DEBUG : poetry.core.masonry.builders.builder : Adding: /usr/src/RPM/BUILD/ttp-0.9.5/ttp/match/mac_eui.py DEBUG : poetry.core.masonry.builders.builder : Adding: /usr/src/RPM/BUILD/ttp-0.9.5/ttp/match/macro.py DEBUG : poetry.core.masonry.builders.builder : Adding: /usr/src/RPM/BUILD/ttp-0.9.5/ttp/match/raise_.py DEBUG : poetry.core.masonry.builders.builder : Adding: /usr/src/RPM/BUILD/ttp-0.9.5/ttp/match/re_.py DEBUG : poetry.core.masonry.builders.builder : Adding: /usr/src/RPM/BUILD/ttp-0.9.5/ttp/match/record.py DEBUG : poetry.core.masonry.builders.builder : Adding: /usr/src/RPM/BUILD/ttp-0.9.5/ttp/match/set_.py DEBUG : poetry.core.masonry.builders.builder : Adding: /usr/src/RPM/BUILD/ttp-0.9.5/ttp/match/string.py DEBUG : poetry.core.masonry.builders.builder : Adding: /usr/src/RPM/BUILD/ttp-0.9.5/ttp/match/to.py DEBUG : poetry.core.masonry.builders.builder : Adding: /usr/src/RPM/BUILD/ttp-0.9.5/ttp/match/unrange.py DEBUG : poetry.core.masonry.builders.builder : Adding: /usr/src/RPM/BUILD/ttp-0.9.5/ttp/match/uptimeparse.py DEBUG : poetry.core.masonry.builders.builder : Adding: /usr/src/RPM/BUILD/ttp-0.9.5/ttp/match/void.py DEBUG : poetry.core.masonry.builders.builder : Adding: /usr/src/RPM/BUILD/ttp-0.9.5/ttp/output/__init__.py DEBUG : poetry.core.masonry.builders.builder : Adding: /usr/src/RPM/BUILD/ttp-0.9.5/ttp/output/deepdiffer.py DEBUG : poetry.core.masonry.builders.builder : Adding: /usr/src/RPM/BUILD/ttp-0.9.5/ttp/output/is_equal.py DEBUG : poetry.core.masonry.builders.builder : Adding: /usr/src/RPM/BUILD/ttp-0.9.5/ttp/output/macro.py DEBUG : poetry.core.masonry.builders.builder : Adding: /usr/src/RPM/BUILD/ttp-0.9.5/ttp/output/transform.py DEBUG : poetry.core.masonry.builders.builder : Adding: /usr/src/RPM/BUILD/ttp-0.9.5/ttp/output/validate_cerberus.py DEBUG : poetry.core.masonry.builders.builder : Adding: /usr/src/RPM/BUILD/ttp-0.9.5/ttp/output/validate_yangson.py DEBUG : poetry.core.masonry.builders.builder : Adding: /usr/src/RPM/BUILD/ttp-0.9.5/ttp/patterns/__init__.py DEBUG : poetry.core.masonry.builders.builder : Adding: /usr/src/RPM/BUILD/ttp-0.9.5/ttp/patterns/get_pattern.py DEBUG : poetry.core.masonry.builders.builder : Adding: /usr/src/RPM/BUILD/ttp-0.9.5/ttp/returners/__init__.py DEBUG : poetry.core.masonry.builders.builder : Adding: /usr/src/RPM/BUILD/ttp-0.9.5/ttp/returners/file_returner.py DEBUG : poetry.core.masonry.builders.builder : Adding: /usr/src/RPM/BUILD/ttp-0.9.5/ttp/returners/self_returner.py DEBUG : poetry.core.masonry.builders.builder : Adding: /usr/src/RPM/BUILD/ttp-0.9.5/ttp/returners/syslog_returner.py DEBUG : poetry.core.masonry.builders.builder : Adding: /usr/src/RPM/BUILD/ttp-0.9.5/ttp/returners/terminal_returner.py DEBUG : poetry.core.masonry.builders.builder : Adding: /usr/src/RPM/BUILD/ttp-0.9.5/ttp/ttp.py DEBUG : poetry.core.masonry.builders.builder : Adding: /usr/src/RPM/BUILD/ttp-0.9.5/ttp/utils/__init__.py DEBUG : poetry.core.masonry.builders.builder : Adding: /usr/src/RPM/BUILD/ttp-0.9.5/ttp/utils/get_attributes.py DEBUG : poetry.core.masonry.builders.builder : Adding: /usr/src/RPM/BUILD/ttp-0.9.5/ttp/utils/guess.py DEBUG : poetry.core.masonry.builders.builder : Adding: /usr/src/RPM/BUILD/ttp-0.9.5/ttp/utils/load_python_exec_py3.py DEBUG : poetry.core.masonry.builders.builder : Adding: /usr/src/RPM/BUILD/ttp-0.9.5/ttp/utils/loaders.py DEBUG : poetry.core.masonry.builders.builder : Adding: /usr/src/RPM/BUILD/ttp-0.9.5/ttp/utils/quick_parse.py DEBUG : poetry.core.masonry.builders.builder : Adding: /usr/src/RPM/BUILD/ttp-0.9.5/ttp/variable/__init__.py DEBUG : poetry.core.masonry.builders.builder : Adding: /usr/src/RPM/BUILD/ttp-0.9.5/ttp/variable/getfilename.py DEBUG : poetry.core.masonry.builders.builder : Adding: /usr/src/RPM/BUILD/ttp-0.9.5/ttp/variable/gethostname.py DEBUG : poetry.core.masonry.builders.builder : Adding: /usr/src/RPM/BUILD/ttp-0.9.5/ttp/variable/time_funcs.py INFO : poetry.core.masonry.builders.wheel : Built ttp-0.9.5-py2.py3-none-any.whl INFO : pyproject_installer.build_cmd._build : Built wheel: ttp-0.9.5-py2.py3-none-any.whl + exit 0 Executing(%install): /bin/sh -e /usr/src/tmp/rpmb-tmp.hhHkuY + umask 022 + /bin/mkdir -p /usr/src/RPM/BUILD + cd /usr/src/RPM/BUILD + /bin/chmod -Rf u+rwX -- /usr/src/tmp/python3-module-ttp-buildroot + : + /bin/rm -rf -- /usr/src/tmp/python3-module-ttp-buildroot + PATH=/usr/libexec/rpm-build:/usr/src/bin:/usr/bin:/bin:/usr/local/bin:/usr/games + cd ttp-0.9.5 + /usr/bin/python3 -m pyproject_installer -v install --destdir=/usr/src/tmp/python3-module-ttp-buildroot INFO : pyproject_installer.install_cmd._install : Installing wheel INFO : pyproject_installer.install_cmd._install : Wheel directory: /usr/src/RPM/BUILD/ttp-0.9.5/dist INFO : pyproject_installer.install_cmd._install : Wheel filename: ttp-0.9.5-py2.py3-none-any.whl INFO : pyproject_installer.install_cmd._install : Destination: /usr/src/tmp/python3-module-ttp-buildroot DEBUG : pyproject_installer.lib.wheel : Parsing wheel filename DEBUG : pyproject_installer.lib.wheel : Validating wheel file DEBUG : pyproject_installer.lib.wheel : Validating wheel spec version DEBUG : pyproject_installer.lib.wheel : Parsing wheel spec metadata DEBUG : pyproject_installer.lib.wheel : Validating RECORD INFO : pyproject_installer.install_cmd._install : Wheel installation root: /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages DEBUG : pyproject_installer.install_cmd._install : Filtering out not allowed file: ttp-0.9.5.dist-info/WHEEL DEBUG : pyproject_installer.install_cmd._install : Filtering out not allowed file: ttp-0.9.5.dist-info/licenses/LICENSE DEBUG : pyproject_installer.install_cmd._install : Filtering out not allowed file: ttp-0.9.5.dist-info/RECORD INFO : pyproject_installer.install_cmd._install : Extracting wheel INFO : pyproject_installer.install_cmd._install : Generating entrypoints scripts DEBUG : pyproject_installer.lib.scripts : Installing console script: ttp INFO : pyproject_installer.install_cmd._install : Wheel was installed + /usr/lib/rpm/brp-alt Cleaning files in /usr/src/tmp/python3-module-ttp-buildroot (auto) Verifying and fixing files in /usr/src/tmp/python3-module-ttp-buildroot (binconfig,pkgconfig,libtool,desktop,gnuconfig) Checking contents of files in /usr/src/tmp/python3-module-ttp-buildroot/ (default) Compressing files in /usr/src/tmp/python3-module-ttp-buildroot (auto) Adjusting library links in /usr/src/tmp/python3-module-ttp-buildroot ./usr/lib: (from :0) Verifying ELF objects in /usr/src/tmp/python3-module-ttp-buildroot (arch=normal,fhs=normal,lfs=relaxed,lint=relaxed,rpath=normal,stack=normal,textrel=normal,unresolved=normal) Splitting links to aliased files under /{,s}bin in /usr/src/tmp/python3-module-ttp-buildroot Bytecompiling python3 modules in /usr/src/tmp/python3-module-ttp-buildroot using /usr/bin/python3 /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/returners/terminal_returner.py:36: SyntaxWarning: "is" with 'int' literal. Did you mean "=="? if _ttp_["python_major_version"] is 2: /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/returners/terminal_returner.py:43: SyntaxWarning: "is" with 'int' literal. Did you mean "=="? elif _ttp_["python_major_version"] is 3: compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/formatters/__init__.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/formatters/csv_formatter.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/formatters/excel_formatter.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/formatters/jinja2_formatter.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/formatters/json_formatter.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/formatters/n2g_formatter.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/formatters/pprint_formatter.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/formatters/raw_formatter.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/formatters/table_formatter.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/formatters/tabulate_formatter.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/formatters/yaml_formatter.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/group/__init__.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/group/contains.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/group/contains_val.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/group/containsall.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/group/delete.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/group/equal.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/group/exclude.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/group/exclude_val.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/group/excludeall.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/group/expand.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/group/itemize.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/group/items2dict.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/group/lookup.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/group/macro.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/group/record.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/group/set_.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/group/sformat.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/group/to_converters.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/group/to_ip.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/group/validate_cerberus.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/group/void.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/input/__init__.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/input/commands.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/input/macro.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/input/test.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/lookup/__init__.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/lookup/geoip2.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/match/__init__.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/match/copy_.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/match/count.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/match/dns_lookups.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/match/geoip_lookup.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/match/ip.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/match/item.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/match/joinmatches.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/match/let.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/match/lookup.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/match/mac_eui.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/match/macro.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/match/raise_.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/match/re_.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/match/record.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/match/set_.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/match/string.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/match/to.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/match/unrange.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/match/uptimeparse.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/match/void.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/output/__init__.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/output/deepdiffer.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/output/is_equal.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/output/macro.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/output/transform.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/output/validate_cerberus.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/output/validate_yangson.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/patterns/__init__.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/patterns/get_pattern.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/returners/__init__.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/returners/file_returner.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/returners/self_returner.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/returners/syslog_returner.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/returners/terminal_returner.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/utils/__init__.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/utils/get_attributes.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/utils/guess.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/utils/load_python_exec_py3.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/utils/loaders.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/utils/quick_parse.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/variable/__init__.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/variable/getfilename.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/variable/gethostname.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/variable/time_funcs.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/__init__.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/ttp.py Bytecompiling python3 modules with optimization in /usr/src/tmp/python3-module-ttp-buildroot using /usr/bin/python3 -O /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/returners/terminal_returner.py:36: SyntaxWarning: "is" with 'int' literal. Did you mean "=="? if _ttp_["python_major_version"] is 2: /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/returners/terminal_returner.py:43: SyntaxWarning: "is" with 'int' literal. Did you mean "=="? elif _ttp_["python_major_version"] is 3: compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/formatters/__init__.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/formatters/csv_formatter.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/formatters/excel_formatter.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/formatters/jinja2_formatter.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/formatters/json_formatter.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/formatters/n2g_formatter.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/formatters/pprint_formatter.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/formatters/raw_formatter.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/formatters/table_formatter.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/formatters/tabulate_formatter.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/formatters/yaml_formatter.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/group/__init__.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/group/contains.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/group/contains_val.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/group/containsall.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/group/delete.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/group/equal.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/group/exclude.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/group/exclude_val.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/group/excludeall.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/group/expand.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/group/itemize.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/group/items2dict.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/group/lookup.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/group/macro.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/group/record.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/group/set_.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/group/sformat.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/group/to_converters.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/group/to_ip.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/group/validate_cerberus.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/group/void.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/input/__init__.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/input/commands.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/input/macro.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/input/test.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/lookup/__init__.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/lookup/geoip2.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/match/__init__.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/match/copy_.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/match/count.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/match/dns_lookups.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/match/geoip_lookup.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/match/ip.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/match/item.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/match/joinmatches.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/match/let.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/match/lookup.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/match/mac_eui.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/match/macro.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/match/raise_.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/match/re_.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/match/record.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/match/set_.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/match/string.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/match/to.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/match/unrange.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/match/uptimeparse.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/match/void.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/output/__init__.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/output/deepdiffer.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/output/is_equal.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/output/macro.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/output/transform.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/output/validate_cerberus.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/output/validate_yangson.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/patterns/__init__.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/patterns/get_pattern.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/returners/__init__.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/returners/file_returner.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/returners/self_returner.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/returners/syslog_returner.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/returners/terminal_returner.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/utils/__init__.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/utils/get_attributes.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/utils/guess.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/utils/load_python_exec_py3.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/utils/loaders.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/utils/quick_parse.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/variable/__init__.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/variable/getfilename.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/variable/gethostname.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/variable/time_funcs.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/__init__.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/ttp.py Bytecompiling python3 modules with optimization-2 in /usr/src/tmp/python3-module-ttp-buildroot using /usr/bin/python3 -OO /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/returners/terminal_returner.py:36: SyntaxWarning: "is" with 'int' literal. Did you mean "=="? if _ttp_["python_major_version"] is 2: /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/returners/terminal_returner.py:43: SyntaxWarning: "is" with 'int' literal. Did you mean "=="? elif _ttp_["python_major_version"] is 3: compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/formatters/__init__.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/formatters/csv_formatter.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/formatters/excel_formatter.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/formatters/jinja2_formatter.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/formatters/json_formatter.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/formatters/n2g_formatter.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/formatters/pprint_formatter.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/formatters/raw_formatter.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/formatters/table_formatter.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/formatters/tabulate_formatter.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/formatters/yaml_formatter.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/group/__init__.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/group/contains.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/group/contains_val.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/group/containsall.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/group/delete.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/group/equal.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/group/exclude.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/group/exclude_val.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/group/excludeall.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/group/expand.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/group/itemize.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/group/items2dict.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/group/lookup.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/group/macro.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/group/record.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/group/set_.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/group/sformat.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/group/to_converters.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/group/to_ip.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/group/validate_cerberus.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/group/void.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/input/__init__.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/input/commands.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/input/macro.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/input/test.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/lookup/__init__.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/lookup/geoip2.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/match/__init__.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/match/copy_.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/match/count.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/match/dns_lookups.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/match/geoip_lookup.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/match/ip.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/match/item.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/match/joinmatches.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/match/let.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/match/lookup.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/match/mac_eui.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/match/macro.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/match/raise_.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/match/re_.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/match/record.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/match/set_.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/match/string.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/match/to.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/match/unrange.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/match/uptimeparse.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/match/void.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/output/__init__.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/output/deepdiffer.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/output/is_equal.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/output/macro.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/output/transform.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/output/validate_cerberus.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/output/validate_yangson.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/patterns/__init__.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/patterns/get_pattern.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/returners/__init__.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/returners/file_returner.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/returners/self_returner.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/returners/syslog_returner.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/returners/terminal_returner.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/utils/__init__.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/utils/get_attributes.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/utils/guess.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/utils/load_python_exec_py3.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/utils/loaders.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/utils/quick_parse.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/variable/__init__.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/variable/getfilename.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/variable/gethostname.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/variable/time_funcs.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/__init__.py compile /usr/src/tmp/python3-module-ttp-buildroot/usr/lib/python3/site-packages/ttp/ttp.py Hardlinking identical .pyc and .opt-?.pyc files './usr/lib/python3/site-packages/ttp/__pycache__/__init__.cpython-314.opt-1.pyc' => './usr/lib/python3/site-packages/ttp/__pycache__/__init__.cpython-314.pyc' './usr/lib/python3/site-packages/ttp/__pycache__/__init__.cpython-314.opt-2.pyc' => './usr/lib/python3/site-packages/ttp/__pycache__/__init__.cpython-314.opt-1.pyc' './usr/lib/python3/site-packages/ttp/__pycache__/ttp.cpython-314.opt-1.pyc' => './usr/lib/python3/site-packages/ttp/__pycache__/ttp.cpython-314.pyc' './usr/lib/python3/site-packages/ttp/formatters/__pycache__/__init__.cpython-314.opt-1.pyc' => './usr/lib/python3/site-packages/ttp/formatters/__pycache__/__init__.cpython-314.pyc' './usr/lib/python3/site-packages/ttp/formatters/__pycache__/__init__.cpython-314.opt-2.pyc' => './usr/lib/python3/site-packages/ttp/formatters/__pycache__/__init__.cpython-314.opt-1.pyc' './usr/lib/python3/site-packages/ttp/formatters/__pycache__/csv_formatter.cpython-314.opt-1.pyc' => './usr/lib/python3/site-packages/ttp/formatters/__pycache__/csv_formatter.cpython-314.pyc' './usr/lib/python3/site-packages/ttp/formatters/__pycache__/excel_formatter.cpython-314.opt-1.pyc' => './usr/lib/python3/site-packages/ttp/formatters/__pycache__/excel_formatter.cpython-314.pyc' './usr/lib/python3/site-packages/ttp/formatters/__pycache__/jinja2_formatter.cpython-314.opt-1.pyc' => './usr/lib/python3/site-packages/ttp/formatters/__pycache__/jinja2_formatter.cpython-314.pyc' './usr/lib/python3/site-packages/ttp/formatters/__pycache__/json_formatter.cpython-314.opt-1.pyc' => './usr/lib/python3/site-packages/ttp/formatters/__pycache__/json_formatter.cpython-314.pyc' './usr/lib/python3/site-packages/ttp/formatters/__pycache__/n2g_formatter.cpython-314.opt-1.pyc' => './usr/lib/python3/site-packages/ttp/formatters/__pycache__/n2g_formatter.cpython-314.pyc' './usr/lib/python3/site-packages/ttp/formatters/__pycache__/n2g_formatter.cpython-314.opt-2.pyc' => './usr/lib/python3/site-packages/ttp/formatters/__pycache__/n2g_formatter.cpython-314.opt-1.pyc' './usr/lib/python3/site-packages/ttp/formatters/__pycache__/pprint_formatter.cpython-314.opt-1.pyc' => './usr/lib/python3/site-packages/ttp/formatters/__pycache__/pprint_formatter.cpython-314.pyc' './usr/lib/python3/site-packages/ttp/formatters/__pycache__/raw_formatter.cpython-314.opt-1.pyc' => './usr/lib/python3/site-packages/ttp/formatters/__pycache__/raw_formatter.cpython-314.pyc' './usr/lib/python3/site-packages/ttp/formatters/__pycache__/table_formatter.cpython-314.opt-1.pyc' => './usr/lib/python3/site-packages/ttp/formatters/__pycache__/table_formatter.cpython-314.pyc' './usr/lib/python3/site-packages/ttp/formatters/__pycache__/tabulate_formatter.cpython-314.opt-1.pyc' => './usr/lib/python3/site-packages/ttp/formatters/__pycache__/tabulate_formatter.cpython-314.pyc' './usr/lib/python3/site-packages/ttp/formatters/__pycache__/yaml_formatter.cpython-314.opt-1.pyc' => './usr/lib/python3/site-packages/ttp/formatters/__pycache__/yaml_formatter.cpython-314.pyc' './usr/lib/python3/site-packages/ttp/group/__pycache__/__init__.cpython-314.opt-1.pyc' => './usr/lib/python3/site-packages/ttp/group/__pycache__/__init__.cpython-314.pyc' './usr/lib/python3/site-packages/ttp/group/__pycache__/__init__.cpython-314.opt-2.pyc' => './usr/lib/python3/site-packages/ttp/group/__pycache__/__init__.cpython-314.opt-1.pyc' './usr/lib/python3/site-packages/ttp/group/__pycache__/contains.cpython-314.opt-1.pyc' => './usr/lib/python3/site-packages/ttp/group/__pycache__/contains.cpython-314.pyc' './usr/lib/python3/site-packages/ttp/group/__pycache__/contains.cpython-314.opt-2.pyc' => './usr/lib/python3/site-packages/ttp/group/__pycache__/contains.cpython-314.opt-1.pyc' './usr/lib/python3/site-packages/ttp/group/__pycache__/contains_val.cpython-314.opt-1.pyc' => './usr/lib/python3/site-packages/ttp/group/__pycache__/contains_val.cpython-314.pyc' './usr/lib/python3/site-packages/ttp/group/__pycache__/containsall.cpython-314.opt-1.pyc' => './usr/lib/python3/site-packages/ttp/group/__pycache__/containsall.cpython-314.pyc' './usr/lib/python3/site-packages/ttp/group/__pycache__/containsall.cpython-314.opt-2.pyc' => './usr/lib/python3/site-packages/ttp/group/__pycache__/containsall.cpython-314.opt-1.pyc' './usr/lib/python3/site-packages/ttp/group/__pycache__/delete.cpython-314.opt-1.pyc' => './usr/lib/python3/site-packages/ttp/group/__pycache__/delete.cpython-314.pyc' './usr/lib/python3/site-packages/ttp/group/__pycache__/delete.cpython-314.opt-2.pyc' => './usr/lib/python3/site-packages/ttp/group/__pycache__/delete.cpython-314.opt-1.pyc' './usr/lib/python3/site-packages/ttp/group/__pycache__/equal.cpython-314.opt-1.pyc' => './usr/lib/python3/site-packages/ttp/group/__pycache__/equal.cpython-314.pyc' './usr/lib/python3/site-packages/ttp/group/__pycache__/exclude.cpython-314.opt-1.pyc' => './usr/lib/python3/site-packages/ttp/group/__pycache__/exclude.cpython-314.pyc' './usr/lib/python3/site-packages/ttp/group/__pycache__/exclude.cpython-314.opt-2.pyc' => './usr/lib/python3/site-packages/ttp/group/__pycache__/exclude.cpython-314.opt-1.pyc' './usr/lib/python3/site-packages/ttp/group/__pycache__/exclude_val.cpython-314.opt-1.pyc' => './usr/lib/python3/site-packages/ttp/group/__pycache__/exclude_val.cpython-314.pyc' './usr/lib/python3/site-packages/ttp/group/__pycache__/excludeall.cpython-314.opt-1.pyc' => './usr/lib/python3/site-packages/ttp/group/__pycache__/excludeall.cpython-314.pyc' './usr/lib/python3/site-packages/ttp/group/__pycache__/excludeall.cpython-314.opt-2.pyc' => './usr/lib/python3/site-packages/ttp/group/__pycache__/excludeall.cpython-314.opt-1.pyc' './usr/lib/python3/site-packages/ttp/group/__pycache__/expand.cpython-314.opt-1.pyc' => './usr/lib/python3/site-packages/ttp/group/__pycache__/expand.cpython-314.pyc' './usr/lib/python3/site-packages/ttp/group/__pycache__/itemize.cpython-314.opt-1.pyc' => './usr/lib/python3/site-packages/ttp/group/__pycache__/itemize.cpython-314.pyc' './usr/lib/python3/site-packages/ttp/group/__pycache__/itemize.cpython-314.opt-2.pyc' => './usr/lib/python3/site-packages/ttp/group/__pycache__/itemize.cpython-314.opt-1.pyc' './usr/lib/python3/site-packages/ttp/group/__pycache__/items2dict.cpython-314.opt-1.pyc' => './usr/lib/python3/site-packages/ttp/group/__pycache__/items2dict.cpython-314.pyc' './usr/lib/python3/site-packages/ttp/group/__pycache__/lookup.cpython-314.opt-1.pyc' => './usr/lib/python3/site-packages/ttp/group/__pycache__/lookup.cpython-314.pyc' './usr/lib/python3/site-packages/ttp/group/__pycache__/lookup.cpython-314.opt-2.pyc' => './usr/lib/python3/site-packages/ttp/group/__pycache__/lookup.cpython-314.opt-1.pyc' './usr/lib/python3/site-packages/ttp/group/__pycache__/macro.cpython-314.opt-1.pyc' => './usr/lib/python3/site-packages/ttp/group/__pycache__/macro.cpython-314.pyc' './usr/lib/python3/site-packages/ttp/group/__pycache__/macro.cpython-314.opt-2.pyc' => './usr/lib/python3/site-packages/ttp/group/__pycache__/macro.cpython-314.opt-1.pyc' './usr/lib/python3/site-packages/ttp/group/__pycache__/record.cpython-314.opt-1.pyc' => './usr/lib/python3/site-packages/ttp/group/__pycache__/record.cpython-314.pyc' './usr/lib/python3/site-packages/ttp/group/__pycache__/record.cpython-314.opt-2.pyc' => './usr/lib/python3/site-packages/ttp/group/__pycache__/record.cpython-314.opt-1.pyc' './usr/lib/python3/site-packages/ttp/group/__pycache__/set_.cpython-314.opt-1.pyc' => './usr/lib/python3/site-packages/ttp/group/__pycache__/set_.cpython-314.pyc' './usr/lib/python3/site-packages/ttp/group/__pycache__/set_.cpython-314.opt-2.pyc' => './usr/lib/python3/site-packages/ttp/group/__pycache__/set_.cpython-314.opt-1.pyc' './usr/lib/python3/site-packages/ttp/group/__pycache__/sformat.cpython-314.opt-1.pyc' => './usr/lib/python3/site-packages/ttp/group/__pycache__/sformat.cpython-314.pyc' './usr/lib/python3/site-packages/ttp/group/__pycache__/to_converters.cpython-314.opt-1.pyc' => './usr/lib/python3/site-packages/ttp/group/__pycache__/to_converters.cpython-314.pyc' './usr/lib/python3/site-packages/ttp/group/__pycache__/to_converters.cpython-314.opt-2.pyc' => './usr/lib/python3/site-packages/ttp/group/__pycache__/to_converters.cpython-314.opt-1.pyc' './usr/lib/python3/site-packages/ttp/group/__pycache__/to_ip.cpython-314.opt-1.pyc' => './usr/lib/python3/site-packages/ttp/group/__pycache__/to_ip.cpython-314.pyc' './usr/lib/python3/site-packages/ttp/group/__pycache__/validate_cerberus.cpython-314.opt-1.pyc' => './usr/lib/python3/site-packages/ttp/group/__pycache__/validate_cerberus.cpython-314.pyc' './usr/lib/python3/site-packages/ttp/group/__pycache__/void.cpython-314.opt-1.pyc' => './usr/lib/python3/site-packages/ttp/group/__pycache__/void.cpython-314.pyc' './usr/lib/python3/site-packages/ttp/group/__pycache__/void.cpython-314.opt-2.pyc' => './usr/lib/python3/site-packages/ttp/group/__pycache__/void.cpython-314.opt-1.pyc' './usr/lib/python3/site-packages/ttp/input/__pycache__/__init__.cpython-314.opt-1.pyc' => './usr/lib/python3/site-packages/ttp/input/__pycache__/__init__.cpython-314.pyc' './usr/lib/python3/site-packages/ttp/input/__pycache__/__init__.cpython-314.opt-2.pyc' => './usr/lib/python3/site-packages/ttp/input/__pycache__/__init__.cpython-314.opt-1.pyc' './usr/lib/python3/site-packages/ttp/input/__pycache__/commands.cpython-314.opt-1.pyc' => './usr/lib/python3/site-packages/ttp/input/__pycache__/commands.cpython-314.pyc' './usr/lib/python3/site-packages/ttp/input/__pycache__/macro.cpython-314.opt-1.pyc' => './usr/lib/python3/site-packages/ttp/input/__pycache__/macro.cpython-314.pyc' './usr/lib/python3/site-packages/ttp/input/__pycache__/macro.cpython-314.opt-2.pyc' => './usr/lib/python3/site-packages/ttp/input/__pycache__/macro.cpython-314.opt-1.pyc' './usr/lib/python3/site-packages/ttp/input/__pycache__/test.cpython-314.opt-1.pyc' => './usr/lib/python3/site-packages/ttp/input/__pycache__/test.cpython-314.pyc' './usr/lib/python3/site-packages/ttp/input/__pycache__/test.cpython-314.opt-2.pyc' => './usr/lib/python3/site-packages/ttp/input/__pycache__/test.cpython-314.opt-1.pyc' './usr/lib/python3/site-packages/ttp/lookup/__pycache__/__init__.cpython-314.opt-1.pyc' => './usr/lib/python3/site-packages/ttp/lookup/__pycache__/__init__.cpython-314.pyc' './usr/lib/python3/site-packages/ttp/lookup/__pycache__/__init__.cpython-314.opt-2.pyc' => './usr/lib/python3/site-packages/ttp/lookup/__pycache__/__init__.cpython-314.opt-1.pyc' './usr/lib/python3/site-packages/ttp/lookup/__pycache__/geoip2.cpython-314.opt-1.pyc' => './usr/lib/python3/site-packages/ttp/lookup/__pycache__/geoip2.cpython-314.pyc' './usr/lib/python3/site-packages/ttp/match/__pycache__/__init__.cpython-314.opt-1.pyc' => './usr/lib/python3/site-packages/ttp/match/__pycache__/__init__.cpython-314.pyc' './usr/lib/python3/site-packages/ttp/match/__pycache__/__init__.cpython-314.opt-2.pyc' => './usr/lib/python3/site-packages/ttp/match/__pycache__/__init__.cpython-314.opt-1.pyc' './usr/lib/python3/site-packages/ttp/match/__pycache__/copy_.cpython-314.opt-1.pyc' => './usr/lib/python3/site-packages/ttp/match/__pycache__/copy_.cpython-314.pyc' './usr/lib/python3/site-packages/ttp/match/__pycache__/copy_.cpython-314.opt-2.pyc' => './usr/lib/python3/site-packages/ttp/match/__pycache__/copy_.cpython-314.opt-1.pyc' './usr/lib/python3/site-packages/ttp/match/__pycache__/count.cpython-314.opt-1.pyc' => './usr/lib/python3/site-packages/ttp/match/__pycache__/count.cpython-314.pyc' './usr/lib/python3/site-packages/ttp/match/__pycache__/count.cpython-314.opt-2.pyc' => './usr/lib/python3/site-packages/ttp/match/__pycache__/count.cpython-314.opt-1.pyc' './usr/lib/python3/site-packages/ttp/match/__pycache__/dns_lookups.cpython-314.opt-1.pyc' => './usr/lib/python3/site-packages/ttp/match/__pycache__/dns_lookups.cpython-314.pyc' './usr/lib/python3/site-packages/ttp/match/__pycache__/geoip_lookup.cpython-314.opt-1.pyc' => './usr/lib/python3/site-packages/ttp/match/__pycache__/geoip_lookup.cpython-314.pyc' './usr/lib/python3/site-packages/ttp/match/__pycache__/geoip_lookup.cpython-314.opt-2.pyc' => './usr/lib/python3/site-packages/ttp/match/__pycache__/geoip_lookup.cpython-314.opt-1.pyc' './usr/lib/python3/site-packages/ttp/match/__pycache__/ip.cpython-314.opt-1.pyc' => './usr/lib/python3/site-packages/ttp/match/__pycache__/ip.cpython-314.pyc' './usr/lib/python3/site-packages/ttp/match/__pycache__/item.cpython-314.opt-1.pyc' => './usr/lib/python3/site-packages/ttp/match/__pycache__/item.cpython-314.pyc' './usr/lib/python3/site-packages/ttp/match/__pycache__/joinmatches.cpython-314.opt-1.pyc' => './usr/lib/python3/site-packages/ttp/match/__pycache__/joinmatches.cpython-314.pyc' './usr/lib/python3/site-packages/ttp/match/__pycache__/joinmatches.cpython-314.opt-2.pyc' => './usr/lib/python3/site-packages/ttp/match/__pycache__/joinmatches.cpython-314.opt-1.pyc' './usr/lib/python3/site-packages/ttp/match/__pycache__/let.cpython-314.opt-1.pyc' => './usr/lib/python3/site-packages/ttp/match/__pycache__/let.cpython-314.pyc' './usr/lib/python3/site-packages/ttp/match/__pycache__/let.cpython-314.opt-2.pyc' => './usr/lib/python3/site-packages/ttp/match/__pycache__/let.cpython-314.opt-1.pyc' './usr/lib/python3/site-packages/ttp/match/__pycache__/lookup.cpython-314.opt-1.pyc' => './usr/lib/python3/site-packages/ttp/match/__pycache__/lookup.cpython-314.pyc' './usr/lib/python3/site-packages/ttp/match/__pycache__/lookup.cpython-314.opt-2.pyc' => './usr/lib/python3/site-packages/ttp/match/__pycache__/lookup.cpython-314.opt-1.pyc' './usr/lib/python3/site-packages/ttp/match/__pycache__/mac_eui.cpython-314.opt-1.pyc' => './usr/lib/python3/site-packages/ttp/match/__pycache__/mac_eui.cpython-314.pyc' './usr/lib/python3/site-packages/ttp/match/__pycache__/macro.cpython-314.opt-1.pyc' => './usr/lib/python3/site-packages/ttp/match/__pycache__/macro.cpython-314.pyc' './usr/lib/python3/site-packages/ttp/match/__pycache__/macro.cpython-314.opt-2.pyc' => './usr/lib/python3/site-packages/ttp/match/__pycache__/macro.cpython-314.opt-1.pyc' './usr/lib/python3/site-packages/ttp/match/__pycache__/raise_.cpython-314.opt-1.pyc' => './usr/lib/python3/site-packages/ttp/match/__pycache__/raise_.cpython-314.pyc' './usr/lib/python3/site-packages/ttp/match/__pycache__/raise_.cpython-314.opt-2.pyc' => './usr/lib/python3/site-packages/ttp/match/__pycache__/raise_.cpython-314.opt-1.pyc' './usr/lib/python3/site-packages/ttp/match/__pycache__/re_.cpython-314.opt-1.pyc' => './usr/lib/python3/site-packages/ttp/match/__pycache__/re_.cpython-314.pyc' './usr/lib/python3/site-packages/ttp/match/__pycache__/re_.cpython-314.opt-2.pyc' => './usr/lib/python3/site-packages/ttp/match/__pycache__/re_.cpython-314.opt-1.pyc' './usr/lib/python3/site-packages/ttp/match/__pycache__/record.cpython-314.opt-1.pyc' => './usr/lib/python3/site-packages/ttp/match/__pycache__/record.cpython-314.pyc' './usr/lib/python3/site-packages/ttp/match/__pycache__/record.cpython-314.opt-2.pyc' => './usr/lib/python3/site-packages/ttp/match/__pycache__/record.cpython-314.opt-1.pyc' './usr/lib/python3/site-packages/ttp/match/__pycache__/set_.cpython-314.opt-1.pyc' => './usr/lib/python3/site-packages/ttp/match/__pycache__/set_.cpython-314.pyc' './usr/lib/python3/site-packages/ttp/match/__pycache__/set_.cpython-314.opt-2.pyc' => './usr/lib/python3/site-packages/ttp/match/__pycache__/set_.cpython-314.opt-1.pyc' './usr/lib/python3/site-packages/ttp/match/__pycache__/string.cpython-314.opt-1.pyc' => './usr/lib/python3/site-packages/ttp/match/__pycache__/string.cpython-314.pyc' './usr/lib/python3/site-packages/ttp/match/__pycache__/string.cpython-314.opt-2.pyc' => './usr/lib/python3/site-packages/ttp/match/__pycache__/string.cpython-314.opt-1.pyc' './usr/lib/python3/site-packages/ttp/match/__pycache__/to.cpython-314.opt-1.pyc' => './usr/lib/python3/site-packages/ttp/match/__pycache__/to.cpython-314.pyc' './usr/lib/python3/site-packages/ttp/match/__pycache__/to.cpython-314.opt-2.pyc' => './usr/lib/python3/site-packages/ttp/match/__pycache__/to.cpython-314.opt-1.pyc' './usr/lib/python3/site-packages/ttp/match/__pycache__/unrange.cpython-314.opt-1.pyc' => './usr/lib/python3/site-packages/ttp/match/__pycache__/unrange.cpython-314.pyc' './usr/lib/python3/site-packages/ttp/match/__pycache__/uptimeparse.cpython-314.opt-1.pyc' => './usr/lib/python3/site-packages/ttp/match/__pycache__/uptimeparse.cpython-314.pyc' './usr/lib/python3/site-packages/ttp/match/__pycache__/void.cpython-314.opt-1.pyc' => './usr/lib/python3/site-packages/ttp/match/__pycache__/void.cpython-314.pyc' './usr/lib/python3/site-packages/ttp/match/__pycache__/void.cpython-314.opt-2.pyc' => './usr/lib/python3/site-packages/ttp/match/__pycache__/void.cpython-314.opt-1.pyc' './usr/lib/python3/site-packages/ttp/output/__pycache__/__init__.cpython-314.opt-1.pyc' => './usr/lib/python3/site-packages/ttp/output/__pycache__/__init__.cpython-314.pyc' './usr/lib/python3/site-packages/ttp/output/__pycache__/__init__.cpython-314.opt-2.pyc' => './usr/lib/python3/site-packages/ttp/output/__pycache__/__init__.cpython-314.opt-1.pyc' './usr/lib/python3/site-packages/ttp/output/__pycache__/deepdiffer.cpython-314.opt-1.pyc' => './usr/lib/python3/site-packages/ttp/output/__pycache__/deepdiffer.cpython-314.pyc' './usr/lib/python3/site-packages/ttp/output/__pycache__/is_equal.cpython-314.opt-1.pyc' => './usr/lib/python3/site-packages/ttp/output/__pycache__/is_equal.cpython-314.pyc' './usr/lib/python3/site-packages/ttp/output/__pycache__/is_equal.cpython-314.opt-2.pyc' => './usr/lib/python3/site-packages/ttp/output/__pycache__/is_equal.cpython-314.opt-1.pyc' './usr/lib/python3/site-packages/ttp/output/__pycache__/macro.cpython-314.opt-1.pyc' => './usr/lib/python3/site-packages/ttp/output/__pycache__/macro.cpython-314.pyc' './usr/lib/python3/site-packages/ttp/output/__pycache__/macro.cpython-314.opt-2.pyc' => './usr/lib/python3/site-packages/ttp/output/__pycache__/macro.cpython-314.opt-1.pyc' './usr/lib/python3/site-packages/ttp/output/__pycache__/transform.cpython-314.opt-1.pyc' => './usr/lib/python3/site-packages/ttp/output/__pycache__/transform.cpython-314.pyc' './usr/lib/python3/site-packages/ttp/output/__pycache__/validate_cerberus.cpython-314.opt-1.pyc' => './usr/lib/python3/site-packages/ttp/output/__pycache__/validate_cerberus.cpython-314.pyc' './usr/lib/python3/site-packages/ttp/output/__pycache__/validate_yangson.cpython-314.opt-1.pyc' => './usr/lib/python3/site-packages/ttp/output/__pycache__/validate_yangson.cpython-314.pyc' './usr/lib/python3/site-packages/ttp/patterns/__pycache__/__init__.cpython-314.opt-1.pyc' => './usr/lib/python3/site-packages/ttp/patterns/__pycache__/__init__.cpython-314.pyc' './usr/lib/python3/site-packages/ttp/patterns/__pycache__/__init__.cpython-314.opt-2.pyc' => './usr/lib/python3/site-packages/ttp/patterns/__pycache__/__init__.cpython-314.opt-1.pyc' './usr/lib/python3/site-packages/ttp/patterns/__pycache__/get_pattern.cpython-314.opt-1.pyc' => './usr/lib/python3/site-packages/ttp/patterns/__pycache__/get_pattern.cpython-314.pyc' './usr/lib/python3/site-packages/ttp/patterns/__pycache__/get_pattern.cpython-314.opt-2.pyc' => './usr/lib/python3/site-packages/ttp/patterns/__pycache__/get_pattern.cpython-314.opt-1.pyc' './usr/lib/python3/site-packages/ttp/returners/__pycache__/__init__.cpython-314.opt-1.pyc' => './usr/lib/python3/site-packages/ttp/returners/__pycache__/__init__.cpython-314.pyc' './usr/lib/python3/site-packages/ttp/returners/__pycache__/__init__.cpython-314.opt-2.pyc' => './usr/lib/python3/site-packages/ttp/returners/__pycache__/__init__.cpython-314.opt-1.pyc' './usr/lib/python3/site-packages/ttp/returners/__pycache__/file_returner.cpython-314.opt-1.pyc' => './usr/lib/python3/site-packages/ttp/returners/__pycache__/file_returner.cpython-314.pyc' './usr/lib/python3/site-packages/ttp/returners/__pycache__/self_returner.cpython-314.opt-1.pyc' => './usr/lib/python3/site-packages/ttp/returners/__pycache__/self_returner.cpython-314.pyc' './usr/lib/python3/site-packages/ttp/returners/__pycache__/syslog_returner.cpython-314.opt-1.pyc' => './usr/lib/python3/site-packages/ttp/returners/__pycache__/syslog_returner.cpython-314.pyc' './usr/lib/python3/site-packages/ttp/returners/__pycache__/syslog_returner.cpython-314.opt-2.pyc' => './usr/lib/python3/site-packages/ttp/returners/__pycache__/syslog_returner.cpython-314.opt-1.pyc' './usr/lib/python3/site-packages/ttp/returners/__pycache__/terminal_returner.cpython-314.opt-1.pyc' => './usr/lib/python3/site-packages/ttp/returners/__pycache__/terminal_returner.cpython-314.pyc' './usr/lib/python3/site-packages/ttp/utils/__pycache__/__init__.cpython-314.opt-1.pyc' => './usr/lib/python3/site-packages/ttp/utils/__pycache__/__init__.cpython-314.pyc' './usr/lib/python3/site-packages/ttp/utils/__pycache__/__init__.cpython-314.opt-2.pyc' => './usr/lib/python3/site-packages/ttp/utils/__pycache__/__init__.cpython-314.opt-1.pyc' './usr/lib/python3/site-packages/ttp/utils/__pycache__/get_attributes.cpython-314.opt-1.pyc' => './usr/lib/python3/site-packages/ttp/utils/__pycache__/get_attributes.cpython-314.pyc' './usr/lib/python3/site-packages/ttp/utils/__pycache__/guess.cpython-314.opt-1.pyc' => './usr/lib/python3/site-packages/ttp/utils/__pycache__/guess.cpython-314.pyc' './usr/lib/python3/site-packages/ttp/utils/__pycache__/guess.cpython-314.opt-2.pyc' => './usr/lib/python3/site-packages/ttp/utils/__pycache__/guess.cpython-314.opt-1.pyc' './usr/lib/python3/site-packages/ttp/utils/__pycache__/load_python_exec_py3.cpython-314.opt-1.pyc' => './usr/lib/python3/site-packages/ttp/utils/__pycache__/load_python_exec_py3.cpython-314.pyc' './usr/lib/python3/site-packages/ttp/utils/__pycache__/loaders.cpython-314.opt-1.pyc' => './usr/lib/python3/site-packages/ttp/utils/__pycache__/loaders.cpython-314.pyc' './usr/lib/python3/site-packages/ttp/utils/__pycache__/quick_parse.cpython-314.opt-1.pyc' => './usr/lib/python3/site-packages/ttp/utils/__pycache__/quick_parse.cpython-314.pyc' './usr/lib/python3/site-packages/ttp/variable/__pycache__/__init__.cpython-314.opt-1.pyc' => './usr/lib/python3/site-packages/ttp/variable/__pycache__/__init__.cpython-314.pyc' './usr/lib/python3/site-packages/ttp/variable/__pycache__/__init__.cpython-314.opt-2.pyc' => './usr/lib/python3/site-packages/ttp/variable/__pycache__/__init__.cpython-314.opt-1.pyc' './usr/lib/python3/site-packages/ttp/variable/__pycache__/getfilename.cpython-314.opt-1.pyc' => './usr/lib/python3/site-packages/ttp/variable/__pycache__/getfilename.cpython-314.pyc' './usr/lib/python3/site-packages/ttp/variable/__pycache__/gethostname.cpython-314.opt-1.pyc' => './usr/lib/python3/site-packages/ttp/variable/__pycache__/gethostname.cpython-314.pyc' './usr/lib/python3/site-packages/ttp/variable/__pycache__/time_funcs.cpython-314.opt-1.pyc' => './usr/lib/python3/site-packages/ttp/variable/__pycache__/time_funcs.cpython-314.pyc' './usr/lib/python3/site-packages/ttp/variable/__pycache__/time_funcs.cpython-314.opt-2.pyc' => './usr/lib/python3/site-packages/ttp/variable/__pycache__/time_funcs.cpython-314.opt-1.pyc' Executing(%check): /bin/sh -e /usr/src/tmp/rpmb-tmp.q1b9QU + umask 022 + /bin/mkdir -p /usr/src/RPM/BUILD + cd /usr/src/RPM/BUILD + cd ttp-0.9.5 + pushd test/pytest ~/RPM/BUILD/ttp-0.9.5/test/pytest ~/RPM/BUILD/ttp-0.9.5 + python3 -m pytest . -k 'not (yangson or test_inputs or test_adding_data_from_files)' ============================= test session starts ============================== platform linux -- Python 3.14.6, pytest-9.0.3, pluggy-1.6.0 rootdir: /usr/src/RPM/BUILD/ttp-0.9.5 configfile: pyproject.toml collected 284 items / 15 deselected / 269 selected test_N2G_formatter.py s [ 0%] test_anonymous_group.py FFFF [ 1%] test_answers_and_docs.py FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF [ 19%] sFsFFFFFFFFFFFFFFFFFF [ 27%] test_empty_group_results.py F [ 27%] test_extend_tag.py FFFFFFFFFFFFFFFFFFFFFF [ 35%] test_group_chain_attribute.py FFFF [ 37%] test_group_functions.py FFFFFFFFFFFFFFFFFFFFFF [ 45%] test_group_lookup.py FFFFFFF [ 47%] test_group_name_attribute.py F [ 48%] test_headers_indicator.py FFFFFFFFFFF [ 52%] test_line_indicator.py F [ 52%] test_lookups.py FF [ 53%] test_match_condition_fun.py FFFFFFFFFFFFFFFFFFFFF [ 61%] test_match_functions.py FFFFFFFFFFFFFF [ 66%] test_misc.py FFFFFFFFFFFFFFFFFFFFFF [ 74%] test_output_formatters.py FFFFFFFFFFFFFF [ 79%] test_output_functions.py FFFFFF [ 82%] test_output_returners.py FFFFF [ 84%] test_regexes.py FFF [ 85%] test_structure.py FFFFFF [ 87%] test_syslog_returner.py F [ 87%] test_template_variables.py FF [ 88%] test_ttp_parser_methods.py FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF [100%] =================================== FAILURES =================================== ________________________ test_simple_anonymous_template ________________________ def test_simple_anonymous_template(): template_1 = """interface {{ interface }} description {{ description | ORPHRASE }}""" data_1 = """ interface Port-Chanel11 description Storage Management interface Loopback0 description RID """ > parser = ttp(template=template_1, data=data_1) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ test_anonymous_group.py:19: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError ________________________ test_anonymous_group_with_vars ________________________ def test_anonymous_group_with_vars(): template = """ interface Port-Chanel11 description Storage Management interface Loopback0 description RID a = 1 b = 2 interface {{ interface }} description {{ description | ORPHRASE }} """ > parser = ttp(template=template) ^^^^^^^^^^^^^^^^^^^^^^ test_anonymous_group.py:55: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError __________ test_anonymous_group_with_child_group_empty_absolute_path ___________ def test_anonymous_group_with_child_group_empty_absolute_path(): template = """ """ > parser = ttp(template=template) ^^^^^^^^^^^^^^^^^^^^^^ test_anonymous_group.py:102: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError _________________ test_anonymous_group_with_per_template_mode __________________ def test_anonymous_group_with_per_template_mode(): template = """ """ datum_1 = """ hostname r2 ! interface GigabitEthernet1 vrf forwarding MGMT ip address 10.123.89.55 255.255.255.0 """ datum_2 = """ hostname r1 ! interface GigabitEthernet1 description some info vrf forwarding MGMT ip address 10.123.89.56 255.255.255.0 interface GigabitEthernet2 ip address 10.123.89.55 255.255.255.0 """ > parser_a = ttp(template=template) ^^^^^^^^^^^^^^^^^^^^^^ test_anonymous_group.py:150: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError ________________________________ test_answer_1 _________________________________ def test_answer_1(): """https://stackoverflow.com/questions/63522291/parsing-blocks-of-text-within-a-file-into-objects""" data = """ #*Approximate Distance Oracles with Improved Query Time. #@Christian Wulff-Nilsen #t2015 #cEncyclopedia of Algorithms #index555036b37cea80f954149ffc #*Subset Sum Algorithm for Bin Packing. #@Julián Mestre #t2015 #cEncyclopedia of Algorithms #index555036b37cea80f954149ffd """ template = """ #*{{ info | ORPHRASE }} #@{{ author | ORPHRASE }} #t{{ year }} #c{{ title | ORPHRASE }} #index{{ index }} """ > parser = ttp(data, template) ^^^^^^^^^^^^^^^^^^^ test_answers_and_docs.py:35: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError ________________________________ test_answer_2 _________________________________ def test_answer_2(): """https://stackoverflow.com/questions/63499479/extract-value-from-text-string-using-format-string-in-python""" data = """ name=username1, age=1001 name=username2, age=1002 name=username3, age=1003 """ template = "name={{ name }}, age={{ age }}" > parser = ttp(data, template) ^^^^^^^^^^^^^^^^^^^ test_answers_and_docs.py:68: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError _____________________________ test_issue_20_answer _____________________________ def test_issue_20_answer(): data_to_parse = """ (*, 239.100.100.100) LISP0.4200, (192.2.101.65, 232.0.3.1), Forward/Sparse, 1d18h/stopped LISP0.4201, (192.2.101.70, 232.0.3.1), Forward/Sparse, 2d05h/stopped (192.2.31.3, 239.100.100.100), 6d20h/00:02:23, flags: FT Incoming interface: Vlan1029, RPF nbr 0.0.0.0 Outgoing interface list: LISP0.4100, (192.2.101.70, 232.0.3.1), Forward/Sparse, 1d18h/stopped """ show_mcast1 = """ """ > parser = ttp(template=show_mcast1) ^^^^^^^^^^^^^^^^^^^^^^^^^ test_answers_and_docs.py:107: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError ________________________________ test_answer_3 _________________________________ def test_answer_3(): """ Fixed bug with results forming - when have two _start_ matches, but one of them is False, TTP was selecting first match without checking if its False, updated decision logic to do that check. """ data = """ /c/slb/virt 12 dis ipver v4 vip 1.1.1.1 rtsrcmac ena vname "my name" /c/slb/virt 12/service 443 https group 15 rport 443 pbind clientip dbind forceproxy /c/slb/virt 12/service 443 https/http xforward ena httpmod hsts_insert /c/slb/virt 12/service 443 https/ssl srvrcert cert certname sslpol ssl-Policy /c/slb/virt 12/service 80 http group 15 rport 80 pbind clientip dbind forceproxy /c/slb/virt 12/service 80 http/http xforward ena /c/slb/virt 14 dis ipver v4 vip 1.1.4.4 rtsrcmac ena vname "my name2" """ template = """ """ > parser = ttp(data, template, log_level="ERROR") ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ test_answers_and_docs.py:228: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError ________________________________ test_answer_4 _________________________________ def test_answer_4(): data = """ /c/slb/virt 12 dis ipver v4 vip 1.1.1.1 rtsrcmac ena vname "my name" /c/slb/virt 12/service 443 https group 15 rport 443 pbind clientip dbind forceproxy /c/slb/virt 12/service 443 https/http xforward ena httpmod hsts_insert /c/slb/virt 12/service 443 https/ssl srvrcert cert certname sslpol ssl-Policy /c/slb/virt 12/service 80 http group 15 rport 80 pbind clientip dbind forceproxy /c/slb/virt 12/service 80 http/http xforward ena /c/slb/virt 14 dis ipver v4 vip 1.1.4.4 rtsrcmac ena vname "my name2" """ template = """ """ > parser = ttp(data, template, log_level="ERROR") ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ test_answers_and_docs.py:345: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError ____________________________ test_issue_20_answer_2 ____________________________ def test_issue_20_answer_2(): data_to_parse = """ (*, 239.100.100.101) LISP0.4200, (192.2.101.65, 232.0.3.1), Forward/Sparse, 1d18h/stopped LISP0.4201, (192.2.101.70, 232.0.3.1), Forward/Sparse, 2d05h/stopped (192.2.31.3, 239.100.100.100), 2d05h/00:01:19, flags: FT Incoming interface: Vlan1029, RPF nbr 0.0.0.0 Outgoing interface list: LISP0.4100, (192.2.101.70, 232.0.3.1), Forward/Sparse, 2d05h/stopped LISP0.4101, (192.2.101.70, 232.0.3.1), Forward/Sparse, 2d05h/stopped (*, 239.100.100.100), 6d20h/00:03:28, RP 192.2.199.1, flags: S Incoming interface: Null, RPF nbr 0.0.0.0 Outgoing interface list: Vlan3014, Forward/Sparse, 1d18h/00:03:28 LISP0.4100, (192.2.101.65, 232.0.3.1), Forward/Sparse, 1d18h/stopped """ show_mcast1 = """ """ > parser = ttp(template=show_mcast1) ^^^^^^^^^^^^^^^^^^^^^^^^^ test_answers_and_docs.py:426: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError ____________________ test_docs_ttp_dictionary_usage_example ____________________ def test_docs_ttp_dictionary_usage_example(): template = """ interface Lo0 ip address 124.171.238.50/29 ! interface Lo1 ip address 1.1.1.1/30 interface {{ interface }} ip address {{ ip }} def add_last_host(data): ip_obj, _ = _ttp_["match"]["to_ip"](data["ip"]) all_ips = list(ip_obj.network.hosts()) data["last_host"] = str(all_ips[-1]) return data """ > parser = ttp(template=template, log_level="ERROR") ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ test_answers_and_docs.py:494: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError _________________________ test_github_issue_21_answer __________________________ def test_github_issue_21_answer(): data_to_parse = """ R1#sh ip nbar protocol-discovery protocol GigabitEthernet1 Last clearing of "show ip nbar protocol-discovery" counters 00:13:45 Input Output ----- ------ Protocol Packet Count Packet Count Byte Count Byte Count 5min Bit Rate (bps) 5min Bit Rate (bps) 5min Max Bit Rate (bps) 5min Max Bit Rate (bps) ---------------------------- ------------------------ ------------------------ ssh 191 134 24805 22072 2000 1000 1999 1001 unknown 172 503 39713 31378 0 0 3000 0 ping 144 144 14592 14592 0 0 1000 1000 dns 107 0 21149 0 0 0 2000 0 vrrp 0 738 0 39852 0 0 0 0 ldp 174 175 13224 13300 0 0 0 0 ospf 86 87 9460 9570 0 0 0 0 Total 874 1781 122943 130764 2000 1000 8000 2000 """ show_nbar = """ """ > parser = ttp(template=show_nbar) ^^^^^^^^^^^^^^^^^^^^^^^ test_answers_and_docs.py:591: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError _____________________________ test_github_issue_22 _____________________________ def test_github_issue_22(): data = """ interface Loopback0 description Fabric Node Router ID ip address 192.2.101.70 255.255.255.255 ip pim sparse-mode ip router isis clns mtu 1400 end interface Loopback0 description Fabric Node Router ID ip address 192.2.101.71 255.255.255.255 ip pim sparse-mode ip router isis clns mtu 1400 end """ template = """{{ ignore(r"\\s+") }}ip address {{ ip_address }} 255.255.255.255""" > parser = ttp(data, template) ^^^^^^^^^^^^^^^^^^^ test_answers_and_docs.py:705: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError _____________________________ test_github_issue_24 _____________________________ def test_github_issue_24(): data = """ 19: IP4 1.1.1.1, 00:03:b2:78:04:13, vname portal, NO SERVICES UP Virtual Services: http: rport http, group 11, health http (HTTP), pbind clientip Real Servers: 22: 10.10.10.10, web1, group ena, health (runtime HTTP), 0 ms, FAILED Reason: N/A 23: 10.11.11.11, web2, group ena, health (runtime HTTP), 0 ms, FAILED Reason: N/A https: rport https, group 12, health tcp (TCP), pbind clientip Real Servers: 22: 10.10.10.10, web1, group ena, health (runtime TCP), 0 ms, FAILED Reason: N/A 23: 10.11.11.11, web2, group ena, health (runtime TCP), 0 ms, FAILED Reason: N/A """ template = """ """ > parser = ttp(data, template) ^^^^^^^^^^^^^^^^^^^ test_answers_and_docs.py:746: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError _____________________________ test_reddit_answer_1 _____________________________ def test_reddit_answer_1(): """ https://www.reddit.com/r/networking/comments/j106ot/export_custom_lists_from_the_config_aruba_switch/ Hit a bug while was doing this template - join action overridden by ignore indicator add action """ data = """ SWITCH# show vlan port 2/11 detail Status and Counters - VLAN Information - for ports 2/11 Port name: VLAN ID Name | Status Voice Jumbo Mode ------- -------------------- + ---------- ----- ----- -------- 60 ABC | Port-based No No Tagged 70 DEF | Port-based No No Tagged 101 GHIJ | Port-based No No Untagged 105 KLMNO | Port-based No No Tagged 116 PQRS | Port-based No No Tagged 117 TVU | Port-based No No Tagged SWITCH# show vlan port 2/12 detail Status and Counters - VLAN Information - for ports 2/12 Port name: VLAN ID Name | Status Voice Jumbo Mode ------- -------------------- + ---------- ----- ----- -------- 61 ABC | Port-based No No Tagged 71 DEF | Port-based No No Tagged 103 GHI | Port-based No No Untagged """ template = """ hostname="gethostname" Status and Counters - VLAN Information - for ports {{ Port_Number }} {{ Tagged_VLAN | joinmatches(" ") }} {{ ignore }} | {{ ignore }} {{ ignore }} {{ ignore }} Tagged {{ Untagged_VLAN }} {{ ignore }} | {{ ignore }} {{ ignore }} {{ ignore }} Untagged {{ Hostname | set(hostname) }} format = "csv" path = "vlans" headers = "Hostname, Port_Number, Untagged_VLAN, Tagged_VLAN" """ > parser = ttp(data, template) ^^^^^^^^^^^^^^^^^^^ test_answers_and_docs.py:859: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError _____________________________ test_reddit_answer_2 _____________________________ def test_reddit_answer_2(): data = """ config router ospf set abr-type standard set auto-cost-ref-bandwidth 1000 set distance-external 110 set distance-inter-area 110 set distance-intra-area 110 set database-overflow disable set database-overflow-max-lsas 10000 set database-overflow-time-to-recover 300 set default-information-originate disable set default-information-metric 10 set default-information-metric-type 2 set default-information-route-map '' set default-metric 10 set distance 110 set rfc1583-compatible disable set router-id 10.1.1.1 set spf-timers 5 10 set bfd disable set log-neighbour-changes enable set distribute-list-in "OSPF_IMPORT_PREFIX" set distribute-route-map-in '' set restart-mode none set restart-period 120 config area edit 0.0.0.1 set shortcut disable set authentication none set default-cost 10 set nssa-translator-role candidate set stub-type summary set type nssa set nssa-default-information-originate disable set nssa-default-information-originate-metric 10 set nssa-default-information-originate-metric-type 2 set nssa-redistribution enable next end config ospf-interface edit "vlan1-int" set interface "Vlan1" set ip 0.0.0.0 set authentication text set authentication-key netconanRemoved13 set prefix-length 0 set retransmit-interval 5 set transmit-delay 1 set cost 0 set priority 1 set dead-interval 40 set hello-interval 10 set hello-multiplier 0 set database-filter-out disable set mtu 0 set mtu-ignore disable set network-type point-to-point set bfd global set status enable set resync-timeout 40 next edit "vlan2-int" set interface "vlan2" set ip 0.0.0.0 set authentication text set authentication-key netconanRemoved14 set prefix-length 0 set retransmit-interval 5 set transmit-delay 1 set cost 0 set priority 1 set dead-interval 40 set hello-interval 10 set hello-multiplier 0 set database-filter-out disable set mtu 0 set mtu-ignore disable set network-type point-to-point set bfd global set status enable set resync-timeout 40 next end config network edit 1 set prefix 10.1.1.1 255.255.255.252 set area 0.0.0.1 next edit 2 set prefix 10.1.1.3 255.255.255.252 set area 0.0.0.1 next end config redistribute "connected" set status enable set metric 0 set routemap '' set metric-type 2 set tag 0 end config redistribute "static" set status enable set metric 0 set routemap '' set metric-type 2 set tag 0 end config redistribute "rip" set status disable set metric 0 set routemap '' set metric-type 2 set tag 0 end config redistribute "bgp" set status enable set metric 0 set routemap '' set metric-type 2 set tag 0 end config redistribute "isis" set status disable set metric 0 set routemap '' set metric-type 2 set tag 0 end end """ template = """ clean_phrase = [ 'ORPHRASE', 'macro(\"clean_str\")' ] clean_list = [ 'ORPHRASE', 'macro(\"build_list\")' ] def build_list(data): if "\\" \\"" in data: t = data.split("\\" \\"") for i in range(0, len(t)): t[i] = t[i].strip("\\"").replace(" ", "_") i+=1 return t else: return [data.strip("\\"").replace(" ", "_")] def clean_str(data): return data.replace("\\"","").replace(" ", "_") def match_ip_or_any(data): import ipaddress if data == \"any\": return data elif "/" in data: return str(data) else: t = data.replace(" ", "/") return str(ipaddress.IPv4Network(t, strict=False)) def ignore_empty(data): if data == "\'\'": return bool(False) else: return data def skip_empty(data): if data == {}: return False return data config router ospf {{ _start_ }} set auto-cost-ref-bandwidth {{ ref_bw }} set default-information-originate {{ default_originate | contains("enable") }} set default-information-metric {{ default_originate_metric }} set default-information-metric-type {{ default_originate_metric_type }} set default-information-route-map {{ default_originate_routemap | chain("clean_phrase") | macro("ignore_empty") }} set default-metric {{ default_rt_metric }} set rfc1583-compatible {{ rfc1583_compat | contains("enable") }} set router-id {{ router_id }} set distribute-list-in {{ dist_list_in | chain("clean_phrase") | macro("ignore_empty") }} set distribute-route-map-in {{ dist_routemap_in | chain("clean_phrase") | macro("ignore_empty") }} config area {{ _start_ }} edit {{ area | _start_ }} set stub-type {{ stub_type }} set type {{ area_type }} set nssa-default-information-originate {{ nssa_default_originate | contains("enable") }} set nssa-default-information-originate-metric {{ nssa_default_metric }} set nssa-default-information-originate-metric-type {{ nssa_default_metric_type }} set nssa-redistribution {{ nssa_redis }} next {{ _end_ }} end {{ _end_ }} config ospf-interface {{ _start_ }} edit {{ name | chain("clean_phrase") | _start_ }} set interface {{ interface | chain("clean_phrase")}} set ip {{ ip | exclude("0.0.0.0") }} set cost {{ cost | exclude("0") }} set priority {{ priority }} set mtu {{ mtu | exclude("0") }} set network-type {{ network }} set status {{ status | contains("enable") }} next {{ _end_ }} end {{ _end_ }} config network {{ _start_ }} edit {{ id | _start_ }} set prefix {{ prefix | ORPHRASE | to_ip | with_prefixlen }} set area {{ area }} next {{ _end_ }} end {{ _end_ }} config redistribute {{ protocol | chain("clean_phrase") | _start_ }} set status {{ status | contains('enable') }} set route-map {{ route_map | chain("clean_phrase") | macro("ignore_empty") }} set metric-type {{ metric-type }} set metric {{ metric | exclude("0") }} set tag {{ tag | exclude("0")}} end {{ _end_ }} end {{ _end_ }} """ > parser = ttp(data, template, log_level="ERROR") ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ test_answers_and_docs.py:1109: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError _____________________________ test_github_issue_32 _____________________________ def test_github_issue_32(): data = """ .id=*c;export-route-targets=65001:48;65001:0;import-route-targets=65001:48;interfaces=lo-ext;vlan56;route-distinguisher=65001:48;routing-mark=VRF_EXT .id=*10;comment=;export-route-targets=65001:80;import-route-targets=65001:80;65001:0;interfaces=lo-private;route-distinguisher=65001:80;routing-mark=VRF_PRIVATE """ template = """ .id={{ id | exclude(";") }};export-route-targets={{ export-route-targets }};import-route-targets={{ import-route-targets }};interfaces={{ interfaces }};route-distinguisher={{ route-distinguisher }};routing-mark={{ routing-mark }} .id={{ id }};comment{{ comment }};export-route-targets={{ export-route-targets }};import-route-targets={{ import-route-targets }};interfaces={{ interfaces }};route-distinguisher={{ route-distinguisher }};routing-mark={{ routing-mark }} """ > parser = ttp(data, template) ^^^^^^^^^^^^^^^^^^^ test_answers_and_docs.py:1182: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError _____________________________ test_slack_answer_1 ______________________________ def test_slack_answer_1(): data = """ Firmware Version ---------------- 02.1.1 Build 002 Hardware Version ---------------- V2R4 """ template = """ Hardware {{ _start_ }} Firmware {{ _start_ }} {{ version | PHRASE | let("type", "firmware") }} {{ version | exclude("---") | exclude("Vers") | let("type", "hardware") }} {{ _end_ }} """ > parser = ttp(data, template) ^^^^^^^^^^^^^^^^^^^ test_answers_and_docs.py:1231: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError ___________________________ test_group_default_docs ____________________________ def test_group_default_docs(): template = """ device-hostame uptime is 27 weeks, 3 days, 10 hours, 46 minutes, 10 seconds device-hostame uptime is {{ uptime | PHRASE }} software version {{ version | default("uncknown") }} Default domain is {{ fqdn }} """ > parser = ttp(template=template) ^^^^^^^^^^^^^^^^^^^^^^ test_answers_and_docs.py:1265: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError _________________________ test_github_issue_34_answer __________________________ def test_github_issue_34_answer(): template = """ Hi World Hello {{ audience | default([]) }} """ > parser = ttp(template=template, log_level="ERROR") ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ test_answers_and_docs.py:1297: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError ________________________ test_github_issue_33_answer_1 _________________________ def test_github_issue_33_answer_1(): template = """ server 1.1.1.1 server 2.2.2.2 3.3.3.3 server 4.4.4.4 5.5.5.5 6.6.6.6 server {{ server | re(r"\\S+") | let("servers_number", 1 ) }} server {{ server | re(r"\\S+ \\S+") | let("servers_number", 2) }} server {{ server | re(r"\\S+ \\S+ \\S+") | let("servers_number", 3) }} """ > parser = ttp(template=template, log_level="ERROR") ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ test_answers_and_docs.py:1321: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError ________________________________ test_issue_36 _________________________________ def test_issue_36(): template = """ ip access-list standard 42 10 remark machine_A 10 permit 192.168.200.162 20 remark machine_B 20 permit 192.168.200.149 30 deny any log ip access-list standard 98 10 permit 10.10.10.1 20 remark toto 20 permit 30.30.30.1 30 permit 30.30.30.0 0.0.0.255 ip access-list standard 99 10 permit 10.20.30.40 log 20 permit 20.30.40.1 log 30 remark DEVICE - SNMP RW 30 permit 50.50.50.128 0.0.0.127 40 permit 60.60.60.64 0.0.0.63 ip access-list extended 199 10 remark COLLECTOR - SNMP 10 permit ip 70.70.70.0 0.0.0.255 any 20 remark RETURN - Back 20 permit ip 80.80.80.0 0.0.0.127 any 30 remark VISUALIZE 30 permit ip host 90.90.90.138 any ip access-list {{ acl_type }} {{ acl_name }} {{ entry_id }} remark {{ remark_name | re(".+") | let("action", "remark") }} {{ entry_id }} {{ action }} {{ src_host }} {{ entry_id }} {{ action }} {{ src_host | let("log", "log") }} log {{ entry_id }} {{ action }} {{ protocol }} host {{ src_host | let("dest_any", "any") }} any {{ entry_id }} {{ action }} {{ protocol }} {{ src_ntw | let("dest_any", "any") }} {{ src_wildcard | IP }} any {{ entry_id }} {{ action }} {{ src_ntw }} {{ src_wildcard | IP }} """ > parser = ttp(template=template, log_level="ERROR") ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ test_answers_and_docs.py:1382: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError _________________ test_github_issue_37_original_data_template __________________ def test_github_issue_37_original_data_template(): template = """ import re def qinq(data): data = re.sub(r"\\*", r"qinq", data) return data service {{ ignore }} epipe {{ service_id | _start_ }} customer {{ customer_id }} create description "{{ description | ORPHRASE | default("none") }}" service-mtu {{ service_mtu | default("none") }} service-name "{{ service_name | ORPHRASE | default("none") }}" endpoint {{ endpoint | _start_ }} create revert-time {{ revert_time | default("none") }} exit {{ _end_ }} sap {{ sap_id | macro("qinq") | _start_ | ORPHRASE }} create description "{{ description | ORPHRASE | default("none")}}" multi-service-site "{{ mss_name | default("none") }}" ingress {{ _start_ }} qos {{ sap_ingress | default("1") }} scheduler-policy {{ scheduler_policy | default("none")}} exit {{ _end_ }} egress {{ _start_ }} scheduler-policy {{ scheduler_policy | default("none") }} qos {{ sap_egress | default("1)") }} exit {{ _end_ }} no shutdown {{ state | set("enabled") | default("disabled") }} exit {{ _end_ }} spoke-sdp {{ pwr_spoke_sdp_id | default("none")}}:{{vc_id | _start_ | default("none") }} endpoint {{ endpoint | default("none") }} create precedence {{ precedence | default("default_precedence") }} no shutdown {{ state | set("enabled") | default("disabled") }} exit {{ _end_ }} spoke-sdp {{ r_spoke_sdp_id }}:{{vc_id | _start_ }} create no shutdown {{ state | set("enabled") | default("disabled") }} exit {{ _end_ }} no shutdown {{ state | set("enabled") | default("disabled") }} exit {{ _end_ }} exit {{ _end_ }} """ data = """ service foo epipe 103076 customer 160 create description "vf=EWL:cn=TATA_COM:tl=2C02495918:st=act:" service-mtu 1588 service-name "EPIPE service-103076 DKTN08a-D0105 (63.130.108.41)" sap 1/2/12:20.* create description "vf=EWL:cn=TATA_COM:tl=2C02495890:st=act:" multi-service-site "TATA_VSNL_STRAT_A206_LAN10" ingress queue-override queue 1 create cbs default mbs 40 kilobytes rate 10000 cir 10000 exit exit exit egress queue-override queue 1 create cbs default mbs 40 kilobytes rate 10000 cir 10000 exit exit exit accounting-policy 4 no shutdown exit spoke-sdp 8051:103076 create no shutdown exit no shutdown exit epipe 103206 customer 1904 create description "vf=1273:cn=skanska:tl=3C02407455:st=act:no='SKANSKA UK PLC Stepney Green E1 3DG'" service-mtu 1988 service-name "EPIPE service-103206 DKTN08a-D0105 (63.130.108.41)" sap 2/2/3:401.100 create description "vf=1273:cn=skanska:tl=3C02407455:st=act:no='SKANSKA UK PLC Stepney Green E1 3DG'" multi-service-site "SKANSKA_E13DG_A825_LAN1" ingress qos 11010 queue-override queue 1 create cbs default mbs 1188 kilobytes rate max cir 47500 exit queue 3 create cbs default mbs 63 kilobytes rate max cir 2500 exit exit exit egress qos 11010 queue-override queue 1 create cbs default mbs 1188 kilobytes rate max cir 47500 exit queue 3 create cbs default mbs 63 kilobytes rate max cir 2500 exit exit exit collect-stats accounting-policy 4 no shutdown exit spoke-sdp 8035:103206 create no shutdown exit no shutdown exit epipe 103256 customer 160 create description "vf=EWL:cn=TATA_COMM:tl=2C02490189:st=act:" service-mtu 1988 service-name "EPIPE service-103256 DKTN08a-D0105 (63.130.108.41)" sap 1/2/12:15.* create description "vf=EWL:cn=TATA_COMM:tl=2C02490171:st=act:" multi-service-site "TATA_VSNL_STRAT_A206_LAN5" ingress qos 11000 queue-override queue 1 create cbs default mbs 391 kilobytes rate 100000 cir 100000 exit exit exit egress qos 11000 queue-override queue 1 create cbs default mbs 391 kilobytes rate 100000 cir 100000 exit exit exit accounting-policy 4 no shutdown exit spoke-sdp 8139:103256 create no shutdown exit no shutdown exit epipe 103742 customer 160 create description "vf=EWL:cn=TATA_COM:tl=2C02410363:st=act:" service-mtu 1588 service-name "EPIPE service-103742 DKTN08a-D0105 (63.130.108.41)" sap 5/2/50:20.* create description "vf=EWL:cn=TATA_COM:tl=2C02410338:st=act:" multi-service-site "TATA_STRAT_LON_A206_LANA" ingress qos 11000 queue-override queue 1 create cbs default mbs 32 kilobytes rate 8000 cir 8000 exit exit exit egress qos 11000 queue-override queue 1 create cbs default mbs 32 kilobytes rate 8000 cir 8000 exit exit exit accounting-policy 4 no shutdown exit spoke-sdp 8061:103742 create no shutdown exit no shutdown exit epipe 55513386 customer 4 vc-switching create description "vf=EAGG:cn=Bulldog:tl=VF" service-mtu 1526 spoke-sdp 78:55513386 create control-word no shutdown exit spoke-sdp 8245:55513386 create control-word no shutdown exit no shutdown exit epipe 55517673 customer 4 create description "vf=EAGG:cn=Bulldog:tl=2C01291821:st=act:no=NGA EPIPE#BAACTQ#VLAN 901" service-mtu 1526 service-name "epipe service-64585 DKTN08a-D0105 (63.130.108.41)" endpoint "SDP" create revert-time infinite exit sap 2/2/3:901.* create description "2_2_3,H0505824A,Bulldog,VLAN 901" ingress scheduler-policy "NGA-LLU-300M" qos 20010 exit egress scheduler-policy "NGA-LLU-300M" qos 20010 exit no shutdown exit spoke-sdp 8243:55517673 endpoint "SDP" create collect-stats precedence 1 no shutdown exit spoke-sdp 8245:55517673 endpoint "SDP" create collect-stats precedence primary no shutdown exit no shutdown exit """ > parser = ttp(data=data, template=template, log_level="ERROR") ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ test_answers_and_docs.py:1743: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError _____________________ test_github_issue_37_cleaned_up_data _____________________ def test_github_issue_37_cleaned_up_data(): """ Problem with below template without bug fix, was that 'no shutdown' statement for sap group was matched by spoke-sdp group as well and added to results causing false match. To fix it, added tracking of previously started groups in results object, so that before add match results to overall results if PATH differ need to check that this particular item groups has been started before, previous logic was not checking for that. Have not noticed any issues with other 200+ tests or any performance degradation for single/multi-process parsing. """ template = """ service {{ ignore }} epipe {{ service_id }} customer {{ customer_id }} create spoke-sdp {{ r_spoke_sdp_id }}:{{vc_id }} create no shutdown {{ state | set("enabled") }} """ data = """ service foo epipe 103076 customer 160 create description "vf=EWL:cn=TATA_COM:tl=2C02495918:st=act:" service-mtu 1588 service-name "EPIPE service-103076 DKTN08a-D0105 (63.130.108.41)" sap 1/2/12:20.* create description "vf=EWL:cn=TATA_COM:tl=2C02495890:st=act:" multi-service-site "TATA_VSNL_STRAT_A206_LAN10" ingress queue-override queue 1 create cbs default mbs 40 kilobytes rate 10000 cir 10000 exit exit exit egress queue-override queue 1 create cbs default mbs 40 kilobytes rate 10000 cir 10000 exit exit exit accounting-policy 4 no shutdown exit spoke-sdp 8051:103076 create no shutdown exit no shutdown exit epipe 103206 customer 1904 create description "vf=1273:cn=skanska:tl=3C02407455:st=act:no='SKANSKA UK PLC Stepney Green E1 3DG'" service-mtu 1988 service-name "EPIPE service-103206 DKTN08a-D0105 (63.130.108.41)" sap 2/2/3:401.100 create description "vf=1273:cn=skanska:tl=3C02407455:st=act:no='SKANSKA UK PLC Stepney Green E1 3DG'" multi-service-site "SKANSKA_E13DG_A825_LAN1" ingress qos 11010 queue-override queue 1 create cbs default mbs 1188 kilobytes rate max cir 47500 exit queue 3 create cbs default mbs 63 kilobytes rate max cir 2500 exit exit exit egress qos 11010 queue-override queue 1 create cbs default mbs 1188 kilobytes rate max cir 47500 exit queue 3 create cbs default mbs 63 kilobytes rate max cir 2500 exit exit exit collect-stats accounting-policy 4 no shutdown exit spoke-sdp 8035:103206 create no shutdown exit no shutdown exit """ > parser = ttp(data=data, template=template, log_level="ERROR") ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ test_answers_and_docs.py:2031: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError __________________ test_github_issue_37_cleaned_data_template __________________ def test_github_issue_37_cleaned_data_template(): template = """ service {{ ignore }} epipe {{ service_id }} customer {{ customer_id }} create description "{{ description | ORPHRASE }}" service-mtu {{ service_mtu }} service-name "{{ service_name | ORPHRASE }}" endpoint {{ endpoint }} create revert-time {{ revert_time }} exit {{ _end_ }} sap {{ sap_id | resub(r"\\*", "qinq") | ORPHRASE }} create description "{{ description | ORPHRASE }}" multi-service-site "{{ mss_name }}" ingress {{ _start_ }} qos {{ sap_ingress | default("1") }} scheduler-policy {{ scheduler_policy | default("none")}} exit {{ _end_ }} egress {{ _start_ }} scheduler-policy {{ scheduler_policy | default("none") }} qos {{ sap_egress | default("1)") }} exit {{ _end_ }} no shutdown {{ state | set("enabled") | default("disabled") }} exit {{ _end_ }} spoke-sdp {{ pwr_spoke_sdp_id }}:{{vc_id }} endpoint {{ endpoint }} create precedence {{ precedence | default("default_precedence") }} no shutdown {{ state | set("enabled") | default("disabled") }} exit {{ _end_ }} spoke-sdp {{ r_spoke_sdp_id }}:{{vc_id }} create no shutdown {{ state | set("enabled") | default("disabled") }} exit {{ _end_ }} no shutdown {{ state | set("enabled") | default("disabled") }} exit {{ _end_ }} exit {{ _end_ }} """ data = """ service foo epipe 103076 customer 160 create description "vf=EWL:cn=TATA_COM:tl=2C02495918:st=act:" service-mtu 1588 service-name "EPIPE service-103076 DKTN08a-D0105 (63.130.108.41)" sap 1/2/12:20.* create description "vf=EWL:cn=TATA_COM:tl=2C02495890:st=act:" multi-service-site "TATA_VSNL_STRAT_A206_LAN10" ingress queue-override queue 1 create cbs default mbs 40 kilobytes rate 10000 cir 10000 exit exit exit egress queue-override queue 1 create cbs default mbs 40 kilobytes rate 10000 cir 10000 exit exit exit accounting-policy 4 no shutdown exit spoke-sdp 8051:103076 create no shutdown exit no shutdown exit epipe 103206 customer 1904 create description "vf=1273:cn=skanska:tl=3C02407455:st=act:no='SKANSKA UK PLC Stepney Green E1 3DG'" service-mtu 1988 service-name "EPIPE service-103206 DKTN08a-D0105 (63.130.108.41)" sap 2/2/3:401.100 create description "vf=1273:cn=skanska:tl=3C02407455:st=act:no='SKANSKA UK PLC Stepney Green E1 3DG'" multi-service-site "SKANSKA_E13DG_A825_LAN1" ingress qos 11010 queue-override queue 1 create cbs default mbs 1188 kilobytes rate max cir 47500 exit queue 3 create cbs default mbs 63 kilobytes rate max cir 2500 exit exit exit egress qos 11010 queue-override queue 1 create cbs default mbs 1188 kilobytes rate max cir 47500 exit queue 3 create cbs default mbs 63 kilobytes rate max cir 2500 exit exit exit collect-stats accounting-policy 4 no shutdown exit spoke-sdp 8035:103206 create no shutdown exit no shutdown exit epipe 103256 customer 160 create description "vf=EWL:cn=TATA_COMM:tl=2C02490189:st=act:" service-mtu 1988 service-name "EPIPE service-103256 DKTN08a-D0105 (63.130.108.41)" sap 1/2/12:15.* create description "vf=EWL:cn=TATA_COMM:tl=2C02490171:st=act:" multi-service-site "TATA_VSNL_STRAT_A206_LAN5" ingress qos 11000 queue-override queue 1 create cbs default mbs 391 kilobytes rate 100000 cir 100000 exit exit exit egress qos 11000 queue-override queue 1 create cbs default mbs 391 kilobytes rate 100000 cir 100000 exit exit exit accounting-policy 4 no shutdown exit spoke-sdp 8139:103256 create no shutdown exit no shutdown exit epipe 103742 customer 160 create description "vf=EWL:cn=TATA_COM:tl=2C02410363:st=act:" service-mtu 1588 service-name "EPIPE service-103742 DKTN08a-D0105 (63.130.108.41)" sap 5/2/50:20.* create description "vf=EWL:cn=TATA_COM:tl=2C02410338:st=act:" multi-service-site "TATA_STRAT_LON_A206_LANA" ingress qos 11000 queue-override queue 1 create cbs default mbs 32 kilobytes rate 8000 cir 8000 exit exit exit egress qos 11000 queue-override queue 1 create cbs default mbs 32 kilobytes rate 8000 cir 8000 exit exit exit accounting-policy 4 no shutdown exit spoke-sdp 8061:103742 create no shutdown exit no shutdown exit epipe 55513386 customer 4 vc-switching create description "vf=EAGG:cn=Bulldog:tl=VF" service-mtu 1526 spoke-sdp 78:55513386 create control-word no shutdown exit spoke-sdp 8245:55513386 create control-word no shutdown exit no shutdown exit epipe 55517673 customer 4 create description "vf=EAGG:cn=Bulldog:tl=2C01291821:st=act:no=NGA EPIPE#BAACTQ#VLAN 901" service-mtu 1526 service-name "epipe service-64585 DKTN08a-D0105 (63.130.108.41)" endpoint "SDP" create revert-time infinite exit sap 2/2/3:901.* create description "2_2_3,H0505824A,Bulldog,VLAN 901" ingress scheduler-policy "NGA-LLU-300M" qos 20010 exit egress scheduler-policy "NGA-LLU-300M" qos 20010 exit no shutdown exit spoke-sdp 8243:55517673 endpoint "SDP" create collect-stats precedence 1 no shutdown exit spoke-sdp 8245:55517673 endpoint "SDP" create collect-stats precedence primary no shutdown exit no shutdown exit """ > parser = ttp(data=data, template=template, log_level="ERROR") ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ test_answers_and_docs.py:2308: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError _____________________________ test_github_issue_42 _____________________________ def test_github_issue_42(): data = """ vrf xyz address-family ipv4 unicast import route-target 65000:3507 65000:3511 65000:5453 65000:5535 ! export route-target 65000:5453 65000:5535 ! ! ! """ template = """ vrf {{name}} import route-target {{ _start_ }} {{ import | to_list | joinmatches }} ! export route-target {{ _start_ }} {{ export | to_list | joinmatches }} """ > parser = ttp(data=data, template=template, log_level="ERROR") ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ test_answers_and_docs.py:2518: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError _________________________ test_github_issue_42_answer __________________________ def test_github_issue_42_answer(): data = """ vrf xyz address-family ipv4 unicast import route-target 65000:3507 65000:3511 65000:5453 65000:5535 ! export route-target 65000:5453 65000:5535 ! ! ! """ template = """ vrf {{name}} import route-target {{ _start_ }} {{ import_rt | _start_ }} ! export route-target {{ _start_ }} {{ export_rt | _start_ }} """ > parser = ttp(data=data, template=template, log_level="ERROR") ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ test_answers_and_docs.py:2578: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError ________________________________ test_issue_45 _________________________________ def test_issue_45(): data = """ vrf2 { forwarding-options { dhcp-relay { server-group { IN_MEDIA_SIGNALING { 10.154.6.147; } DHCP-NGN-SIG { 10.154.6.147; } } group group2 { active-server-group IN_MEDIA_SIGNALING; overrides { trust-option-82; } } group NGN-SIG { active-server-group DHCP-NGN-SIG; overrides { trust-option-82; } } } } } """ template = """ {{ name | _start_ }} { forwarding-options { {{ _start_ }} dhcp-relay { {{ _start_ }} server-group { {{ _start_ }} {{ server_group_name1 | _start_ }} { {{ helper_address | IP }}; } {{ _end_ }} } {{ _end_ }} group {{ group_name | _start_ }} { active-server-group {{server_group_name2}}; } {{ _end_ }} } {{ _end_ }} } {{ _end_ }} } {{ _end_ }} """ > parser = ttp(data=data, template=template, log_level="ERROR") ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ test_answers_and_docs.py:2668: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError _______________________________ test_issue_45_1 ________________________________ def test_issue_45_1(): data = """ vrf2 { forwarding-options { dhcp-relay { server-group { IN_MEDIA_SIGNALING { 10.154.6.147; } group NGN-SIG { active-server-group DHCP-NGN-SIG; overrides { trust-option-82; } } } } } """ template = """ {{ name | _start_ }} { forwarding-options { {{ _start_ }} dhcp-relay { {{ _start_ }} server-group { {{ _start_ }} {{ server_group_name | _start_ }} { group {{ group_name | _start_ }} { """ > parser = ttp(data=data, template=template, log_level="ERROR") ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ test_answers_and_docs.py:2805: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError _________________________ test_issue_45_filtering_fix __________________________ def test_issue_45_filtering_fix(): data = """ vrf2 { forwarding-options { dhcp-relay { server-group { IN_MEDIA_SIGNALING { 10.154.6.147; } DHCP-NGN-SIG { 10.154.6.147; } } group group2 { active-server-group IN_MEDIA_SIGNALING; overrides { trust-option-82; } } group NGN-SIG { active-server-group DHCP-NGN-SIG; overrides { trust-option-82; } } } } } """ template = """ {{ name | _start_ }} { forwarding-options { {{ _start_ }} dhcp-relay { {{ _start_ }} server-group { {{ _start_ }} {{ server_group_name1 | _start_ | exclude("overrides") }} { {{ helper_address | IP }}; } {{ _end_ }} } {{ _end_ }} group {{ group_name | _start_ }} { active-server-group {{server_group_name2}}; } {{ _end_ }} } {{ _end_ }} } {{ _end_ }} } {{ _end_ }} """ > parser = ttp(data=data, template=template, log_level="ERROR") ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ test_answers_and_docs.py:2898: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError _____________________________ test_issue_47_answer _____________________________ def test_issue_47_answer(): data = """ Some text which indicates that below block should be included in results ABC interface Loopback0 description Router-id-loopback ip address 192.168.0.113/24 ! Some text which indicates that below block should be included in results DEF interface Loopback2 description Router-id-loopback 2 ip address 192.168.0.114/24 ! Some text which indicates that below block should NOT be included in results interface Vlan778 description CPE_Acces_Vlan ip address 2002::fd37/124 ip vrf CPE1 ! Some text which indicates that below block should be included in results GKL interface Loopback3 description Router-id-loopback 3 ip address 192.168.0.115/24 ! """ template = """ Some text which indicates that below block should be included in results ABC {{ _start_ }} Some text which indicates that below block should be included in results DEF {{ _start_ }} Some text which indicates that below block should be included in results GKL {{ _start_ }} interface {{ interface }} ip address {{ ip }}/{{ mask }} description {{ description | re(".+") }} ip vrf {{ vrf }} ! {{ _end_ }} """ > parser = ttp(data=data, template=template, log_level="ERROR") ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ test_answers_and_docs.py:2982: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError _____________________________ test_issue_48_answer _____________________________ def test_issue_48_answer(): data = """ ECON*3400 The Economics of Personnel Management U (3-0) [0.50] In this course, we examine the economics of personnel management in organizations. Using mainstream microeconomic and behavioural economic theory, we will consider such issues as recruitment, promotion, financial and non-financial incentives, compensation, job performance, performance evaluation, and investment in personnel. The interplay between theoretical models and empirical evidence will be emphasized in considering different approaches to the management of personnel. Prerequisite(s): ECON*2310 or ECON*2200 Department(s): Department of Economics and Finance ECON*4400 The Economics of Personnel Management U (7-1) [0.90] In this course, we examine the economics of personnel management in organizations. Using mainstream microeconomic and behavioural economic theory, we will consider such issues as recruitment, promotion, financial and non-financial incentives, compensation, job performance, performance evaluation, and investment in personnel. Prerequisite(s): ECON*2310 Department(s): Department of Economics """ template = """ descr_chain = [ "PHRASE", "exclude('Prerequisite(s)')", "exclude('Department(s)')", "joinmatches" ] {{ course }}*{{ code }} {{ name | PHRASE }} {{ semester }} ({{ lecture_lab_time }}) [{{ weight }}] {{ description | chain(descr_chain) }} Prerequisite(s): {{ prereqs | ORPHRASE }} Department(s): {{ department | ORPHRASE }} """ > parser = ttp(data=data, template=template, log_level="ERROR") ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ test_answers_and_docs.py:3052: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError __________________________ test_issue_48_answer_more ___________________________ def test_issue_48_answer_more(): data = """ IBIO*4521 Thesis in Integrative Biology F (0-12) [1.00] This course is the first part of the two-semester course IBIO*4521/2. This course is a two-semester (F,W) undergraduate project in which students conduct a comprehensive, independent research project in organismal biology under the supervision of a faculty member in the Department of Integrative Biology. Projects involve a thorough literature review, a research proposal, original research communicated in oral and poster presentations, and in a written, publication quality document. This two-semester course offers students the opportunity to pursue research questions and experimental designs that cannot be completed in the single semester research courses. Students must make arrangements with both a faculty supervisor and the course coordinator at least one semester in advance. A departmental registration form must be obtained from the course coordinator and submitted no later than the second class day of the fall semester. This is a twosemester course offered over consecutive semesters F-W. When you select this course, you must select IBIO*4521 in the Fall semester and IBIO*4522 in the Winter semester.A grade will not be assigned to IBIO*4521 until IBIO*4522 has been completed. Prerequisite(s): 12.00 credits Restriction(s): Normally a minimum cumulative average of 70%. Permission of course coordinator. Department(s): Department of Integrative Biology IBIO*4533 Thesis in Integrative Biology F (0-14) [2.00] This course is the first part of the two-semester course IBIO*4521/2. This course is a two-semester (F,W) undergraduate project in which students conduct a comprehensive, independent research project in organismal biology under the supervision of a faculty member in the Department of Integrative Biology. Restriction(s): Normally a minimum cumulative average of 80%. Permission of course coordinator. Normally a minimum cumulative average of 90%. Permission of course coordinator. Department(s): Department of Integrative Biology """ template = """ chain_1 = [ "ORPHRASE", "exclude('Prerequisite(s)')", "exclude('Department(s)')", "exclude('Restriction(s)')", "joinmatches" ] {{ course }}*{{ code }} {{ name | PHRASE }} {{ semester }} ({{ lecture_lab_time }}) [{{ weight }}] {{ description | chain(chain_1) }} Prerequisite(s): {{ prereqs | ORPHRASE }} Department(s): {{ department | ORPHRASE }} Restriction(s): {{ restrictions | PHRASE | joinmatches }} {{ restrictions | chain(chain_1) }} """ > parser = ttp(data=data, template=template, log_level="ERROR") ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ test_answers_and_docs.py:3153: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError ______________________ test_slack_channel_answer_for_Noif ______________________ def test_slack_channel_answer_for_Noif(): data = """ # not disabled and no comment /ip address add address=10.4.1.245 interface=lo0 network=10.4.1.245 /ip address add address=10.4.1.246 interface=lo1 network=10.4.1.246 # not disabled and comment with no quotes /ip address add address=10.9.48.241/29 comment=SITEMON interface=ether2 network=10.9.48.240 /ip address add address=10.9.48.233/29 comment=Camera interface=vlan205@bond1 network=10.9.48.232 /ip address add address=10.9.49.1/24 comment=SM-Management interface=vlan200@bond1 network=10.9.49.0 # not disabled and comment with quotes /ip address add address=10.4.1.130/30 comment="to core01" interface=vlan996@bond4 network=10.4.1.128 /ip address add address=10.4.250.28/29 comment="BH 01" interface=vlan210@bond1 network=10.4.250.24 /ip address add address=10.9.50.13/30 comment="Cust: site01-PE" interface=vlan11@bond1 network=10.9.50.12 # disabled no comment /ip address add address=10.0.0.2/30 disabled=yes interface=bridge:customer99 network=10.0.0.0 # disabled with comment /ip address add address=169.254.1.100/24 comment=Cambium disabled=yes interface=vlan200@bond1 network=169.254.1.0 # disabled with comment with quotes /ip address add address=10.4.248.20/29 comment="Backhaul to AGR (Test Segment)" disabled=yes interface=vlan209@bond1 network=10.4.248.16 """ template = """ default_values = { "comment": "", "disabled": False } ## not disabled and no comment /ip address add address={{ ip | _start_ }} interface={{ interface }} network={{ network }} ## not disabled and comment with/without quotes /ip address add address={{ ip | _start_ }}/{{ mask }} comment={{ comment | ORPHRASE | exclude("disabled=") | strip('"')}} interface={{ interface }} network={{ network }} ## disabled no comment /ip address add address={{ ip | _start_ }}/{{ mask }} disabled={{ disabled }} interface={{ interface }} network={{ network }} ## disabled with comment with/without quotes /ip address add address={{ ip | _start_ }}/{{ mask }} comment={{ comment | ORPHRASE | exclude("disabled=") | strip('"') }} disabled={{ disabled }} interface={{ interface }} network={{ network }} """ > parser = ttp(data=data, template=template, log_level="ERROR") ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ test_answers_and_docs.py:3251: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError _____________________________ test_slack_answer_2 ______________________________ def test_slack_answer_2(): data_to_parse = """ port 1/1/1 description "port 1 description" ethernet mode hybrid encap-type dot1q crc-monitor sd-threshold 5 multiplier 5 sf-threshold 3 multiplier 5 window-size 60 exit network queue-policy "ncq-only" accounting-policy 12 collect-stats egress queue-group "qos-policy-for-router1" instance 1 create accounting-policy 1 collect-stats agg-rate rate 50000 exit exit exit exit access egress queue-group "policer-output-queues" instance 1 create accounting-policy 1 collect-stats exit exit exit lldp dest-mac nearest-bridge admin-status tx-rx notification tx-tlvs port-desc sys-name sys-desc sys-cap tx-mgmt-address system exit exit down-on-internal-error exit no shutdown exit port 1/1/2 description "another port to a another router" ethernet mode hybrid encap-type dot1q egress-scheduler-policy "qos-port-scheduler" crc-monitor sd-threshold 5 multiplier 5 sf-threshold 3 multiplier 5 window-size 60 exit access egress queue-group "policer-output-queues" instance 1 create accounting-policy 1 collect-stats exit exit exit down-on-internal-error exit no shutdown exit port 1/1/3 description "port 3 to some third router" ethernet mode access encap-type dot1q mtu 2000 egress-scheduler-policy "strict-scheduler" network queue-policy "ncq-only" accounting-policy 12 collect-stats egress queue-group "some-shaping-policy" instance 1 create accounting-policy 1 collect-stats agg-rate rate 50000 exit exit queue-group "another-shaping-policy" instance 1 create accounting-policy 1 collect-stats agg-rate rate 50000 exit exit queue-group "this-shaper-is-cool" instance 1 create agg-rate rate 1000000 exit exit exit exit exit no shutdown exit """ template = """ port {{ id }} shutdown {{ admin_enabled | set(false) }} description "{{ description | ORPHRASE | strip('"') }}" ethernet {{ _start_ }} mode {{ mode }} encap-type {{ encap_type }} mtu {{ mtu | DIGIT }} egress-scheduler-policy {{ egress_sched_policy | strip('"') }} loopback internal persistent {{ loop_internal | set(true) }} network {{ _start_ }} queue-policy {{ queue_policy | ORPHRASE | strip('"') }} accounting-policy {{ accounting_policy | DIGIT }} collect-stats {{ collect_stats | set(true) }} egress {{ _start_ }} queue-group {{ name | strip('"') }} instance 1 create rate {{ agg_rate | DIGIT }} exit {{_end_}} ## this "exit {{ _end_ }}" had wrong indentation level, leading to ## group name="egress" finishing too early exit {{_end_}} exit {{_end_}} lldp {{ lldp_enabled | set(true) }} exit {{_end_}} no shutdown {{admin_enabled | set(true)}} exit {{_end_}} """ > parser = ttp(data=data_to_parse, template=template, log_level="ERROR") ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ test_answers_and_docs.py:3491: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError _____________________________ test_slack_answer_3 ______________________________ def test_slack_answer_3(): """ Problem was that interfaces were matched by regexes from both ospf and ospfv3 groups, decision logic was not able to properly work out to which group result should belong, changed behavior to check if match is a child of current record group and use it if so. Also had to change how group id encoded from string to tuple of two elements ("group path", "group index",) Here is some debug output until problem was fixed: self.record["GRP_ID"]: service.vprns*.{{id}}**.ospf3**::1 re_["GROUP"].group_id: service.vprns*.{{id}}**.ospf**.interfaces*::0 re_idex: 0 self.record["GRP_ID"]: service.vprns*.{{id}}**.ospf3**::1 re_["GROUP"].group_id: service.vprns*.{{id}}**.ospf3**.interfaces*::0 re_idex: 1 # problem was happening because logic was not able to decide that need to use this match self.record["GRP_ID"]: service.vprns*.{{id}}**.ospf**::0 re_["GROUP"].group_id: service.vprns*.{{id}}**.ospf**.interfaces*::0 re_idex: 0 # problem was happening because logic was picking up this match self.record["GRP_ID"]: service.vprns*.{{id}}**.ospf**::0 re_["GROUP"].group_id: service.vprns*.{{id}}**.ospf3**.interfaces*::0 re_idex: 1 Wrong results: [[{'service': {'vprns': [{'4': {'name': 'ospf_version3_vprn', 'ospf': {'area': '0.0.0.0', 'interfaces': [{'name': 'interface-one'}]}, 'ospf3': {'area': '0.0.0.0', 'interfaces': [{'name': 'interface-two'}]}}, '5': {'name': 'vprn5', 'ospf': {'area': '0.0.0.0'}, 'ospf3': {'interfaces': [{'name': 'interface-three'}]}}}]}}]] """ data = """ service vprn 4 name "ospf_version3_vprn" customer 40 create ospf area 0.0.0.0 interface "interface-one" ospf3 0 area 0.0.0.0 interface "interface-two" vprn 5 name "vprn5" customer 50 create ospf area 0.0.0.0 interface "interface-three" """ template = """ vprn {{ id }} name {{ name | ORPHRASE | strip('"') }} customer {{ ignore }} create ospf {{ _start_ }} area {{ area }} interface {{ name | ORPHRASE | strip('"') }} ospf3 0 {{ _start_ }} area {{ area }} interface {{ name | ORPHRASE | strip('"') }} """ > parser = ttp(data, template, log_level="ERROR") ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ test_answers_and_docs.py:3642: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError ___________________________ test_slack_answer_3_full ___________________________ def test_slack_answer_3_full(): data = """ service vprn 1 name "vprn1" customer 10 create interface "loopback" create exit interface "interface-one" create exit interface "interface-two" create exit interface "bgp-interface" create exit exit vprn 2 name "vprn2" customer 20 create interface "loopback" create exit interface "interface-two" create exit interface "bgp-interface" create exit exit vprn 3 name "vprn3" customer 30 create interface "loopback" create exit interface "interface-two" create exit exit vprn 4 name "ospf_version3_vprn" customer 40 create interface "loopback" create exit interface "interface-two" create exit exit vprn 5 name "vprn5" customer 50 create interface "loopback" create exit interface "interface-two" create exit interface "bgp-interface" create exit exit vprn 1 name "vprn1" customer 10 create interface "loopback" create address 10.10.10.1/32 loopback exit interface "interface-one" create address 10.10.10.10/30 sap 1/1/1:10 create exit exit interface "interface-two" create address 10.10.10.100/31 sap lag-5:80 create exit exit interface "bgp-interface" create address 10.10.10.200/31 sap lag-4:100 create exit exit ospf area 0.0.0.0 interface "interface-two" passive no shutdown exit exit no shutdown exit no shutdown exit vprn 2 name "vprn2" customer 20 create interface "interface-two" create address 10.11.11.10/31 sap lag-1:50 create exit exit ospf area 0.0.0.0 interface "interface-two" passive no shutdown exit exit no shutdown exit no shutdown exit vprn 3 name "vprn3" customer 30 create interface "loopback" create address 10.12.12.12/32 loopback exit interface "interface-two" create address 10.12.12.100/31 sap lag-5:33 create exit exit ospf area 0.0.0.0 interface "interface-two" passive no shutdown exit exit no shutdown exit no shutdown exit vprn 4 name "ospf_version3_vprn" customer 40 create interface "loopback" create address 10.40.40.10/32 ipv6 address 1500:1000:460e::a03:ae46/128 exit loopback exit interface "interface-two" create address 10.40.40.100/31 ipv6 address 1500:1000:460e::2222:1111/64 exit sap lag-5:800 create exit exit ospf area 0.0.0.0 interface "interface-two" passive no shutdown exit exit no shutdown exit ospf3 0 area 0.0.0.0 interface "interface-two" passive no shutdown exit exit no shutdown exit no shutdown exit vprn 5 name "vprn5" customer 50 create interface "loopback" create address 10.50.50.50/32 loopback exit interface "interface-two" create address 10.50.50.100/31 sap lag-5:5 create exit exit interface "bgp-interface" create address 10.50.50.200/31 sap lag-1:602 create exit exit bgp group "eBGP" peer-as 4444 neighbor 10.50.50.201 exit exit no shutdown exit ospf area 0.0.0.0 interface "interface-two" passive no shutdown exit exit no shutdown exit no shutdown exit exit """ template = """ #-------------------------------------------------- {{ ignore }} echo "Service Configuration" {{ ignore }} #-------------------------------------------------- {{ ignore }} service {{ ignore }} vprn {{ id }} name {{ name | ORPHRASE | strip('"') }} customer {{ ignore }} create shutdown {{ admin_enabled | set("False") }} description {{ description | ORPHRASE | strip('"') }} vrf-import {{ import_policy | ORPHRASE | strip('"') }} router-id {{ router_id }} autonomous-system {{ local_as }} route-distinguisher {{ loopback_ip }}:{{ vrf_routedist }} vrf-target target:{{ ignore }}:{{ vrf_routetarget }} vrf-target {{ vrf_export }} target:{{ ignore }}:{{ vrf_routetarget }} interface {{ name | ORPHRASE | strip('"') }} create shutdown {{ admin_enabled | set("False") }} description {{ description | ORPHRASE | strip('"') }} address {{ address | IP }}/{{ mask | DIGIT }} ip-mtu {{ mtu }} bfd {{ bfd_timers }} receive {{ ignore }} multiplier {{ bfd_interval }} vrrp {{ instance }} backup {{ backup }} priority {{ priority }} policy {{ policy }} ping-reply {{ pingreply | set("True") }} traceroute-reply {{ traceroute_reply | set("True") }} init-delay {{ initdelay }} message-interval {{ message_int_seconds }} message-interval milliseconds {{ message_int_milliseconds }} bfd-enable 1 interface {{ bfd_interface | ORPHRASE | strip('"')}} dst-ip {{ bfd_dst_ip }} exit {{ _end_ }} ipv6 {{ _start_ }} address {{ address | IPV6 }}/{{ mask | DIGIT }} address {{ address | _start_ | IPV6 }}/{{ mask | DIGIT }} dad-disable link-local-address {{ linklocal_address | IPV6 }} dad-disable vrrp {{ instance | _start_ }} backup {{ ip }} priority {{ priority }} policy {{ policy }} ping-reply {{ pingreplay | set("True") }} traceroute-reply {{ traceroute_reply | set("True") }} init-delay {{ initdelay }} message-interval milliseconds {{ message_int_milliseconds }} exit {{ _end_ }} exit {{ _end_ }} vpls {{ vpls_name | ORPHRASE | strip('"') | _start_ }} exit {{ _end_ }} sap {{ port | _start_ }}:{{ vlan | DIGIT }} create ingress {{ _exact_ }} qos {{ qos_sap_ingress }} egress {{ _start_ }} qos {{ qos_sap_egress }} collect-stats {{ collect_stats | set("True") }} accounting-policy {{ accounting_policy }} exit {{ _end_}} exit {{ _end_}} static-route-entry {{ prefix | PREFIX | _start_ }} black-hole {{ blackhole | set("True") }} next-hop {{ nexthop | IP }} shutdown {{ admin_enabled | set("False") }} no shutdown {{ admin_enabled | set("True") }} exit {{ _end_ }} aggregate {{ agg_block | PREFIX | _start_ }} summary-only router-advertisement {{ _start_ }} interface {{ interface | ORPHRASE | strip('"') }} use-virtual-mac {{ use_virtualmac | set("True") }} no shutdown {{ admin_enabled | set("True") }} exit {{ _end_ }} bgp {{ _start_ }} min-route-advertisement {{ min_route_advertisement | DIGIT }} group {{ name | ORPHRASE | strip('"') }} family {{ family | ORPHRASE | split(" ") }} type {{ peer_type | ORPHRASE }} import {{ importpolicy | ORPHRASE | strip('"') }} export {{ exportpolicy | ORPHRASE | strip('"') }} peer-as {{ remote_as }} bfd-enable {{ bfd_enabled | set("True") }} neighbor {{ address | IP | _start_ }} neighbor {{ address | IPV6 | _start_ }} shutdown {{ admin_enabled | set("False") }} keepalive {{ keepalive }} hold-time {{ holdtime }} bfd-enable {{ bfd_enabled | set("True") }} as-override {{ as_override | set("True") }} exit {{ _end_ }} exit {{ _end_ }} no shutdown {{ admin_enabled | set("True") | _start_ }} exit {{ _end_ }} ospf {{ _start_ }}{{ _exact_ }} area {{ area }} interface {{ name | ORPHRASE | strip('"') | _start_ }} passive {{ passive | set("True") }} exit {{ _end_ }} no shutdown {{ admin_enabled | set("True") }} exit {{ _end_ }} ospf3 0 {{ _start_ }}{{ _exact_ }} area {{ area }} interface {{ name | ORPHRASE | strip('"') | _start_ }} passive {{ passive | set("True") }} exit {{ _end_ }} no shutdown {{ admin_enabled | set("True") }} exit {{ _end_ }} no shutdown {{ admin_enabled | set("True") }} exit {{ _end_ }} """ > parser = ttp(data, template, log_level="ERROR") ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ test_answers_and_docs.py:4006: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError _________________________ test_issue_45_for_junos_cfg __________________________ def test_issue_45_for_junos_cfg(): data = """ system { host-name LAB-MX-1; time-zone some/time; default-address-selection; no-redirects; no-ping-record-route; no-ping-time-stamp; tacplus-server { 1.1.1.1 { port 49; secret ""; ## SECRET-DATA source-address 5.5.5.5; } 2.2.2.2 { port 49; secret ""; ## SECRET-DATA source-address 5.5.5.5; } 4.4.4.4 { port 49; secret ""; ## SECRET-DATA source-address 5.5.5.5; } } services { ssh { root-login deny; no-tcp-forwarding; protocol-version v2; max-sessions-per-connection 32; client-alive-count-max 3; client-alive-interval 10; connection-limit 10; rate-limit 5; } netconf { ssh { connection-limit 10; rate-limit 4; } } } } """ template = """ system { {{ _start_ }} host-name {{ HOSTNAME }}; time-zone {{ TZ }}; default-address-selection; {{ default_address_selection | set(True) }} no-redirects; {{ no_redirects | set(True) }} no-ping-record-route; {{ no_ping_record_route | set(True) }} no-ping-time-stamp; {{ no_ping_time_stamp | set(True) }} services { {{ _start_ }} {{ service }} { http; {{ http | set(true) }} https; {{ https | set(true) }} no-tcp-forwarding; {{ no-tcp-fwding | set(true) }} protocol-version {{ ssh-proto }}; connection-limit {{ connection-limit | DIGIT }}; rate-limit {{rate-limit | DIGIT }}; root-login deny; {{ root-login | set(false) }} max-sessions-per-connection {{ max-sessions | DIGIT }}; client-alive-count-max {{ client-alive-count-max | DIGIT }}; client-alive-interval {{ client-alive-interval | DIGIT }}; ssh; {{ ssh | set(true) }} ssh { {{ _start_ }} connection-limit {{ connection-limit | DIGIT }}; rate-limit {{ rate-limit | DIGIT }}; } {{ _end_ }} } {{ _end_ }} } {{ _end_ }} internet-options { {{ _start_ }} icmpv4-rate-limit packet-rate {{ packet-rate| DIGIT }}; icmpv6-rate-limit packet-rate {{ packet-rate| DIGIT }}; no-source-quench; {{ no-source-quench | set(true) }} tcp-drop-synfin-set; {{ tcp-drop-synfin-set | set(true) }} no-tcp-reset {{ no-tcp-reset }}; } {{ _end_ }} authentication-order [{{ authentication-order }}]; ports { {{ _start_ }} auxiliary disable; {{ auxiliary | set(false) }} } {{ _end_ }} root-authentication { {{ _start_ }} encrypted-password "{{ encrypted-password }}"; ## SECRET-DATA } {{ _end_ }} name-server { {{ _start_ }} {{ name_server | IP | _line_ | to_list }}; } {{ _end_ }} commit { {{ _start_ }} synchronize; {{ commit_sync | set(true) }} persist-groups-inheritance; {{ commit_persist-groups-inherit | set(true) }} } {{ _end_ }} tacplus-server { {{ _start_ }} {{ tac_server | IP }} { port {{ tac_port }}; secret "{{ tac_secret }}"; ## SECRET-DATA source-address {{ tac_source | IP }}; } {{ end }} } {{ end }} } {{ end }} """ > parser = ttp(data, template, log_level="ERROR") ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ test_answers_and_docs.py:4312: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError ______________________ test_faq_multiline_output_matching ______________________ def test_faq_multiline_output_matching(): data = """ Local Intf: Te2/1/23 System Name: r1.lab.local System Description: Cisco IOS Software, Catalyst 1234 L3 Switch Software (cat1234e-ENTSERVICESK9-M), Version 1534.1(1)SG, RELEASE SOFTWARE (fc3) Technical Support: http://www.cisco.com/techsupport Copyright (c) 1986-2012 by Cisco Systems, Inc. Compiled Sun 15-Apr-12 02:35 by p Time remaining: 92 seconds """ template = """ Local Intf: {{ local_intf }} System Name: {{ peer_name }} System Description: {{ _start_ }} {{ sys_description | _line_ | joinmatches(" ") }} Time remaining: {{ ignore }} seconds {{ _end_ }} """ > parser = ttp(data, template, log_level="ERROR") ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ test_answers_and_docs.py:4395: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError _____________________________ test_issue_52_answer _____________________________ def test_issue_52_answer(): data = """ Origin: Some random name Example Address, example number, example city Origin: Some random name 2 Example Address, example number, example city 2 Origin: Some random name 3 Example Address, example number, example city 3 One more string """ template = """ def process(data): lines = data["match"].splitlines() name = lines[0] address = lines[1] return {"name": name, "address": address} Origin: {{ _start_ }} {{ match | _line_ | joinmatches }} """ > parser = ttp(data, template, log_level="ERROR") ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ test_answers_and_docs.py:4451: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError _____________________________ test_issue_51_answer _____________________________ def test_issue_51_answer(): """ test workaround for removing <> chars from input data """ data = """ Name:Jane
Name:Michael
Name:July
""" template = """ Name:{{ name }}<br> """ # this works as well # template = "Name:{{ name }}br" # data = data.replace("<", "").replace(">", "") # this did not work. fails with xml parsing error # template = "Name:{{ name }}<br>" # data = data.replace("<", "<").replace(">", ">") > parser = ttp(data, template, log_level="ERROR") ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ test_answers_and_docs.py:4501: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError ________________________________ test_issue_50 _________________________________ def test_issue_50(): template = """ interface "BNG-RH201-CORE" address 11.11.11.11/31 description "BNG-RH201-CORE" ldp-sync-timer 10 port lag-107:709 ipv6 address 1111:0:1111:1111::1/64 exit bfd 150 receive 150 multiplier 3 no shutdown exit interface "BNG-RH202-CORE" address 22.22.22.22/31 description "BNG-RH201-CORE" ldp-sync-timer 10 port lag-108:809 ipv6 address 2222:0:2222:2222::2/64 exit bfd 150 receive 150 multiplier 3 no shutdown exit interface "system" address 33.33.33.33/32 ipv6 address 3333:0:3333:3333::3/128 exit no shutdown exit ies 97 name "OTDR-MGT" customer 1 create description "OTDR-MGT" interface "OTDR-MGT" create address 44.44.44.44/25 vrrp 97 backup 10.20.30.1 priority 200 exit vpls "OTDR-MGT-VPLS" exit exit no shutdown exit ies 99 name "OLT-MGT" customer 1 create description "OLT-INBAND-MGT" interface "OLT-MGT" create address 55.55.55.55/25 vrrp 1 backup 10.20.40.1 priority 200 exit vpls "OLT-MGT-VPLS" exit exit no shutdown exit ies 100 name "100" customer 1 create description "IES 100 for subscribers" redundant-interface "shunt" create address 66.66.66.66/31 spoke-sdp 1:100 create no shutdown exit exit subscriber-interface "s100" create description " Subscriber interface for subscribers" allow-unmatching-subnets address 77.77.77.77/22 gw-ip-address 77.77.77.1 address 88.88.88.88/20 gw-ip-address 88.88.88.1 group-interface "s100-lag210-vlan101" create tos-marking-state trusted ipv6 router-advertisements managed-configuration no shutdown exit dhcp6 proxy-server no shutdown exit exit exit exit exit ## group to match top level interfaces interface "{{ name }}" description {{ description | re(".+") | strip('"') }} address {{ ipv4 | joinmatches('; ') }} address {{ ipv6 | contains(":") | joinmatches('; ') }} exit {{ _end_ }} ## group to match lower level interfaces interface "{{ name | _start_ }}" create {{ iftype }}-interface "{{ name | _start_ }}" create description {{ description | re(".+") | strip('"') | strip }} address {{ ipv4 | contains(".") | joinmatches('; ') }} address {{ ipv4 | contains(".") | joinmatches('; ') }} gw-ip-address {{ ignore }} exit {{ _end_ }} """ > parser = ttp(template=template, log_level="ERROR") ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ test_answers_and_docs.py:4624: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError _____________________________ test_start_with_set ______________________________ def test_start_with_set(): data = """ authentication { inactive: authentication { """ template = """ authentication { {{ inactive | set(False) | _start_ }} inactive: authentication { {{ inactive | set(True) | _start_ }} """ > parser = ttp(data, template, log_level="ERROR") ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ test_answers_and_docs.py:4672: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError ____________________________ test_ios_bgp_pers_pars ____________________________ def test_ios_bgp_pers_pars(): template = """ defaults_bgp_peers = { "description": "", "remote-as": "", "shutdown": "no", "inherit_peer-session": "", "update-source": "", "password": "" } router bgp {{ ASN }} neighbor {{ PeerIP }} remote-as {{ remote-as }} neighbor {{ PeerIP }} description {{ description | ORPHRASE }} neighbor {{ PeerIP | let("shutdown", "yes") }} shutdown neighbor {{ PeerIP }} inherit peer-session {{ inherit_peer-session }} neighbor {{ PeerIP }} password {{ password | ORPHRASE }} neighbor {{ PeerIP }} update-source {{ update-source }} """ data = """ router bgp 65100 neighbor 1.1.1.1 remote-as 1234 neighbor 1.1.1.1 description Some Description here neighbor 1.1.1.1 shutdown neighbor 1.1.1.1 inherit peer-session session_1 neighbor 1.1.1.1 password 12345678 neighbor 1.1.1.1 update-source Loopback 1 neighbor 1.1.1.2 remote-as 1234 neighbor 1.1.1.2 inherit peer-session session_1 neighbor 1.1.1.2 update-source Loopback 1 """ > parser = ttp(data, template, log_level="DEBUG") ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ test_answers_and_docs.py:4721: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError ------------------------------ Captured log call ------------------------------- INFO ttp.ttp:ttp.py:84 ttp.lazy_import_functions: starting functions lazy import INFO ttp.ttp:ttp.py:122 ttp.lazy_import_functions: loading files for ast parsing ___________________________ test_ip_address_parsing ____________________________ def test_ip_address_parsing(): data = """ interface Vlan99 description vlan99_interface ip address 20.99.10.1 255.255.255.0 secondary ip address 30.99.10.1 255.255.255.0 secondary ip address 10.99.10.1 255.255.255.0 load-interval 60 bandwidth 10000000 ! interface Vlan100 description vlan100_interface ip address 10.100.10.1 255.255.255.0 load-interval 60 bandwidth 10000000 ! """ template = """ interface {{ interface }} description {{ description }} ip address {{ ipv4_addr | PHRASE | exclude("secondary") | to_ip | with_prefixlen }} load-interval {{ load-interval }} bandwidth {{ bandwidth }} ip address {{ ipv4_addr | PHRASE | let("is_secondary", True) | to_ip | with_prefixlen }} secondary """ > parser = ttp(data, template) ^^^^^^^^^^^^^^^^^^^ test_answers_and_docs.py:4785: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError ______________________________ test_vlans_parsing ______________________________ def test_vlans_parsing(): template = """ {{ port }} {{ mode }} {{ encap }} {{ satus }} {{ native_vlan | DIGIT }} Port Vlans allowed on trunk {{ _start_ }} {{ port }} {{ vlans | unrange('-', ',') | split(",") }} {{ _end_ }} Port Vlans allowed and active in management domain {{ _start_ }} {{ port }} {{ vlans | unrange('-', ',') | split(",") }} {{ _end_ }} Port Vlans in spanning tree forwarding state and not pruned {{ _start_ }} {{ port }} {{ vlans | unrange('-', ',') | split(",") }} {{ _end_ }} """ data = """ Port Mode Encapsulation Status Native vlan Gi0 on 802.1q trunking 1 Gi7 on 802.1q trunking 1 Port Vlans allowed on trunk Gi0 1,8,999,1002-1005 Gi7 1,100,120,1000,1002-1005 Port Vlans allowed and active in management domain Gi0 1,8,999 Gi7 1,100,120,1000 Port Vlans in spanning tree forwarding state and not pruned Gi0 1,8,999 Gi7 1,100,120,1000 """ > parser = ttp(data, template, log_level="DEBUG") ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ test_answers_and_docs.py:4867: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError ------------------------------ Captured log call ------------------------------- INFO ttp.ttp:ttp.py:84 ttp.lazy_import_functions: starting functions lazy import INFO ttp.ttp:ttp.py:122 ttp.lazy_import_functions: loading files for ast parsing ____________ test_asa_acls_issue_55_uses_itemize_with_dynamic_path _____________ def test_asa_acls_issue_55_uses_itemize_with_dynamic_path(): data = """ object-group service gokuhead service-object tcp-udp destination eq gokurpc service-object tcp destination eq 902 service-object tcp destination eq https service-object tcp destination eq nfs service-object tcp destination eq 10025 object-group network gohan network-object object gohan-01 network-object object gohan-02 network-object object vlan_944 network-object object gohan-03 network-object object gohan-05 network-object object gohan-06 object-group service sql tcp port-object eq 1433 object-group network vegeta group-object trunks network-object object vegeta-01 object-group network Space-Users network-object object ab network-object object ac network-object object ad network-object object ae network-object object af network-object object ag network-object object ah network-object object ai network-object object aj object-group network dalmatians network-object object dog-01 group-object trunks network-object object vlan_950 group-object Space-Users network-object object Darts-Summary """ template = """ SVC_PORTS = "tcp-udp|tcp|udp" object-group {{ object_type }} {{ object_name | _start_ }} object-group {{ object_type }} {{ object_name | _start_ }} {{ protocol | re("SVC_PORTS")}} description {{ description | re(".*") }} network-object object {{ obj_name | let("type", "network") }} network-object host {{ obj_name | IP | let("type", "network") }} group-object {{ obj_name | let("type", "group") }} service-object object {{ obj_name | let("type", "service") }} service-object {{ obj_name | let("type", "service") }} service-object {{ protocol | re("SVC_PORTS") }} destination eq {{port}} service-object {{ protocol | re("SVC_PORTS") }} destination range {{port_begin}} {{port_end}} port-object eq {{ port_obj }} """ > parser = ttp(data, template) ^^^^^^^^^^^^^^^^^^^ test_answers_and_docs.py:5000: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError ____________________________ test_asa_acls_issue_55 ____________________________ def test_asa_acls_issue_55(): data = """ object-group service gokuhead service-object tcp-udp destination eq gokurpc service-object tcp destination eq 902 service-object tcp destination eq https service-object tcp destination eq nfs service-object tcp destination eq 10025 object-group network gohan network-object object gohan-01 network-object object gohan-02 network-object object vlan_944 network-object object gohan-03 network-object object gohan-05 network-object object gohan-06 object-group service sql tcp port-object eq 1433 object-group network vegeta group-object trunks network-object object vegeta-01 object-group network Space-Users network-object object ab network-object object ac network-object object ad network-object object ae network-object object af network-object object ag network-object object ah network-object object ai network-object object aj object-group network dalmatians network-object object dog-01 group-object trunks network-object object vlan_950 group-object Space-Users network-object object Darts-Summary """ template = """ SVC_PORTS = "tcp-udp|tcp|udp" object-group {{ object_type }} {{ object_name | _start_ }} object-group {{ object_type }} {{ object_name | _start_ }} {{ protocol | re("SVC_PORTS")}} description {{ description | re(".*") }} network-object object {{ obj_name | }} network-object host {{ obj_name | IP }} group-object {{ obj_name }} service-object object {{ obj_name }} service-object {{ obj_name }} service-object {{ protocol | re("SVC_PORTS") }} destination eq {{port}} service-object {{ protocol | re("SVC_PORTS") }} destination range {{port_begin}} {{port_end}} port-object eq {{ port_obj }} """ > parser = ttp(data, template) ^^^^^^^^^^^^^^^^^^^ test_answers_and_docs.py:5135: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError ________________________ test_issue_57_headers_parsing _________________________ def test_issue_57_headers_parsing(): """ Issue first was with startempty match not beeing selected in favour of start match produced by headers : Interface Link Protocol Primary_IP Description {{ _headers_ }} that was fixed by adding this code to the TTP selection logic for multiple matches: # startempty RE always more preferred if startempty_re: for index in startempty_re: re_ = result[index][0] result_data = result[index][1] # skip results that did not pass validation check if result_data == False: continue # prefer result with same path as current record elif re_["GROUP"].group_id == self.record["GRP_ID"]: break # prefer children of current record group elif self.record["GRP_ID"] and re_["GROUP"].group_id[ 0 ].startswith(self.record["GRP_ID"][0]): break # start RE preferred next elif start_re: Another problem was with Interface Link Protocol Primary_IP Description {{ _headers_ }} matching on "Duplex: (a)/A - auto; H - half; F - full" line, that was fixed by chaning _end_ logic by introducing self.ended_groups set to _results_class and replacing self.GRPLOCL with logic to use self.ended_groups instead. All in all it resulted in better _end_ handling behavior and allowed to fix issue 45 as well where before this one had to use filtering instead, but now _end_ also helps. """ data = """ Brief information on interfaces in route mode: Link: ADM - administratively down; Stby - standby Protocol: (s) - spoofing Interface Link Protocol Primary IP Description InLoop0 UP UP(s) -- REG0 UP -- -- Vlan401 UP UP 10.251.147.36 HSSBC_to_inband_mgmt_r4 Brief information on interfaces in bridge mode: Link: ADM - administratively down; Stby - standby Speed: (a) - auto Duplex: (a)/A - auto; H - half; F - full Type: A - access; T - trunk; H - hybrid Interface Link Speed Duplex Type PVID Description BAGG1 UP 20G(a) F(a) T 1 to-KDC-R4.10-Core-1 BAGG14 UP 10G(a) F(a) T 1 KDC-R429-E1 BackUp Chassis BAGG22 UP 20G(a) F(a) T 1 HSSBC-NS-01 FGE1/0/49 DOWN auto A A 1 XGE1/0/1 UP 10G(a) F(a) T 1 KDC-R402-E1 Backup Chassis """ template = """ Brief information on interfaces in route mode: {{ _start_ }} Interface Link Protocol Primary_IP Description {{ _headers_ }} {{ _end_ }} Brief information on interfaces in bridge mode: {{ _start_ }} Interface Link Speed Duplex Type PVID Description {{ _headers_ }} {{ _end_ }} """ > parser = ttp(data, template, log_level="error") ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ test_answers_and_docs.py:5274: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError _________________ test_issue_57_headers_parsing_using_columns __________________ def test_issue_57_headers_parsing_using_columns(): """ Added columns for headers, now can adjust headers size as required to filter unwanted results """ data = """ Brief information on interfaces in route mode: Link: ADM - administratively down; Stby - standby Protocol: (s) - spoofing Interface Link Protocol Primary IP Description InLoop0 UP UP(s) -- REG0 UP -- -- Vlan401 UP UP 10.251.147.36 HSSBC_to_inband_mgmt_r4 Brief information on interfaces in bridge mode: Link: ADM - administratively down; Stby - standby Speed: (a) - auto Duplex: (a)/A - auto; H - half; F - full Type: A - access; T - trunk; H - hybrid Interface Link Speed Duplex Type PVID Description BAGG1 UP 20G(a) F(a) T 1 to-KDC-R4.10-Core-1 BAGG14 UP 10G(a) F(a) T 1 KDC-R429-E1 BackUp Chassis BAGG22 UP 20G(a) F(a) T 1 HSSBC-NS-01 FGE1/0/49 DOWN auto A A 1 XGE1/0/1 UP 10G(a) F(a) T 1 KDC-R402-E1 Backup Chassis """ template = """ Brief information on interfaces in route mode: {{ _start_ }} Interface Link Protocol Primary_IP Description {{ _headers_ | columns(5)}} {{ _end_ }} Brief information on interfaces in bridge mode: {{ _start_ }} Interface Link Speed Duplex Type PVID Description {{ _headers_ | columns(7) }} {{ _end_ }} """ > parser = ttp(data, template, log_level="error") ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ test_answers_and_docs.py:5413: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError ___________ test_interface_template_not_collecting_all_data_solution ___________ def test_interface_template_not_collecting_all_data_solution(): data = """ interface Bundle-Ether10 description Bundle-Ether10 bfd mode ietf bfd address-family ipv4 multiplier 3 bfd address-family ipv4 destination 192.168.1.7 bfd address-family ipv4 fast-detect bfd address-family ipv4 minimum-interval 100 mtu 9114 ipv4 address 192.168.1.6 255.255.255.254 ipv6 address fc00::1:5/127 load-interval 30 ! interface Bundle-Ether51 description Bundle-Ether51 bfd mode ietf bfd address-family ipv4 multiplier 3 bfd address-family ipv4 destination 192.168.1.2 bfd address-family ipv4 fast-detect bfd address-family ipv4 minimum-interval 100 mtu 9114 ipv4 address 192.168.1.3 255.255.255.254 ipv6 address fc00::1:3/127 load-interval 30 ! interface Loopback0 description Loopback0 ipv4 address 10.1.1.1 255.255.255.255 ipv4 address 10.2.2.2 255.255.255.255 secondary ipv6 address fc00::1/128 ipv6 address fc00::101/128 ! interface Loopback1 description Loopback1 ipv4 address 10.100.0.1 255.255.255.0 ipv4 address 10.100.1.1 255.255.255.0 secondary ipv4 address 10.100.2.1 255.255.255.0 secondary ipv6 address fc00:100::1/64 ipv6 address fc00:100::101/64 ipv6 address fc00:100::201/64 ! interface MgmtEth0/RP0/CPU0/0 description MgmtEth0/RP0/CPU0/0 cdp vrf VRF-MGMT ipv4 address 172.23.136.21 255.255.252.0 ! interface GigabitEthernet0/0/0/12 description GigabitEthernet0/0/0/12 mtu 9018 lldp receive disable transmit disable ! negotiation auto load-interval 30 l2transport ! ! interface TenGigE0/0/0/4 description TenGigE0/0/0/4 bundle id 51 mode active cdp load-interval 30 ! interface TenGigE0/0/0/5 shutdown ! interface TenGigE0/0/0/5.100 l2transport description TenGigE0/0/0/5.100 ! interface TenGigE0/0/0/47 description TenGigE0/0/0/47 shutdown mac-address 201.b19.1234 ! interface BVI101 cdp description BVI101 ipv4 address 192.168.101.1 255.255.255.0 load-interval 30 mac-address 200.b19.4321 ! interface HundredGigE0/0/1/0 description HundredGigE0/0/1/0 bundle id 10 mode active cdp load-interval 30 mac-address 200.b19.5678 ! interface preconfigure GigabitEthernet0/0/0/11 description GigabitEthernet0/0/0/11 shutdown ! interface preconfigure GigabitEthernet0/0/0/16 description GigabitEthernet0/0/0/16 shutdown ! interface preconfigure GigabitEthernet0/0/0/17 description GigabitEthernet0/0/0/17 shutdown ! """ template_original = """ Template for capturing interface configuration data from IOS-XR devices Note: In order to different interface appearances, the interface block has been replicated. Be sure to update all blocks accordingly when adding any new values to capture. intf_defaults = { "description": None, "speed": None, "negotiation": None, "disabled": False, "mode": None, } ## parses ipv4 addresses to determine which is primary and which are secondary ## and converts dotted-quad subnet mask into cidr format def ipv4_macro(data): data_list = list(data.split(" ")) addr = str(data_list[0]) mask = str(data_list[1]) mask = str(sum(bin(int(x)).count('1') for x in mask.split('.'))) ipv4 = addr+"/"+mask if 'secondary' in data: is_secondary = True else: is_secondary = False result = { "ipv4" : ipv4, "is_secondary" : is_secondary } return result interface {{ interface | _start_}} interface {{ interface | let("mode", "l2transport") | _start_ }} l2transport interface preconfigure {{ interface | let("mode", "preconfigure") | _start_ }} description {{ description | re(".+") }} speed {{ speed }} negotiation {{ negotiation }} shutdown {{ disabled | set(True) }} mac-address {{ mac_address }} ipv4 address {{ ipv4 | PHRASE | _exact_ | macro("ipv4_macro") }} ipv6 address {{ ipv6 | ORPHRASE | _exact_ }} ! {{ _end_ }} """ > parser = ttp(data, template_original, log_level="error") ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ test_answers_and_docs.py:5649: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError ___________ test_interface_template_not_collecting_all_data_reduced ____________ def test_interface_template_not_collecting_all_data_reduced(): """ Below template and data were producing this result: [[{'interfaces': [{'interface': 'TenGigE0/0/0/5.100'}, {'interface': 'BVI101', 'ipv4': [{'ipv4': '192.168.101.1 255.255.255.0'}]}]}]] TTP was not collecting mac-address for BVI 101 """ data = """ interface TenGigE0/0/0/5.100 l2transport ! interface BVI101 ipv4 address 192.168.101.1 255.255.255.0 mac-address 200.b19.4321 ! """ template = """ ## matches primary interfaces interface {{ interface }} ipv4 address {{ ipv4 | _line_ | _exact_ }} mac-address {{ mac_address }} ## matches sub-interfaces interface {{ interface }} l2transport mac-address {{ mac_address }} """ > parser = ttp(data, template, log_level="error") ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ test_answers_and_docs.py:6077: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError ________________________________ test_issue_61 _________________________________ def test_issue_61(): data = """ banner motd & BANNER MESSAGE line 1 BANNER MESSAGE line 2 BANNER MESSAGE line 3 & some other staff """ template_to_match_marker = "banner motd {{ marker }}" template_to_parse_banner = """ banner motd {{ ignore(banner_marker) }} {{ _start_ }} {{ banner_mesage | _line_ | joinmatches("\\n") }} {{ ignore(banner_marker) }} {{ _end_ }} """ # extract marker value > parser = ttp(data, template_to_match_marker) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ test_answers_and_docs.py:6186: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError _________________________ test_fortigate_intf_parsing __________________________ def test_fortigate_intf_parsing(): template = """ config system interface {{ _start_ }} edit "{{ interface }}" set allowaccess {{ allowaccess }} set description "{{ description }}" set interface "{{ phy_interface }}" set snmp-index {{ snmp_index }} set type {{ fgt_int_type }} set vdom "{{ vdom }}" set vlanid {{ vlan }} next {{ _end_ }} end {{ _end_ }} """ data = """ config system np6 edit "np6_0" next end config system interface edit "mgmt1" set vdom "root" set ip 10.10.10.1 255.255.255.248 set allowaccess ping set type physical set description "mgmt1" set snmp-index 1 next edit "port1" set vdom "internal" set ip 20.20.20.1 255.255.255.248 set allowaccess ping set type physical set snmp-index 2 next end config system custom-language edit "en" set filename "en" next edit "fr" set filename "fr" next end """ > parser = ttp(data, template) ^^^^^^^^^^^^^^^^^^^ test_answers_and_docs.py:6250: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError ____________________________ test_issue_57_one_more ____________________________ def test_issue_57_one_more(): """ Without _anonymous_ group groups id formation bug fix below template/data were producitng this result: [[{'portchannel': {'1': {'local_members': [{}], 'remote_members': [{'flag': '{EF}', 'interface': 'GE6/0/1', 'mac': '0000-0000-0000', 'oper_key': '0', 'priority': '32768', 'status': '0', 'sys_id': '0x8000'}, {'flag': '{EF}', 'interface': 'GE6/0/2', 'mac': '0000-0000-0000', 'oper_key': '0', 'priority': '32768', 'status': '0', 'sys_id': '0x8000'}]}, '2': {'local_members': [{}], 'remote_members': [{'flag': '{EF}', 'interface': 'GE6/0/3', 'mac': '0000-0000-0000', 'oper_key': '0', 'priority': '32768', 'status': '0', 'sys_id': '0x8000'}, {'flag': '{EF}', 'interface': 'GE6/0/4', 'mac': '0000-0000-0000', 'oper_key': '0', 'priority': '32768', 'status': '0', 'sys_id': '0x8000'}]}}}]] Further debugging revelead the flaw in results selection logic, due to exclude("Port") statemets group was invalidated and anonymous group_id was same as parent group_id resulting in new anonymous group matches were not able to restart the group, fixed by changing the way how anonymous group id formed. Before fix: self.ended_groups: set() re_["GROUP"].group_id: ('portchannel.{{channel_number}}.local_members*', 0) re_["GROUP"].parent_group_id: ('portchannel.{{channel_number}}.local_members*', 0) self.ended_groups: {('portchannel.{{channel_number}}.local_members*', 0)} re_["GROUP"].group_id: ('portchannel.{{channel_number}}.local_members*', 0) re_["GROUP"].parent_group_id: ('portchannel.{{channel_number}}.local_members*', 0) self.ended_groups: {('portchannel.{{channel_number}}.local_members*', 0)} re_["GROUP"].group_id: ('portchannel.{{channel_number}}.local_members*', 0) re_["GROUP"].parent_group_id: ('portchannel.{{channel_number}}.local_members*', 0) After fix: self.ended_groups: set() re_["GROUP"].group_id: ('portchannel.{{channel_number}}.local_members*._anonymous_', 0) re_["GROUP"].parent_group_id: ('portchannel.{{channel_number}}.local_members*', 0) self.ended_groups: {('portchannel.{{channel_number}}.local_members*._anonymous_', 0)} re_["GROUP"].group_id: ('portchannel.{{channel_number}}.local_members*._anonymous_', 0) re_["GROUP"].parent_group_id: ('portchannel.{{channel_number}}.local_members*', 0) self.ended_groups: set() re_["GROUP"].group_id: ('portchannel.{{channel_number}}.local_members*._anonymous_', 0) re_["GROUP"].parent_group_id: ('portchannel.{{channel_number}}.local_members*', 0) """ data = """ Loadsharing Type: Shar -- Loadsharing, NonS -- Non-Loadsharing Port Status: S -- Selected, U -- Unselected, I -- Individual, * -- Management port Flags: A -- LACP_Activity, B -- LACP_Timeout, C -- Aggregation, D -- Synchronization, E -- Collecting, F -- Distributing, G -- Defaulted, H -- Expired Aggregate Interface: Bridge-Aggregation1 Aggregation Mode: Dynamic Loadsharing Type: Shar Management VLAN : None System ID: 0x8000, d07e-28b5-a200 Local: Port Status Priority Oper-Key Flag -------------------------------------------------------------------------------- GE6/0/1 U 32768 1 {ACG} GE6/0/2 U 32768 1 {ACG} Remote: Actor Partner Priority Oper-Key SystemID Flag -------------------------------------------------------------------------------- GE6/0/1 0 32768 0 0x8000, 0000-0000-0000 {EF} GE6/0/2 0 32768 0 0x8000, 0000-0000-0000 {EF} Aggregate Interface: Bridge-Aggregation2 Aggregation Mode: Dynamic Loadsharing Type: Shar Management VLAN : None System ID: 0x8000, d07e-28b5-a200 Local: Port Status Priority Oper-Key Flag -------------------------------------------------------------------------------- GE6/0/3 U 32768 2 {ACG} GE6/0/4 U 32768 2 {ACG} Remote: Actor Partner Priority Oper-Key SystemID Flag -------------------------------------------------------------------------------- GE6/0/3 0 32768 0 0x8000, 0000-0000-0000 {EF} GE6/0/4 0 32768 0 0x8000, 0000-0000-0000 {EF} """ template = """ Aggregate Interface: Bridge-Aggregation{{ channel_number}} Local: {{_start_}} {{interface | exclude("Port") }} {{status}} {{priority}} {{oper_key }} {{flag}} {{interface }} {{status}} {{priority}} {{oper_key}} {{sys_id}}, {{ mac | MAC }} {{flag}} """ > parser = ttp(data, template) ^^^^^^^^^^^^^^^^^^^ test_answers_and_docs.py:6393: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError ________________________ test_issue_57_one_more_answer _________________________ def test_issue_57_one_more_answer(): data = """ Loadsharing Type: Shar -- Loadsharing, NonS -- Non-Loadsharing Port Status: S -- Selected, U -- Unselected, I -- Individual, * -- Management port Flags: A -- LACP_Activity, B -- LACP_Timeout, C -- Aggregation, D -- Synchronization, E -- Collecting, F -- Distributing, G -- Defaulted, H -- Expired Aggregate Interface: Bridge-Aggregation1 Aggregation Mode: Dynamic Loadsharing Type: Shar Management VLAN : None System ID: 0x8000, d07e-28b5-a200 Local: Port Status Priority Oper-Key Flag -------------------------------------------------------------------------------- GE6/0/1 U 32768 1 {ACG} GE6/0/2 U 32768 1 {ACG} Remote: Actor Partner Priority Oper-Key SystemID Flag -------------------------------------------------------------------------------- GE6/0/1 0 32768 0 0x8000, 0000-0000-0000 {EF} GE6/0/2 0 32768 0 0x8000, 0000-0000-0000 {EF} Aggregate Interface: Bridge-Aggregation2 Aggregation Mode: Dynamic Loadsharing Type: Shar Management VLAN : None System ID: 0x8000, d07e-28b5-a200 Local: Port Status Priority Oper-Key Flag -------------------------------------------------------------------------------- GE6/0/3 U 32768 2 {ACG} GE6/0/4 U 32768 2 {ACG} Remote: Actor Partner Priority Oper-Key SystemID Flag -------------------------------------------------------------------------------- GE6/0/3 0 32768 0 0x8000, 0000-0000-0000 {EF} GE6/0/4 0 32768 0 0x8000, 0000-0000-0000 {EF} """ template = """ Aggregate Interface: Bridge-Aggregation{{ channel_number}} {{interface}} {{status}} {{priority | DIGIT}} {{oper_key | DIGIT}} {{flag}} {{interface}} {{status}} {{priority | DIGIT}} {{oper_key | DIGIT}} {{sys_id}}, {{ mac | MAC }} {{flag}} """ > parser = ttp(data, template) ^^^^^^^^^^^^^^^^^^^ test_answers_and_docs.py:6503: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError ___________________ test_issue_57_one_more_empty_dict_in_res ___________________ def test_issue_57_one_more_empty_dict_in_res(): """ Without fix this results produced: [[{'portchannel': {'1': {'local_members': [{}, {'flag': '{ACG}', 'interface': 'GE6/0/1', 'oper_key': '1', 'priority': '32768', 'status': 'U'}, {'flag': '{ACG}', 'interface': 'GE6/0/2', 'oper_key': '1', 'priority': '32768', 'status': 'U'}], 'remote_members': [{}, {'flag': '{EF}', 'interface': 'GE6/0/1', 'mac': '0000-0000-0000', 'oper_key': '0', 'priority': '32768', 'status': '0', 'sys_id': '0x8000'}, {'flag': '{EF}', 'interface': 'GE6/0/2', 'mac': '0000-0000-0000', 'oper_key': '0', 'priority': '32768', 'status': '0', 'sys_id': '0x8000'}]}, '2': {'local_members': [{}, {'flag': '{ACG}', 'interface': 'GE6/0/3', 'oper_key': '2', 'priority': '32768', 'status': 'U'}, {'flag': '{ACG}', 'interface': 'GE6/0/4', 'oper_key': '2', 'priority': '32768', 'status': 'U'}], 'remote_members': [{}, {'flag': '{EF}', 'interface': 'GE6/0/3', 'mac': '0000-0000-0000', 'oper_key': '0', 'priority': '32768', 'status': '0', 'sys_id': '0x8000'}, {'flag': '{EF}', 'interface': 'GE6/0/4', 'mac': '0000-0000-0000', 'oper_key': '0', 'priority': '32768', 'status': '0', 'sys_id': '0x8000'}]}}}]] Above results contain empty dictionary list item, this is because local_members* and remote_members* use * to indicate list item as a result self.dict_by_path was returning E as a list element, and results were appended to that element, but results are empty dictionary, update saving logic to check if results are empty and skip appending them if so. """ data = """ Loadsharing Type: Shar -- Loadsharing, NonS -- Non-Loadsharing Port Status: S -- Selected, U -- Unselected, I -- Individual, * -- Management port Flags: A -- LACP_Activity, B -- LACP_Timeout, C -- Aggregation, D -- Synchronization, E -- Collecting, F -- Distributing, G -- Defaulted, H -- Expired Aggregate Interface: Bridge-Aggregation1 Aggregation Mode: Dynamic Loadsharing Type: Shar Management VLAN : None System ID: 0x8000, d07e-28b5-a200 Local: Port Status Priority Oper-Key Flag -------------------------------------------------------------------------------- GE6/0/1 U 32768 1 {ACG} GE6/0/2 U 32768 1 {ACG} Remote: Actor Partner Priority Oper-Key SystemID Flag -------------------------------------------------------------------------------- GE6/0/1 0 32768 0 0x8000, 0000-0000-0000 {EF} GE6/0/2 0 32768 0 0x8000, 0000-0000-0000 {EF} Aggregate Interface: Bridge-Aggregation2 Aggregation Mode: Dynamic Loadsharing Type: Shar Management VLAN : None System ID: 0x8000, d07e-28b5-a200 Local: Port Status Priority Oper-Key Flag -------------------------------------------------------------------------------- GE6/0/3 U 32768 2 {ACG} GE6/0/4 U 32768 2 {ACG} Remote: Actor Partner Priority Oper-Key SystemID Flag -------------------------------------------------------------------------------- GE6/0/3 0 32768 0 0x8000, 0000-0000-0000 {EF} GE6/0/4 0 32768 0 0x8000, 0000-0000-0000 {EF} """ template = """ Aggregate Interface: Bridge-Aggregation{{ channel_number}} Local: {{_start_}} {{interface }} {{status}} {{priority}} {{oper_key | DIGIT }} {{flag}} Remote: {{_start_}} {{interface }} {{status}} {{priority}} {{oper_key}} {{sys_id}}, {{ mac | MAC }} {{flag}} """ > parser = ttp(data, template) ^^^^^^^^^^^^^^^^^^^ test_answers_and_docs.py:6682: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError ________________________________ test_issue_62 _________________________________ def test_issue_62(): data = """ security: received (in 351815.564 secs): 220203204 packets 14522703007 bytes 3 pkts/sec 41010 bytes/sec transmitted (in 351815 secs): 0 packets 0 bytes 0 pkts/sec 0 bytes/sec """ template = """ {{ nameif | ORPHRASE }}: {{ ignore(r'\s+') }}received{{ ignore('.*') }} {{ ignore(r'\s+') }}{{ rpps | DIGIT }} pkts/sec{{ ignore('.*') }} {{ ignore(r'\s+') }}trasmitted{{ ignore('.*') }} {{ ignore(r'\s+') }}{{ tpps | DIGIT }} pkts/sec{{ ignore('.*') }} """ > parser = ttp(data, template) ^^^^^^^^^^^^^^^^^^^ test_answers_and_docs.py:6756: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError ______________________________ test_issue_62_fix _______________________________ def test_issue_62_fix(): data = """ security: received (in 351815.564 secs): 220203204 packets 14522703007 bytes 3 pkts/sec 41010 bytes/sec transmitted (in 351815 secs): 0 packets 0 bytes 0 pkts/sec 0 bytes/sec """ template = """ {{ nameif | ORPHRASE }}: received (in {{ ignore }} secs): {{ _start_ }} {{ rpps }} pkts/sec 41010 bytes/sec transmitted (in {{ ignore }} secs): {{ _start_ }} {{ tpps }} pkts/sec 0 bytes/sec """ > parser = ttp(data, template) ^^^^^^^^^^^^^^^^^^^ test_answers_and_docs.py:6791: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError __________________________ test_lookup_crosstemplates __________________________ def test_lookup_crosstemplates(): template = """ """ > parser = ttp() ^^^^^ test_answers_and_docs.py:6836: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError _____________________________ test_answer_hpe_bgp ______________________________ def test_answer_hpe_bgp(): data = """ ipv4-family vpn-instance FHA router-id 10.251.0.15 peer 10.251.64.113 as-number 64991 peer 10.251.64.97 as-number 64991 aggregate 10.251.64.0 255.255.248.0 detail-suppressed attribute-policy IGP_into_FHA aggregate 10.251.160.0 255.255.248.0 detail-suppressed attribute-policy IGP_into_FHA preference 75 80 90 network 10.248.128.0 255.255.255.0 route-policy IGP_into_FHA network 10.248.137.160 255.255.255.224 route-policy IGP_into_FHA peer 10.251.64.97 route-policy fhadmz_to_fha import peer 10.251.64.97 ebgp-max-hop 5 peer 10.251.64.97 timer keepalive 1 hold 5 peer 10.251.64.97 route-update-interval 1 peer 10.251.64.97 connect-interface LoopBack101 peer 10.251.64.97 fake-as 64881 peer 10.251.64.113 route-policy fha_to_fhaimz export peer 10.251.64.113 route-policy fhaimz_to_fha import peer 10.251.64.113 ebgp-max-hop 5 peer 10.251.64.113 timer keepalive 1 hold 5 peer 10.251.64.113 route-update-interval 1 peer 10.251.64.113 connect-interface LoopBack101 peer 10.251.64.113 fake-as 64881 """ template = """ {{address_family}}-family vpn-instance {{vpn_instance}} router-id {{router_id}} preference {{pref_internal}} {{pref_external}} {{pref_local}} peer {{peer_id}} as-number {{peer_as_number}} peer {{peer_id}} group {{peer_group_id }} peer {{peer_id}} label_route_capability {{label_router_capability | re("label-route-capability")}} peer {{peer_id}} {{bfd | re("bfd") | let("enabled") }} peer {{peer_id}} route-policy {{peer_import_policy}} import peer {{peer_id}} route-policy {{peer_export_policy}} export peer {{peer_id}} ebgp-max-hop {{ebgp_max_hop}} peer {{peer_id}} timer keepalive {{timet_keepalive}} hold {{timer_hold}} peer {{peer_id}} route-update-interval {{timer_route_update}} peer {{peer_id}} connect-interface {{source_interface}} peer {{peer_id}} fake-as {{local_as}} aggregate {{network}} {{mask}} {{detail_suppressed }} attribute-policy {{attribute_policy}} network {{network}} {{mask}} route-policy {{route_policy}} """ > parser = ttp(data, template) ^^^^^^^^^^^^^^^^^^^ test_answers_and_docs.py:6920: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError ________________ test_stackoverflow_62421344_python_parse_text _________________ def test_stackoverflow_62421344_python_parse_text(): data = """ JAVA_OPTS=blablalba lbalbalba 1. main1: aelo1 2020-06-15 11 4001 sddg2 2020-06-12 19 422 2. main2: fdata3 2020-06-16 11 4422 gcontent4 2020-06-12 19 422 3. main3: hxvnt5 2020-06-17 11 4002 vcfdet6 2020-06-12 19 422 """ template = """ 1. main1: {{ _start_ }} {{ ignore }} {{ date }} {{ hour | lessthan("12") }} {{ value | greaterthan("4000") }} """ > parser = ttp(data, template) ^^^^^^^^^^^^^^^^^^^ test_answers_and_docs.py:6990: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError _____________________ test_same_config_different_contexts ______________________ def test_same_config_different_contexts(): """ data below contains nemserevers across different config contexts, TTp matches all of them but voids all except from within vrfs. """ data = """ bar ip name-server 3.3.3.1 ip name-server 6.6.6.2 vrf context management foo bar ip name-server 2.2.2.2 ip name-server 4.4.4.4 ip name-server 5.5.5.5 ip route 0.0.0.0/0 2.3.4.5 foo ip name-server 3.3.3.3 ip name-server 6.6.6.6 biz ip name-server 3.3.3.4 ip name-server 6.6.6.7 vrf context main_vrf ip name-server 1.2.3.4 ip route 0.0.0.0/0 4.5.6.7 bar ip name-server 3.3.3.1 ip name-server 6.6.6.2 """ template = """ vrf context {{ vrf_name | ORPHRASE | _start_ }} ip name-server {{ name_servers | to_list | joinmatches}} foo {{ _start_ }} biz {{ _start_ }} bar {{ _start_ }} ip name-server {{ name_servers | to_list | joinmatches}} """ > parser = ttp(data, template) ^^^^^^^^^^^^^^^^^^^ test_answers_and_docs.py:7042: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError ____________________ test_to_int_with_dynamic_path_issue_67 ____________________ def test_to_int_with_dynamic_path_issue_67(): data = """ foo domain 100 bar 123 biz baz foo domain 101 bar 234 biz foo domain 102 bar 345 """ template = """ foo domain {{ domain_id | DIGIT | to_int | _start_ }} bar {{ bar | DIGIT | to_int }} biz {{ biz | default(false) | set(true) }} baz {{ baz | default(false) | set(true) }} """ > parser = ttp(data, template, log_level="error", dynamic_path_key_to_int=True) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ test_answers_and_docs.py:7074: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError ___________ test_to_int_with_dynamic_path_issue_67_multiptocess_mode ___________ def test_to_int_with_dynamic_path_issue_67_multiptocess_mode(): data1 = """ foo domain 100 bar 123 biz baz foo domain 101 bar 234 biz foo domain 102 bar 345 """ data2 = """ foo domain 100 bar 123 biz baz """ data3 = """ foo domain 101 bar 234 biz foo domain 102 bar 345 """ data4 = """ foo domain 100 bar 123 biz baz foo domain 102 bar 345 """ template = """ foo domain {{ domain_id | DIGIT | to_int | _start_ }} bar {{ bar | DIGIT | to_int }} biz {{ biz | default(false) | set(true) }} baz {{ baz | default(false) | set(true) }} """ > parser = ttp(template=template, log_level="error", dynamic_path_key_to_int=True) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ test_answers_and_docs.py:7125: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError ______________________________ test_issue_69_fix _______________________________ def test_issue_69_fix(): template1 = """ snmp-server chassis-id test snmp-server host 2.2.2.2 version 2c public snmp-server host 1.1.1.1 version 2c public snmp-server enable traps bgp snmp-server enable traps entity snmp-server chassis-id {{ chassis_id }} snmp-server host {{ server }} version {{ version }} {{ community }} snmp-server enable traps {{ traps | joinmatches(',') | to_list }} """ template2 = """ snmp-server chassis-id test snmp-server enable traps bgp snmp-server enable traps entity snmp-server host 2.2.2.2 version 2c public snmp-server host 1.1.1.1 version 2c public snmp-server chassis-id {{ chassis_id }} snmp-server host {{ server }} version {{ version }} {{ community }} snmp-server enable traps {{ traps | joinmatches(',') | to_list }} """ > parser1 = ttp(template=template1) ^^^^^^^^^^^^^^^^^^^^^^^ test_answers_and_docs.py:7180: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError ________________________________ test_issue_77 _________________________________ def test_issue_77(): """ """ data =""" lsp "lsp100" primary "name" include "1" exclude "2" exit secondary "name" include "3" exclude "4" exit exit lsp "lsp101" primary "name" include "5" exclude "6" exit secondary "name" include "7" exclude "8" exit exit """ template = """ lsp "{{ lspname | _start_ }}" primary "{{ primaryname | _start_ }}" include "{{ item | _start_ }}" exclude "{{ item | _start_ }}" exit{{ _end_ }} secondary "{{ secondaryname | _start_ }}" include "{{ item | _start_ }}" exclude "{{ item | _start_ }}" exit{{ _end_ }} exit{{ _end_ }} """ > parser = ttp(data, template) ^^^^^^^^^^^^^^^^^^^ test_answers_and_docs.py:7252: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError ________________________________ test_issue_94 _________________________________ def test_issue_94(): data = """ router isis LAB flex-algo 128 priority 100 metric-type delay advertise-definition prefix-metric ! address-family ipv4 unicast metric-style wide ! ! """ template = """ router isis LAB {{ _start_ | _exact_ }} flex-algo 128 {{ _start_ | _exact_ }} priority {{ priority | equal('999') }} metric-type {{ metric_type | equal('delay') }} advertise-definition {{ advertise_definition | set('true') }} prefix-metric {{ prefix_metric | set('true') }} !{{ _end_ }} {{ LEFTOVER | _line_ | joinmatches }} !{{ _end_ }} """ > parser = ttp(data, template) ^^^^^^^^^^^^^^^^^^^ test_answers_and_docs.py:7297: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError _______________________________ test_issue_94_1 ________________________________ def test_issue_94_1(): data = """ router isis LAB flex-algo 128 priority 100 metric-type delay advertise-definition prefix-metric ! address-family ipv4 unicast metric-style wide advertise passive-only mpls traffic-eng level-2-only ! interface Loopback0 passive ! """ template = """ router isis LAB {{ _start_ | _exact_ }} flex-algo 128 {{ _start_ | _exact_ }} priority {{ priority | equal('999') }} metric-type {{ metric_type | equal('delay') }} advertise-definition {{ advertise_definition | set('true') }} prefix-metric {{ prefix_metric | set('true') }} {{ LEFTOVER | _line_ | joinmatches }} !{{ _end_ }} {{ LEFTOVER | _line_ | joinmatches }} !{{ _end_ }} """ > parser = ttp(data, template) ^^^^^^^^^^^^^^^^^^^ test_answers_and_docs.py:7349: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError ________________________________ test_issue_89 _________________________________ def test_issue_89(): template = """ interface Bundle-Ether801.101 description TTP MACRO TEST INTERFACE mtu 9104 ipv4 address 192.168.1.1 255.255.255.0 ipv4 address 10.50.45.1 255.255.255.128 secondary load-interval 30 encapsulation dot1q 101 ! def is_trunk(data): if "dot1q" in data: data['trunk'] = True else: data['trunk'] = False return data interface {{ interface }} description {{ description |ORPHRASE }} mtu {{ mtu }} vrf {{ vrf |default(None) }} service-policy input {{ sp_ingress |default(None) }} service-policy output {{ sp_egress |default(None) }} ipv4 address {{ ipv4_addr |default(None) }} {{ ipv4_mask |default(None) }} ipv4 address {{ ipv4_addr |default(None) }} {{ ipv4_mask |default(None) }} secondary ipv6 address {{ ipv6_addr |default(None) }}/{{ ipv6_mask |default(None) }} encapsulation dot1q {{ dot1q }} ipv4 access-group {{ ingress_acl_v4 |_exact_ |default(None) }} ingress ipv4 access-group {{ egress_acl_v4 |_exact_ |default(None) }} egress bundle id {{ lag_id }} mode {{ mode }} ipv6 access-group {{ ingress_acl_v6 |_exact_ |default(None) }} ingress ipv6 access-group {{ egress_acl_v6 |_exact_ |default(None) }} egress shutdown {{ disabled |set(True) }} ! {{ _end_ }} """ > parser = ttp( template=template, log_level="ERROR", log_file="macro_test_1.log", ) test_answers_and_docs.py:7414: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError ___________________________ test_empty_group_results ___________________________ def test_empty_group_results(): template = """ vlan 1234 name some_vlan vlan 5678 vlan 910 name one_more vlan 777 vlan {{ vlan }} name {{ name }} """ > parser = ttp(template=template) ^^^^^^^^^^^^^^^^^^^^^^ test_empty_group_results.py:25: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError __________________________ test_extend_tag_from_file ___________________________ def test_extend_tag_from_file(): """ template="./assets/extend_vlan.txt" content is: vlan {{ vlan }} name {{ name }} """ template = """ """ data = """ vlan 1234 name some_vlan ! vlan 910 name one_more ! """ > parser = ttp(data=data, template=template) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ test_extend_tag.py:45: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError _____________________ test_extend_tag_from_file_anonymous ______________________ def test_extend_tag_from_file_anonymous(): """ template="./assets/extend_vlan.txt" content is: vlan {{ vlan }} name {{ name }} """ template = """ """ data = """ vlan 1234 name some_vlan ! vlan 910 name one_more ! """ > parser = ttp(data=data, template=template) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ test_extend_tag.py:74: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError _________________ test_extend_tag_from_file_with_template_tag __________________ def test_extend_tag_from_file_with_template_tag(): """ template="./assets/extend_vlan.txt" content is: """ template = """ """ data = """ vlan 1234 name some_vlan ! vlan 910 name one_more ! """ > parser = ttp(data=data, template=template) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ test_extend_tag.py:107: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError _____________________ test_extend_tag_from_file_wrong_path _____________________ def test_extend_tag_from_file_wrong_path(): """ template="./assets/extend_vlan.txt" content is: """ template = """ """ data = """ vlan 1234 name some_vlan ! vlan 910 name one_more ! """ with pytest.raises(FileNotFoundError): > parser = ttp(data=data, template=template) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ test_extend_tag.py:141: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError ______________________ test_extend_tag_from_ttp_templates ______________________ @skip_if_no_ttp_templates def test_extend_tag_from_ttp_templates(): """ Test loading ttp_templates template """ template = """ vlan {{ vlan }} name {{ name }} """ data = """ interface Gi1.100 description Some description 1 encapsulation dot1q 100 ip address 10.0.0.1 255.255.255.0 shutdown ! interface Gi2 description Some description 2 ip address 10.1.0.1 255.255.255.0 ! vlan 1234 name some_vlan ! vlan 910 name one_more ! """ > parser = ttp(data=data, template=template) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ test_extend_tag.py:178: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError __________________ test_extend_tag_from_file_vars_and_lookup ___________________ def test_extend_tag_from_file_vars_and_lookup(): """ ./assets/extend_vars_and_lookup_tag.txt content: '65100': as_description: Private ASN as_name: Subs prefix_num: '734' '65101': as_description: Cust-1 ASN as_name: Cust1 prefix_num: '156' var_1: value_1 var_2: value_2 var_3: [1,2,3,4,"a"] """ template = """ router bgp 65100 router bgp {{ bgp_as | lookup("bgp_asn", add_field="as_details") }} {{ var_1_value | set(var_1) }} {{ var_2_value | set(var_2) }} {{ var_2_value | set(var_3) }} """ > parser = ttp(template=template) ^^^^^^^^^^^^^^^^^^^^^^ test_extend_tag.py:242: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError _________________________ test_extend_tag_within_group _________________________ def test_extend_tag_within_group(): template = """ router bgp 65100 router-id 1.1.1.1 neighbor 2.2.2.2 remote-as 65000 router bgp {{ bgp_as }} neighbor {{ peer }} remote-as {{ asn }} """ > parser = ttp(template=template, log_level="warning") ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ test_extend_tag.py:286: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError _____________ test_extend_tag_within_group_with_child_groups_above _____________ def test_extend_tag_within_group_with_child_groups_above(): template = """ router bgp 65100 router-id 1.1.1.1 neighbor 2.2.2.2 remote-as 65000 router bgp {{ bgp_as }} neighbor {{ peer }} remote-as {{ asn }} """ > parser = ttp(template=template, log_level="warning") ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ test_extend_tag.py:325: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError ___________ test_extend_tag_within_group_with_non_hierarch_template ____________ def test_extend_tag_within_group_with_non_hierarch_template(): template = """ router bgp 65100 router-id 1.1.1.1 neighbor 2.2.2.2 remote-as 65000 router bgp {{ bgp_as }} neighbor {{ peer }} remote-as {{ asn }} """ > parser = ttp(template=template, log_level="warning") ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ test_extend_tag.py:366: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError ______________ test_extend_tag_within_group_with_anonymous_group _______________ def test_extend_tag_within_group_with_anonymous_group(): template = """ router bgp 65100 router-id 1.1.1.1 neighbor 2.2.2.2 remote-as 65000 router bgp {{ bgp_as }} neighbor {{ peer }} remote-as {{ asn }} """ > parser = ttp(template=template, log_level="warning") ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ test_extend_tag.py:407: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError ______________ test_extend_tag_within_group_with_multiple_groups _______________ def test_extend_tag_within_group_with_multiple_groups(): """ ./assets/test_extend_tag_within_group_with_multiple_groups.txt content: router-id {{ rid }} address-family ipv4 vrf {{ vrf }} """ template = """ router bgp 65100 router-id 1.1.1.1 neighbor 2.2.2.2 remote-as 65000 neighbor 2.2.2.3 remote-as 65001 ! address-family ipv4 vrf TEST_1 address-family ipv4 vrf TEST_2 router bgp {{ bgp_as }} neighbor {{ peer }} remote-as {{ asn }} """ > parser = ttp(template=template, log_level="warning") ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ test_extend_tag.py:460: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError _________________ test_extend_tag_from_file_group_name_filter __________________ def test_extend_tag_from_file_group_name_filter(): """ template="./assets/extend_vlan.txt" content is: vlan {{ vlan }} name {{ name }} """ template = """ """ data = """ vlan 1234 name some_vlan ! vlan 910 name one_more ! """ > parser = ttp(data=data, template=template) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ test_extend_tag.py:503: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError _________________ test_extend_tag_from_file_group_index_filter _________________ def test_extend_tag_from_file_group_index_filter(): """ template="./assets/extend_vlan.txt" content is: vlan {{ vlan }} name {{ name }} """ template = """ """ data = """ vlan 1234 name some_vlan ! vlan 910 name one_more ! """ > parser = ttp(data=data, template=template) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ test_extend_tag.py:534: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError ____________________ test_extend_tag_from_file_vars_filter _____________________ def test_extend_tag_from_file_vars_filter(): template = """ a = 1 b = 2 vlan {{ vlan }} name {{ name }} {{ r_test | set(r) }} """ data = """ vlan 1234 name some_vlan ! vlan 910 name one_more ! """ > parser = ttp(data=data, template=template) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ test_extend_tag.py:569: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError ______________ test_extend_tag_from_file_with_vars_inputs_filter _______________ def test_extend_tag_from_file_with_vars_inputs_filter(): template = """ vlan {{ vlan }} name {{ name }} """ > parser = ttp(template=template) ^^^^^^^^^^^^^^^^^^^^^^ test_extend_tag.py:600: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError ___________________ test_extend_tag_from_file_lookups_filter ___________________ def test_extend_tag_from_file_lookups_filter(): template = """ router bgp 65100 router bgp {{ bgp_as | lookup("bgp_asn", add_field="as_details") }} {{ var_1_value | set(var_1) }} {{ var_2_value | set(var_2) }} {{ var_3_value | set(var_3) }} """ > parser = ttp(template=template) ^^^^^^^^^^^^^^^^^^^^^^ test_extend_tag.py:633: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError ___________________ test_extend_tag_from_file_output_filter ____________________ def test_extend_tag_from_file_output_filter(): data = """ vlan 1234 name some_vlan ! vlan 910 name one_more ! """ template = """ vlan {{ vlan }} name {{ name }} """ > parser = ttp(data=data, template=template) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ test_extend_tag.py:676: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError ________________ test_extend_tag_from_file_nested_group_filter _________________ def test_extend_tag_from_file_nested_group_filter(): data = """ interface Gi1 description bla bla bla ip address 1.1.1.1 255.255.255.0 ! interface Gi2 name bla bla shutdown ip address 1.1.2.1 255.255.255.0 ! """ template = """ interface {{ interface }} description {{ description }} shutdown {{ disabled | set(True) }} """ > parser = ttp(data=data, template=template) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ test_extend_tag.py:706: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError _________________ test_extend_tag_groups_recursive_extend_load _________________ @skip_if_no_ttp_templates def test_extend_tag_groups_recursive_extend_load(): template = """ vlan {{ vlan }} name {{ name }} """ data = """ logging host 1.1.1.1 logging host 1.1.1.2 ! interface Gi1.100 description Some description 1 encapsulation dot1q 100 ip address 10.0.0.1 255.255.255.0 shutdown ! interface Gi2 description Some description 2 ip address 10.1.0.1 255.255.255.0 ! vlan 1234 name some_vlan ! vlan 910 name one_more ! """ > parser = ttp(data=data, template=template, log_level="ERROR") ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ test_extend_tag.py:763: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError _______ test_extend_tag_groups_recursive_extend_load_several_top_groups ________ @skip_if_no_ttp_templates def test_extend_tag_groups_recursive_extend_load_several_top_groups(): template = """ vlan {{ vlan }} name {{ name }} """ data = """ logging host 1.1.1.1 logging host 1.1.1.2 ! interface Gi1.100 description Some description 1 encapsulation dot1q 100 ip address 10.0.0.1 255.255.255.0 shutdown ! interface Gi2 description Some description 2 ip address 10.1.0.1 255.255.255.0 ! vlan 1234 name some_vlan ! vlan 910 name one_more ! """ > parser = ttp(data=data, template=template, log_level="ERROR") ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ test_extend_tag.py:829: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError _____________________ test_extend_tag_from_file_with_macro _____________________ def test_extend_tag_from_file_with_macro(): template = """ def indent(data): # macro to indent each line of original template with 4 space characters return "\\n".join(f" {line}" for line in data.splitlines()) """ data = """ vlan 1234 name some_vlan ! vlan 910 name one_more ! """ > parser = ttp(data=data, template=template) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ test_extend_tag.py:880: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError _______________ test_ttp_templates_dir_env_variable_with_extend ________________ def test_ttp_templates_dir_env_variable_with_extend(): os.environ["TTP_TEMPLATES_DIR"] = os.path.join( os.getcwd(), "assets", "TTP_TEMPLATES_DIR_TEST" ) data = """ vlan 1234 name some_vlan ! vlan 910 name one_more ! """ template = """ """ > parser = ttp(data=data, template=template) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ test_extend_tag.py:906: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError _______________________ test_group_chain_attribute_list ________________________ def test_group_chain_attribute_list(): template_1 = """ interface Port-Chanel11 vlan 10 interface Loopback0 vlan 20 description test loopback0 interface Loopback1 vlan 30 description test loopback1 chain1 = [ "del(vlan)", "contains_val(interface, 'Loop')" ] interface {{ interface }} vlan {{ vlan | to_int }} description {{ description | ORPHRASE }} """ > parser = ttp(template=template_1) ^^^^^^^^^^^^^^^^^^^^^^^^ test_group_chain_attribute.py:34: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError __________________ test_group_chain_attribute_list_multi_func __________________ def test_group_chain_attribute_list_multi_func(): template_1 = """ interface Port-Chanel11 vlan 10 interface Loopback0 vlan 20 description test loopback0 interface Loopback1 vlan 30 description test loopback1 chain1 = [ "del(vlan) | set('set_value', 'set_key')", "contains_val(interface, 'Loop')", "macro('test_macro')", "macro('test_macro1, test_macro2')", "macro(test_macro3, test_macro4)", ] def test_macro(data): data["test_macro"] = "DONE" return data def test_macro1(data): data["test_macro1"] = "DONE" return data def test_macro2(data): data["test_macro2"] = "DONE" return data def test_macro3(data): data["test_macro3"] = "DONE" return data def test_macro4(data): data["test_macro4"] = "DONE" return data interface {{ interface }} vlan {{ vlan | to_int }} description {{ description | ORPHRASE }} """ > parser = ttp(template=template_1) ^^^^^^^^^^^^^^^^^^^^^^^^ test_group_chain_attribute.py:99: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError ____________________ test_group_chain_attribute_string_var _____________________ def test_group_chain_attribute_string_var(): template_1 = """ interface Port-Chanel11 vlan 10 interface Loopback0 vlan 20 description test loopback0 interface Loopback1 vlan 30 description test loopback1 chain1 = "del(vlan) | set('set_value', 'set_key') | contains_val(interface, 'Loop') | macro('test_macro')" def test_macro(data): data["test_macro"] = "DONE" return data interface {{ interface }} vlan {{ vlan | to_int }} description {{ description | ORPHRASE }} """ > parser = ttp(template=template_1) ^^^^^^^^^^^^^^^^^^^^^^^^ test_group_chain_attribute.py:160: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError ___________________ test_group_chain_attribute_string_inline ___________________ def test_group_chain_attribute_string_inline(): template_1 = """ interface Port-Chanel11 vlan 10 interface Loopback0 vlan 20 description test loopback0 interface Loopback1 vlan 30 description test loopback1 def test_macro(data): data["test_macro"] = "DONE" return data def test_macro1(data): data["test_macro1"] = "DONE" return data interface {{ interface }} vlan {{ vlan | to_int }} description {{ description | ORPHRASE }} """ > parser = ttp(template=template_1) ^^^^^^^^^^^^^^^^^^^^^^^^ test_group_chain_attribute.py:213: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError _________________________ test_group_validate_function _________________________ def test_group_validate_function(): template_123 = """ device-1# interface Lo0 ! interface Lo1 description this interface has description device-2# interface Lo10 ! interface Lo11 description another interface with description intf_description_validate = { 'description': {'required': True, 'type': 'string'} } hostname_1="gethostname" interface {{ interface }} description {{ description | ORPHRASE }} {{ hostname | set(hostname_1) }} """ > parser = ttp(template=template_123) ^^^^^^^^^^^^^^^^^^^^^^^^^^ test_group_functions.py:42: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError ____ test_group_default_referencing_variable_parent_group_no_re_two_inputs _____ def test_group_default_referencing_variable_parent_group_no_re_two_inputs(): template_123 = """ Hi World Hello World var_name = {"audiences": []} Hello {{ audience }} """ > parser = ttp(template=template_123, log_level="WARNING") ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ test_group_functions.py:109: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError _____ test_group_default_referencing_variable_parent_group_no_re_one_input _____ def test_group_default_referencing_variable_parent_group_no_re_one_input(): template_123 = """ Hi World var_name = {"audiences": []} Hello {{ audience }} """ > parser = ttp(template=template_123, log_level="WARNING") ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ test_group_functions.py:137: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError ____________ test_top_group_default_referencing_variable_dictionary ____________ def test_top_group_default_referencing_variable_dictionary(): template_123 = """ device-1# interface Lo0 ! interface Lo1 description this interface has description device-2# interface Lo10 ! interface Lo11 description another interface with description var_name = { "switchport": False, "is_l3": True, "description": "Undefined" } interface {{ interface }} description {{ description | ORPHRASE }} """ > parser = ttp(template=template_123, log_level="DEBUG") ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ test_group_functions.py:175: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError ------------------------------ Captured log call ------------------------------- INFO ttp.ttp:ttp.py:84 ttp.lazy_import_functions: starting functions lazy import INFO ttp.ttp:ttp.py:122 ttp.lazy_import_functions: loading files for ast parsing ______________________________ test_group_default ______________________________ def test_group_default(): template = """ device-hostame uptime is 27 weeks, 3 days, 10 hours, 46 minutes, 10 seconds device-hostame uptime is {{ uptime | PHRASE }} software version {{ version | default("uncknown") }} Default domain is {{ fqdn }} """ > parser = ttp(template=template, log_level="WARNING") ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ test_group_functions.py:237: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError ________________ test_child_group_default_referencing_variable _________________ def test_child_group_default_referencing_variable(): template_123 = """ interface Lo0 ip address 1.1.1.1 255.255.255.255 ! interface Lo1 description this interface has description interface Lo10 ip address 1.1.1.2 255.255.255.255 ! interface Lo11 description another interface with description ip address 1.1.1.3 255.255.255.255 var_name = { "L3": True, "has_ip": True } interface {{ interface }} description {{ description | ORPHRASE }} ip address {{ IP }} {{ MASK }} """ > parser = ttp(template=template_123, log_level="WARNING") ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ test_group_functions.py:291: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError _______________ test_group_set_function_source_from_global_vars ________________ def test_group_set_function_source_from_global_vars(): template_123 = """ hostname router_1 interface Lo0 ip address 1.1.1.1 255.255.255.255 ! interface Lo0 ip address 1.1.1.2 255.255.255.255 hostname {{ hostname }} interface {{ interface }} ip address {{ IP }} {{ MASK }} """ > parser = ttp(template=template_123, log_level="WARNING") ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ test_group_functions.py:367: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError ________________________ test_group_macro_returns_false ________________________ def test_group_macro_returns_false(): template_123 = """ interface Lo0 ! interface Lo1 description this interface has description def check(data): if not "description" in data: return False interface {{ interface }} description {{ description | ORPHRASE }} """ > parser = ttp(template=template_123) ^^^^^^^^^^^^^^^^^^^^^^^^^^ test_group_functions.py:417: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError ________________________ test_group_macro_returns_true _________________________ def test_group_macro_returns_true(): template_123 = """ interface Lo0 ! interface Lo1 description this interface has description def check(data): if "description" in data: return True interface {{ interface }} description {{ description | ORPHRASE }} """ > parser = ttp(template=template_123) ^^^^^^^^^^^^^^^^^^^^^^^^^^ test_group_functions.py:449: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError ________________________ test_group_macro_returns_none _________________________ def test_group_macro_returns_none(): template_123 = """ interface Lo0 ! interface Lo1 description this interface has description def check(data): return None interface {{ interface }} description {{ description | ORPHRASE }} """ > parser = ttp(template=template_123) ^^^^^^^^^^^^^^^^^^^^^^^^^^ test_group_functions.py:485: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError __________________________ test_group_macro_chaining ___________________________ def test_group_macro_chaining(): template_123 = """ interface Lo0 ! interface Lo1 description this interface has description def check_1(data): if not "description" in data: data["has_description"] = False else: data["has_description"] = True def check_2(data): if "Lo" in data["interface"]: data["is_loopback"] = True interface {{ interface }} description {{ description | ORPHRASE }} """ > parser = ttp(template=template_123) ^^^^^^^^^^^^^^^^^^^^^^^^^^ test_group_functions.py:528: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError _________________ test_group_macro_chaining_returns_dictionary _________________ def test_group_macro_chaining_returns_dictionary(): template_123 = """ interface Lo0 ! interface Lo1 description this interface has description def check_1(data): if not "description" in data: return {"completely_new_data": True} def check_2(data): if "Lo" in data.get("interface", ""): data["is_loopback"] = True else: data.update({"completely_new_data_2": True}) return data interface {{ interface }} description {{ description | ORPHRASE }} """ > parser = ttp(template=template_123) ^^^^^^^^^^^^^^^^^^^^^^^^^^ test_group_functions.py:577: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError _________________________________ test_itemize _________________________________ def test_itemize(): template = """ interface Vlan778 description some description 1 ip address 2002:fd37::91/124 ! interface Vlan779 description some description 2 ! interface Vlan780 switchport port-security mac 4 ip address 192.168.1.1/124 ! interface Vlan790 description some description 790 switchport port-security mac 4 ip address 192.168.190.1/124 ! interface {{ interface | upper | append("a") }} ip address {{ ip }} interface {{ interface }} description {{ description | ORPHRASE }} ip address {{ ip }} !{{ _end_ }} interface {{ interface }} description {{ description | ORPHRASE }} ip address {{ ip }} !{{ _end_ }} """ > parser = ttp(template=template) ^^^^^^^^^^^^^^^^^^^^^^ test_group_functions.py:638: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError __________________________ test_itemize_dynamic_path ___________________________ def test_itemize_dynamic_path(): template = """ interface Loopback0 ip address 2002:fd37::91/124 ! interface Vlan779 ! interface Loopback1 switchport port-security mac 4 ip address 192.168.1.1/124 ! interface Vlan790 switchport port-security mac 4 ip address 192.168.190.1/124 ! interface {{ interface | contains("Vlan") | let("intf_type", "vlans") }} ip address {{ ip }} interface {{ interface | contains("Loop") | let("intf_type", "loopbacks") }} ip address {{ ip }} """ > parser = ttp(template=template) ^^^^^^^^^^^^^^^^^^^^^^ test_group_functions.py:697: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError _____________________ test_itemize_dynamic_path_attribute ______________________ def test_itemize_dynamic_path_attribute(): template = """ interface Loopback0 ip address 2002:fd37::91/124 ! interface Vlan779 ! interface Loopback1 switchport port-security mac 4 ip address 192.168.1.1/124 ! interface Vlan790 switchport port-security mac 4 ip address 192.168.190.1/124 ! interface {{ interface | contains("Vlan") | let("intf_type", "vlans") }} ip address {{ ip }} interface {{ interface | contains("Loop") | let("intf_type", "loopbacks") }} ip address {{ ip }} """ > parser = ttp(template=template) ^^^^^^^^^^^^^^^^^^^^^^ test_group_functions.py:744: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError ___________________________ test_items2dict_function ___________________________ def test_items2dict_function(): template = """ vlan 123 name SERVERS ! vlan 456 name WORKSTATIONS vlan {{ vlan }} name {{ name }} """ > parser = ttp(template=template) ^^^^^^^^^^^^^^^^^^^^^^ test_group_functions.py:784: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError _________________________________ test_expand __________________________________ def test_expand(): template = """ interface GigabitEthernet1/1 description to core-1 mtu 9100 switchport mode trunk ! interface {{ name }} description {{ config.description | ORPHRASE }} mtu {{ config.mtu | to_int }} switchport mode {{ mode }} ! {{_end_}} """ > parser = ttp(template=template) ^^^^^^^^^^^^^^^^^^^^^^ test_group_functions.py:813: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError _____________________________ test_expand_issue_65 _____________________________ def test_expand_issue_65(): template = """ interface GigabitEthernet1/1 description to core-1 switchport mode trunk mtu 9100 vrf ABC ! interface GigabitEthernet1/2 description to AGG-1 switchport mode access mtu 9200 vrf XYZ ! interface {{ name }} description {{ config.description | ORPHRASE }} mtu {{ config.mtu | to_int }} vrf {{ vrf }} switchport mode {{ mode }} ! {{_end_}} """ > parser = ttp(template=template) ^^^^^^^^^^^^^^^^^^^^^^ test_group_functions.py:852: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError ______________________ test_group_to_int_for_non_integer _______________________ def test_group_to_int_for_non_integer(): template = """ interface GigabitEthernet1/1 mtu ABC ! interface GigabitEthernet1/2 mtu 8000 ! interface GigabitEthernet1/2 mtu 9200.0 ! interface {{ name }} mtu {{ mtu }} """ > parser = ttp(template=template) ^^^^^^^^^^^^^^^^^^^^^^ test_group_functions.py:888: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError ___________________ test_group_to_int_missing_key_issue_109 ____________________ def test_group_to_int_missing_key_issue_109(): template = """ interface GigabitEthernet1/1 mtu ABC ! interface GigabitEthernet1/2 mtu 8000 ! interface GigabitEthernet1/2 mtu 9200.0 ! interface {{ name }} mtu {{ mtu }} """ > parser = ttp(template=template) ^^^^^^^^^^^^^^^^^^^^^^ test_group_functions.py:917: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError ________________ test_group_to_int_with_intlist_true_issue_109 _________________ def test_group_to_int_with_intlist_true_issue_109(): template = """ interface GigabitEthernet1/1 switchport trunk allowed vlan 1,2,3,4 ! interface GigabitEthernet1/2 switchport trunk allowed vlan 123 ! interface GigabitEthernet1/3 switchport trunk allowed vlan foo,bar ! interface GigabitEthernet1/4 ! interface {{ name }} switchport trunk allowed vlan {{ trunk_vlan | split(',') }} """ > parser = ttp(template=template) ^^^^^^^^^^^^^^^^^^^^^^ test_group_functions.py:948: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError ________________ test_group_to_int_with_intlist_false_issue_109 ________________ def test_group_to_int_with_intlist_false_issue_109(): template = """ interface GigabitEthernet1/1 switchport trunk allowed vlan 1,2,3,4 ! interface GigabitEthernet1/2 switchport trunk allowed vlan 123 ! interface GigabitEthernet1/3 switchport trunk allowed vlan foo,bar ! interface GigabitEthernet1/4 ! interface {{ name }} switchport trunk allowed vlan {{ trunk_vlan | split(',') }} """ > parser = ttp(template=template) ^^^^^^^^^^^^^^^^^^^^^^ test_group_functions.py:981: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError _____________ test_group_lookup_using_lookup_table_action_replace ______________ def test_group_lookup_using_lookup_table_action_replace(): template_1 = """ Protocol Address Age (min) Hardware Addr Type Interface Internet 10.12.13.2 98 0950.5785.5cd1 ARPA FastEthernet2.13 Internet 10.12.14.3 131 0150.7685.14d5 ARPA GigabitEthernet2.13 [ip_addresses] 10.12.13.2 = app_1 10.12.14.3 = app_2 Internet {{ ip }} {{ age | DIGIT }} {{ mac }} ARPA {{ interface }} """ > parser = ttp(template=template_1) ^^^^^^^^^^^^^^^^^^^^^^^^ test_group_lookup.py:27: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError ____________ test_group_lookup_using_lookup_table_action_add_field _____________ def test_group_lookup_using_lookup_table_action_add_field(): template_1 = """ Protocol Address Age (min) Hardware Addr Type Interface Internet 10.12.13.2 98 0950.5785.5cd1 ARPA FastEthernet2.13 Internet 10.12.14.3 131 0150.7685.14d5 ARPA GigabitEthernet2.13 { "ip_addresses": { "10.12.13.2": "app_1", "10.12.14.3": "app_2"}} Internet {{ ip }} {{ age | DIGIT }} {{ mac }} ARPA {{ interface }} """ > parser = ttp(template=template_1) ^^^^^^^^^^^^^^^^^^^^^^^^ test_group_lookup.py:71: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError ______________ test_group_lookup_using_lookup_table_action_update ______________ def test_group_lookup_using_lookup_table_action_update(): template_1 = """ Protocol Address Age (min) Hardware Addr Type Interface Internet 10.12.13.2 98 0950.5785.5cd1 ARPA FastEthernet2.13 Internet 10.12.14.3 131 0150.7685.14d5 ARPA GigabitEthernet2.13 ip_addresses: 10.12.13.2: app_name: app_1 app_owner: team2 10.12.14.3: app_name: app_2 app_owner: team_2 Internet {{ ip }} {{ age | DIGIT }} {{ mac }} ARPA {{ interface }} """ > parser = ttp(template=template_1) ^^^^^^^^^^^^^^^^^^^^^^^^ test_group_lookup.py:121: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError __________ test_group_lookup_using_group_in_same_input_action_update ___________ def test_group_lookup_using_group_in_same_input_action_update(): template_1 = """ interface FastEthernet2.13 description Customer CPE interface ip address 10.12.13.1 255.255.255.0 vrf forwarding CPE-VRF ! interface GigabitEthernet2.13 description Customer CPE interface ip address 10.12.14.1 255.255.255.0 vrf forwarding CUST1 ! Protocol Address Age (min) Hardware Addr Type Interface Internet 10.12.13.2 98 0950.5785.5cd1 ARPA FastEthernet2.13 Internet 10.12.14.3 131 0150.7685.14d5 ARPA GigabitEthernet2.13 interface {{ interface }} description {{ description | ORPHRASE }} ip address {{ subnet | PHRASE | to_ip | network | to_str }} vrf forwarding {{ vrf }} Internet {{ ip }} {{ age | DIGIT }} {{ mac }} ARPA {{ interface }} """ > parser = ttp(template=template_1) ^^^^^^^^^^^^^^^^^^^^^^^^ test_group_lookup.py:180: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError ________ test_group_lookup_using_group_from_another_input_action_update ________ def test_group_lookup_using_group_from_another_input_action_update(): template_1 = """ interface FastEthernet2.13 description Customer CPE interface ip address 10.12.13.1 255.255.255.0 vrf forwarding CPE-VRF ! interface GigabitEthernet2.13 description Customer CPE interface ip address 10.12.14.1 255.255.255.0 vrf forwarding CUST1 ! Protocol Address Age (min) Hardware Addr Type Interface Internet 10.12.13.2 98 0950.5785.5cd1 ARPA FastEthernet2.13 Internet 10.12.14.3 131 0150.7685.14d5 ARPA GigabitEthernet2.13 interface {{ interface }} description {{ description | ORPHRASE }} ip address {{ subnet | PHRASE | to_ip | network | to_str }} vrf forwarding {{ vrf }} Internet {{ ip }} {{ age | DIGIT }} {{ mac }} ARPA {{ interface }} """ > parser = ttp(template=template_1) ^^^^^^^^^^^^^^^^^^^^^^^^ test_group_lookup.py:256: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError ________ test_group_lookup_in_template_results_per_input_action_update _________ def test_group_lookup_in_template_results_per_input_action_update(): template_1 = """ """ > parser = ttp(template=template_1) ^^^^^^^^^^^^^^^^^^^^^^^^ test_group_lookup.py:338: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError _____ test_group_lookup_in_template_results_per_template_action_add_field ______ def test_group_lookup_in_template_results_per_template_action_add_field(): template_1 = """ """ > parser = ttp(template=template_1) ^^^^^^^^^^^^^^^^^^^^^^^^ test_group_lookup.py:421: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError _________________ test_group_same_null_path_for_several_groups _________________ def test_group_same_null_path_for_several_groups(): data = """ vrf xyz address-family ipv4 unicast import route-target 65000:3507 65000:3511 65000:5453 65000:5535 ! export route-target 65000:5453 65000:5535 ! ! ! """ template = """ vrf {{name}} import route-target {{ _start_ }} {{ import | to_list | joinmatches }} ! export route-target {{ _start_ }} {{ export | to_list | joinmatches }} """ > parser = ttp(data=data, template=template, log_level="ERROR") ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ test_group_name_attribute.py:44: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError _____________________ test_headers_indicator_left_aligned ______________________ def test_headers_indicator_left_aligned(): template = """ Port Name Status Vlan Duplex Speed Type Gi0/1 PIT-VDU213 connected 18 a-full a-100 10/100/1000BaseTX Gi0/2 PIT-VDU211 connected 18 a-full a-100 10/100/1000BaseTX Gi0/3 PIT-VDU212 notconnect 18 auto auto 10/100/1000BaseTX Gi0/4 connected 18 a-full a-100 10/100/1000BaseTX Gi0/5 notconnect 18 auto auto 10/100/1000BaseTX Gi0/6 notconnect 18 auto auto 10/100/1000BaseTX Gi0/7 notconnect 18 auto auto 10/100/1000BaseTX Gi0/8 notconnect 18 auto auto 10/100/1000BaseTX Gi0/9 notconnect 18 auto auto 10/100/1000BaseTX Gi0/10 notconnect 18 auto auto 10/100/1000BaseTX Gi0/11 notconnect 18 auto auto 10/100/1000BaseTX Gi0/12 notconnect 18 auto auto 10/100/1000BaseTX Gi0/13 disabled 1 auto auto 10/100/1000BaseTX Gi0/14 disabled 1 auto auto 10/100/1000BaseTX Gi0/15 connected trunk full 1000 1000BaseLX SFP Gi0/16 pitrs2201 te1/1/4 connected trunk full 1000 1000BaseLX SFP Port Name Status Vlan Duplex Speed Type {{ _headers_ }} """ > parser = ttp(template=template) ^^^^^^^^^^^^^^^^^^^^^^ test_headers_indicator.py:38: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError _________________ test_headers_indicator_space_indented_header _________________ def test_headers_indicator_space_indented_header(): template = """ Network Next Hop Metric LocPrf Weight Path *>e11.11.1.111/32 12.123.12.1 0 0 65000 ? *>e222.222.222.2/32 12.123.12.1 0 0 65000 ? *>e333.33.333.333/32 12.123.12.1 0 0 65000 ? Network Next_Hop Metric LocPrf Weight Path {{ _headers_ }} """ > parser = ttp(template=template, log_level="ERROR") ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ test_headers_indicator.py:210: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError ___________________ test_headers_indicator_multiline_header ____________________ def test_headers_indicator_multiline_header(): template = """ -------------------------------------------------------------------------------- Port Name Status Vlan Duplex Speed Type -------------------------------------------------------------------------------- Gi0/1 PIT-VDU213 connected 18 a-full a-100 10/100/1000BaseTX Gi0/2 PIT-VDU211 connected 18 a-full a-100 10/100/1000BaseTX Gi0/3 PIT-VDU212 notconnect 18 auto auto 10/100/1000BaseTX Gi0/4 connected 18 a-full a-100 10/100/1000BaseTX Gi0/5 notconnect 18 auto auto 10/100/1000BaseTX Gi0/6 notconnect 18 auto auto 10/100/1000BaseTX Gi0/7 notconnect 18 auto auto 10/100/1000BaseTX Gi0/8 notconnect 18 auto auto 10/100/1000BaseTX Gi0/9 notconnect 18 auto auto 10/100/1000BaseTX Gi0/10 notconnect 18 auto auto 10/100/1000BaseTX Gi0/11 notconnect 18 auto auto 10/100/1000BaseTX Gi0/12 notconnect 18 auto auto 10/100/1000BaseTX Gi0/13 disabled 1 auto auto 10/100/1000BaseTX Gi0/14 disabled 1 auto auto 10/100/1000BaseTX Gi0/15 connected trunk full 1000 1000BaseLX SFP Gi0/16 pitrs2201 te1/1/4 connected trunk full 1000 1000BaseLX SFP Port Name Status Vlan Duplex Speed Type {{ _headers_ }} def clean_up(data): if "----" in data["Port"]: return False return True """ > parser = ttp(template=template, log_level="ERROR") ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ test_headers_indicator.py:284: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError ____________________ test_headers_indicator_columns_merged _____________________ def test_headers_indicator_columns_merged(): template = """ Port Name Status Vlan Duplex Speed Type Gi0/1 PIT-VDU213 connected 18 a-full a-100 10/100/1000BaseTX Gi0/3 PIT-VDU212 notconnect18 auto auto 10/100/1000BaseTX Gi0/5 notconnect18 auto auto 10/100/1000BaseTX Gi0/15 connected trunk full 1000 1000BaseLX SFP Gi0/16 pitrs2201 te1/1/4connected trunk full 1000 1000BaseLX SFP Port Name Status Vlan Duplex Speed Type {{ _headers_ }} """ > parser = ttp(template=template) ^^^^^^^^^^^^^^^^^^^^^^ test_headers_indicator.py:460: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError __________________ test_headers_indicator_tab_indented_header __________________ def test_headers_indicator_tab_indented_header(): template = """ Network Next Hop Metric LocPrf Weight Path *>ef11.11.1.111/32 12.123.12.1 0 0 65000 ? *>ef222.222.222.2/32 12.123.12.1 0 0 65000 ? *>ef333.333.333.333/32 12.123.12.1 0 0 65000 ? Network Next_Hop Metric LocPrf Weight Path {{ _headers_ }} """ > parser = ttp(template=template, log_level="ERROR") ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ test_headers_indicator.py:534: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError __________________________ test_headers_docs_example ___________________________ def test_headers_docs_example(): template = """ Port Name Status Vlan Duplex Speed Type Gi0/1 PIT-VDU213 connected 18 a-full a-100 10/100/1000BaseTX Gi0/4 connected 18 a-full a-100 10/100/1000BaseTX Gi0/16 pitrs2201 te1/1/4 connected trunk full 1000 1000BaseLX SFP Port Name Status Vlan Duplex Speed Type {{ _headers_ }} """ > parser = ttp(template=template, log_level="ERROR") ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ test_headers_indicator.py:586: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError __________________________ test_headers_shorter_lines __________________________ def test_headers_shorter_lines(): data = """ Filesystem 1K-blocks Used Available Use% Mounted on tmpfs 1457328 0 1457328 0% /sys/fs/cgroup /dev/mapper/centos-root 14034944 5783384 8251560 42% / /dev/sda1 1038336 220604 817732 22% /boot """ template = """ Filesystem K1_blocks Used Available Use_ Mounted_on {{ _headers_ }} """ > parser = ttp(template=template, log_level="ERROR") ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ test_headers_indicator.py:638: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError ________________________ test_headers_last_column_empty ________________________ def test_headers_last_column_empty(): data = """ Filesystem 1K-blocks Used Available Use% Mounted on tmpfs 1457328 0 1457328 0% /sys/fs/cgroup /dev/mapper/centos-root 14034944 5783384 8251560 2% /dev/sda1 1038336 220604 817732 22% /boot """ template = """ Filesystem K1_blocks Used Available Use_ Mounted_on {{ _headers_ }} """ > parser = ttp(template=template, log_level="ERROR") ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ test_headers_indicator.py:688: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError ______________________________ test_with_garbage _______________________________ def test_with_garbage(): template = """ interface Lo0 ip address 124.171.238.50/29 ! interface Lo1 ip address 1.1.1.1/30 ! Port Name Status Vlan Duplex Speed Type Gi0/1 PIT-VDU213 connected 18 a-full a-100 10/100/1000BaseTX Gi0/4 connected 18 a-full a-100 10/100/1000BaseTX Gi0/16 pitrs2201 te1/1/4 connected trunk full 1000 1000BaseLX SFP Port Name Status Vlan Duplex Speed Type {{ _headers_ }} """ > parser = ttp(template=template, log_level="ERROR") ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ test_headers_indicator.py:747: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError ___________________________ test_headers_with_column ___________________________ def test_headers_with_column(): template = """ Port Name Status Vlan Duplex Speed Type Gi0/1 Gi0/2 PIT-VDU212 Gi0/3 PIT-VDU212 notconnect Gi0/4 PIT-VDU212 notconnect 18 Gi0/5 PIT-VDU212 notconnect 18 auto Gi0/6 PIT-VDU212 notconnect 18 auto auto Gi0/7 PIT-VDU212 notconnect 18 auto auto 10/100/1000BaseTX Port Name Status Vlan Duplex Speed Type {{ _headers_ | columns(10) }} Port Name Status Vlan Duplex Speed Type {{ _headers_ | columns(7) }} Port Name Status Vlan Duplex Speed Type {{ _headers_ | columns(6) }} Port Name Status Vlan Duplex Speed Type {{ _headers_ | columns(5) }} Port Name Status Vlan Duplex Speed Type {{ _headers_ | columns(4) }} Port Name Status Vlan Duplex Speed Type {{ _headers_ | columns(3) }} Port Name Status Vlan Duplex Speed Type {{ _headers_ | columns(2) }} Port Name Status Vlan Duplex Speed Type {{ _headers_ | columns(1) }} Port Name Status Vlan Duplex Speed Type {{ _headers_ | columns(0) }} Port Name Status Vlan Duplex Speed Type {{ _headers_ | columns(-1) }} Port Name Status Vlan Duplex Speed Type {{ _headers_ }} """ > parser = ttp(template=template, log_level="DEBUG") ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ test_headers_indicator.py:846: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError ------------------------------ Captured log call ------------------------------- INFO ttp.ttp:ttp.py:84 ttp.lazy_import_functions: starting functions lazy import INFO ttp.ttp:ttp.py:122 ttp.lazy_import_functions: loading files for ast parsing ________________________ test_headers_on_tabular_output ________________________ def test_headers_on_tabular_output(): data = """ Partition Name L3V Index Max. Aflex Admin Count ---------------------------------------------------- sivr_icm No 1 32 0 ent_mgmt No 2 32 0 Cloud No 3 * 32 0 lync No 4 32 0 sap No 5 32 0 config_mgmts No 6 32 0 Uprising No 7 32 0 ERC_MGMT No 8 32 0 sc_sw_ctrl No 9 32 0 cust_hub No 10 32 0 A10-CIS No 11 32 0 SAP_Dev_Admin No 12 * 32 0 sentry_ext No 13 32 0 web_ecom_srvs No 14 32 0 dir_sec_svc No 15 32 0 eng_ops No 16 32 0 mw_mgmt No 17 32 0 oracle_db_adm No 18 32 0 idm_mgmt No 19 32 0 info_mgmt No 20 * 32 0 sa_ops_natapps No 21 32 0 eng_supt No 37 * 32 0 retail_apps No 128 32 0 """ template = """ Partition_Name L3V Index Max__Aflex Admin_Count {{ _headers_ }} """ > parser = ttp(data=data, template=template, log_level="ERROR") ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ test_headers_indicator.py:934: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError _________________________ test_line_when_its_start_re __________________________ def test_line_when_its_start_re(): data_to_parse_a = """ R1#sh vrrp GigabitEthernet1 - Group 100 DC-LAN Subnet State is Master Virtual IP address is 192.168.10.1 Virtual MAC address is 0000.5e00.0164 Advertisement interval is 1.000 sec Preemption enabled Priority is 120 VRRS Group name DC_LAN Track object 1 state Up decrement 30 Authentication text "hash" Master Router is 192.168.1.233 (local), priority is 120 Master Advertisement interval is 1.000 sec Master Down interval is 3.531 sec Some other line """ data_to_parse_b = """ R2#sh vrrp GigabitEthernet1 - Group 100 State is Init Virtual IP address is 192.168.10.1 Virtual MAC address is 0000.5e00.0164 Advertisement interval is 1.000 sec Preemption enabled Priority is 115 Authentication text "hash" Master Router is 192.168.1.233, priority is 120 Master Advertisement interval is 1.000 sec Master Down interval is 3.550 sec """ ttp_template = """ """ > parser = ttp(template=ttp_template) ^^^^^^^^^^^^^^^^^^^^^^^^^^ test_line_indicator.py:77: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError ___________________________ test_lookup_include_csv ____________________________ def test_lookup_include_csv(): template = """ router bgp 65101 router bgp {{ bgp_as | lookup(ASNs, add_field="as_info") }} """ > parser = ttp(template=template) ^^^^^^^^^^^^^^^^^^^^^^ test_lookups.py:25: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError ___________________________ test_lookup_include_yaml ___________________________ def test_lookup_include_yaml(): template = """ router bgp 65100 router bgp {{ bgp_as | lookup("yaml_look", add_field="as_details") }} """ > parser = ttp(template=template) ^^^^^^^^^^^^^^^^^^^^^^ test_lookups.py:69: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError ___________________________ test_contains_re_inline ____________________________ def test_contains_re_inline(): template = """ interface Port-Channel11 description Storage Management interface Loopback0 description RID interface Vlan777 description Management interface {{ interface | contains_re("Port-Channel") }} description {{ description }} {{ is_lag | set(True) }} {{ is_loopback| set(False) }} """ > parser = ttp(template=template) ^^^^^^^^^^^^^^^^^^^^^^ test_match_condition_fun.py:27: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError __________________________ test_contains_re_from_vars __________________________ def test_contains_re_from_vars(): template = """ interface Port-Channel11 description Storage interface Loopback0 description RID interface Port-Channel12 description Management_2 interface Vlan777 description Management var_1 = "Port-.+" interface {{ interface | contains_re(var_1) }} description {{ description }} {{ is_lag | set(True) }} {{ is_loopback| set(False) }} """ > parser = ttp(template=template) ^^^^^^^^^^^^^^^^^^^^^^ test_match_condition_fun.py:63: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError __________________________ test_startswith_re_inline ___________________________ def test_startswith_re_inline(): template = """ interface Port-Channel11 description Storage Management interface Loopback0 description RID interface Vlan777 description Management interface {{ interface | startswith_re(r"Por\\S") }} description {{ description }} {{ is_lag | set(True) }} {{ is_loopback| set(False) }} """ > parser = ttp(template=template) ^^^^^^^^^^^^^^^^^^^^^^ test_match_condition_fun.py:108: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError _________________________ test_startswith_re_from_vars _________________________ def test_startswith_re_from_vars(): template = """ interface Port-Channel11 description Storage interface Loopback0 description RID interface Port-Channel12 description Management_2 interface Vlan777 description Management var_1 = "Port-.+" interface {{ interface | startswith_re(var_1) }} description {{ description }} {{ is_lag | set(True) }} {{ is_loopback| set(False) }} """ > parser = ttp(template=template) ^^^^^^^^^^^^^^^^^^^^^^ test_match_condition_fun.py:144: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError ___________________________ test_endswith_re_inline ____________________________ def test_endswith_re_inline(): template = """ interface Port-Channel11 description Storage Management interface Loopback0 description RID interface Vlan777 description Management interface {{ interface | endswith_re(r"Channel\\d+") }} description {{ description }} {{ is_lag | set(True) }} {{ is_loopback| set(False) }} """ > parser = ttp(template=template) ^^^^^^^^^^^^^^^^^^^^^^ test_match_condition_fun.py:189: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError __________________________ test_endswith_re_from_vars __________________________ def test_endswith_re_from_vars(): template = """ interface Port-Channel11 description Storage Management interface Loopback0 description RID interface Vlan777 description Management var_1 = r"Channel\\d+" interface {{ interface | endswith_re(var_1) }} description {{ description }} {{ is_lag | set(True) }} {{ is_loopback| set(False) }} """ > parser = ttp(template=template) ^^^^^^^^^^^^^^^^^^^^^^ test_match_condition_fun.py:220: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError _________________________ test_notstartswith_re_inline _________________________ def test_notstartswith_re_inline(): template = """ interface Port-Channel11 description Storage Management interface Loopback0 description RID interface Vlan777 description Management interface {{ interface | notstartswith_re(r"Loop\\S+") }} description {{ description }} {{ is_lag | set(True) }} {{ is_loopback| set(False) }} """ > parser = ttp(template=template) ^^^^^^^^^^^^^^^^^^^^^^ test_match_condition_fun.py:247: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError _______________________ test_notstartswith_re_from_vars ________________________ def test_notstartswith_re_from_vars(): template = """ interface Port-Channel11 description Storage Management interface Loopback0 description RID interface Vlan777 description Management var_1 = r"Loop\\S+" interface {{ interface | notstartswith_re(var_1) }} description {{ description }} {{ is_lag | set(True) }} {{ is_loopback| set(False) }} """ > parser = ttp(template=template) ^^^^^^^^^^^^^^^^^^^^^^ test_match_condition_fun.py:291: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError __________________________ test_notendswith_re_inline __________________________ def test_notendswith_re_inline(): template = """ interface Port-Channel11 description Storage Management interface Loopback0 description RID interface Vlan777 description Management interface {{ interface | notendswith_re(r"back\\d+") }} description {{ description }} {{ is_lag | set(True) }} {{ is_loopback| set(False) }} """ > parser = ttp(template=template) ^^^^^^^^^^^^^^^^^^^^^^ test_match_condition_fun.py:328: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError ________________________ test_notendswith_re_from_vars _________________________ def test_notendswith_re_from_vars(): template = """ interface Port-Channel11 description Storage Management interface Loopback0 description RID interface Vlan777 description Management var_1 = r"back\\d+|lan\\d+" interface {{ interface | notendswith_re(var_1) }} description {{ description }} {{ is_lag | set(True) }} {{ is_loopback| set(False) }} """ > parser = ttp(template=template) ^^^^^^^^^^^^^^^^^^^^^^ test_match_condition_fun.py:369: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError ____________________________ test_exclude_re_inline ____________________________ def test_exclude_re_inline(): template = """ interface Port-Channel11 description Storage Management interface Loopback0 description RID interface Vlan777 description Management interface {{ interface | exclude_re(r"back.+") }} description {{ description }} """ > parser = ttp(template=template) ^^^^^^^^^^^^^^^^^^^^^^ test_match_condition_fun.py:397: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError __________________________ test_exclude_re_from_vars ___________________________ def test_exclude_re_from_vars(): template = """ interface Port-Channel11 description Storage interface Loopback0 description RID interface Vlan777 description Management var_1 = r"back\\d+|lan\\d+" interface {{ interface | exclude_re(var_1) }} description {{ description }} """ > parser = ttp(template=template) ^^^^^^^^^^^^^^^^^^^^^^ test_match_condition_fun.py:434: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError _____________________________ test_exclude_inline ______________________________ def test_exclude_inline(): template = """ interface Port-Channel11 description Storage Management interface Loopback0 description RID interface Vlan777 description Management interface {{ interface | exclude(Loop) }} description {{ description }} """ > parser = ttp(template=template) ^^^^^^^^^^^^^^^^^^^^^^ test_match_condition_fun.py:460: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError ____________________________ test_exclude_from_vars ____________________________ def test_exclude_from_vars(): template = """ interface Port-Channel11 description Storage Management interface Loopback0 description RID interface Vlan777 description Management var_1 = "Loop" interface {{ interface | exclude(var_1) }} description {{ description }} """ > parser = ttp(template=template) ^^^^^^^^^^^^^^^^^^^^^^ test_match_condition_fun.py:494: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError _____________________________ test_contains_inline _____________________________ def test_contains_inline(): template = """ interface Port-Channel11 description Storage interface Loopback0 description RID interface Port-Channel12 description Management interface Vlan777 description Management interface {{ interface | contains(Port) }} description {{ description }} """ > parser = ttp(template=template) ^^^^^^^^^^^^^^^^^^^^^^ test_match_condition_fun.py:526: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError ___________________________ test_contains_from_vars ____________________________ def test_contains_from_vars(): template = """ interface Port-Channel11 description Storage interface Loopback0 description RID interface Port-Channel12 description Management interface Vlan777 description Management var_1 = "Port" interface {{ interface | contains(var_1) }} description {{ description }} """ > parser = ttp(template=template) ^^^^^^^^^^^^^^^^^^^^^^ test_match_condition_fun.py:565: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError _____________________________ test_contains_multi ______________________________ def test_contains_multi(): template = """ interface Port-Channel11 description Storage interface Loopback0 description RID interface Port-Channel12 description Management interface Vlan777 description Management var_1 = "Port" interface {{ interface | contains(var_1, Vlan) }} description {{ description }} """ > parser = ttp(template=template) ^^^^^^^^^^^^^^^^^^^^^^ test_match_condition_fun.py:601: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError ______________________________ test_equal_inline _______________________________ def test_equal_inline(): template = """ interface Port-Channel11 description Storage interface Loopback0 description RID interface Port-Channel12 description Management interface Vlan777 description Management interface {{ interface | equal("Port-Channel12") }} description {{ description }} """ > parser = ttp(template=template) ^^^^^^^^^^^^^^^^^^^^^^ test_match_condition_fun.py:637: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError _____________________________ test_equal_from_vars _____________________________ def test_equal_from_vars(): template = """ interface Port-Channel11 description Storage interface Loopback0 description RID interface Port-Channel12 description Management interface Vlan777 description Management var_1 = "Port-Channel12" interface {{ interface | equal(var_1) }} description {{ description }} """ > parser = ttp(template=template) ^^^^^^^^^^^^^^^^^^^^^^ test_match_condition_fun.py:669: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError _____________________________ test_notequal_inline _____________________________ def test_notequal_inline(): template = """ interface Port-Channel11 description Storage interface Loopback0 description RID interface Port-Channel12 description Management interface Vlan777 description Management interface {{ interface | notequal("Port-Channel12") }} description {{ description }} """ > parser = ttp(template=template) ^^^^^^^^^^^^^^^^^^^^^^ test_match_condition_fun.py:694: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError ___________________________ test_notequal_from_vars ____________________________ def test_notequal_from_vars(): template = """ interface Port-Channel11 description Storage interface Loopback0 description RID interface Port-Channel12 description Management interface Vlan777 description Management var_1 = "Port-Channel12" interface {{ interface | notequal(var_1) }} description {{ description }} """ > parser = ttp(template=template) ^^^^^^^^^^^^^^^^^^^^^^ test_match_condition_fun.py:734: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError _____________________________ test_sformat_inline ______________________________ def test_sformat_inline(): template = """ interface Port-Channel11 description Storage interface Loopback0 description RID interface Port-Channel12 description Management interface Vlan777 description Management interface {{ interface | sformat("BSQ {}") }} description {{ description }} """ > parser = ttp(template=template) ^^^^^^^^^^^^^^^^^^^^^^ test_match_functions.py:32: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError ____________________________ test_sformat_from_vars ____________________________ def test_sformat_from_vars(): template = """ interface Port-Channel11 description Storage interface Loopback0 description RID interface Port-Channel12 description Management interface Vlan777 description Management var_1 = "BSQ {}" interface {{ interface | sformat(var_1) }} description {{ description }} """ > parser = ttp(template=template) ^^^^^^^^^^^^^^^^^^^^^^ test_match_functions.py:73: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError ________________________ test_to_list_with_joinmatches _________________________ def test_to_list_with_joinmatches(): template = """ interface GigabitEthernet3/3 switchport trunk allowed vlan add 138,166,173 switchport trunk allowed vlan add 400,401,410 interface {{ interface }} switchport trunk allowed vlan add {{ trunk_vlans | to_list | joinmatches }} """ > parser = ttp(template=template) ^^^^^^^^^^^^^^^^^^^^^^ test_match_functions.py:102: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError __________________________ test_multiple_joinmatches ___________________________ def test_multiple_joinmatches(): data = """ SWITCH# show vlan port 2/11 detail Status and Counters - VLAN Information - for ports 2/11 Port name: VLAN ID Name | Status Voice Jumbo Mode ------- -------------------- + ---------- ----- ----- -------- 60 ABC | Port-based No No Tagged 70 DEF | Port-based No No Tagged 101 GHIJ | Port-based No No Untagged 105 KLMNO | Port-based No No Tagged 116 PQRS | Port-based No No Tagged 117 TVU | Port-based No No Tagged SWITCH# show vlan port 2/12 detail Status and Counters - VLAN Information - for ports 2/12 Port name: VLAN ID Name | Status Voice Jumbo Mode ------- -------------------- + ---------- ----- ----- -------- 61 ABC | Port-based No No Tagged 71 DEF | Port-based No No Tagged 103 GHI | Port-based No No Untagged """ template = """ hostname="gethostname" Status and Counters - VLAN Information - for ports {{ Port_Number }} {{ Tagged_VLAN | joinmatches(", ") }} {{ name | joinmatches(", ") }} | {{ ignore }} {{ ignore }} {{ ignore }} Tagged {{ Untagged_VLAN }} {{ name | joinmatches(", ") }} | {{ ignore }} {{ ignore }} {{ ignore }} Untagged {{ Hostname | set(hostname) }} """ > parser = ttp(data, template) ^^^^^^^^^^^^^^^^^^^ test_match_functions.py:173: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError _________________________ test_joinmatches_with_ignore _________________________ def test_joinmatches_with_ignore(): data = """ SWITCH# show vlan port 2/11 detail Status and Counters - VLAN Information - for ports 2/11 Port name: VLAN ID Name | Status Voice Jumbo Mode ------- -------------------- + ---------- ----- ----- -------- 60 ABC | Port-based No No Tagged 70 DEF | Port-based No No Tagged 101 GHIJ | Port-based No No Untagged 105 KLMNO | Port-based No No Tagged 116 PQRS | Port-based No No Tagged 117 TVU | Port-based No No Tagged SWITCH# show vlan port 2/12 detail Status and Counters - VLAN Information - for ports 2/12 Port name: VLAN ID Name | Status Voice Jumbo Mode ------- -------------------- + ---------- ----- ----- -------- 61 ABC | Port-based No No Tagged 71 DEF | Port-based No No Tagged 103 GHI | Port-based No No Untagged """ template = """ hostname="gethostname" Status and Counters - VLAN Information - for ports {{ Port_Number }} {{ Tagged_VLAN | joinmatches(" ") }} {{ ignore }} | {{ ignore }} {{ ignore }} {{ ignore }} Tagged {{ Untagged_VLAN }} {{ ignore }} | {{ ignore }} {{ ignore }} {{ ignore }} Untagged {{ Hostname | set(hostname) }} """ > parser = ttp(data, template) ^^^^^^^^^^^^^^^^^^^ test_match_functions.py:256: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError ___________________ test_match_variable_default_set_to_list ____________________ def test_match_variable_default_set_to_list(): template = """ interface Port-Channel11 ip address 1.1.1.1/24 interface Loopback0 interface {{ interface }} ip address {{ ip | default([]) }} """ > parser = ttp(template=template) ^^^^^^^^^^^^^^^^^^^^^^ test_match_functions.py:295: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError __________________ test_match_variable_default_set_to_string ___________________ def test_match_variable_default_set_to_string(): template = """ interface Port-Channel11 ip address 1.1.1.1/24 interface Loopback0 interface {{ interface }} ip address {{ ip | default("Undefined") }} """ > parser = ttp(template=template) ^^^^^^^^^^^^^^^^^^^^^^ test_match_functions.py:325: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError _________________ test_match_variable_default_for_start_regex __________________ def test_match_variable_default_for_start_regex(): template = """ interface Port-Channel11 description Staff ports ntp server {{ server | default('Unconfigured') }} ntp source {{ source | default("undefined") }} """ > parser = ttp(template=template) ^^^^^^^^^^^^^^^^^^^^^^ test_match_functions.py:354: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError ________________ test_match_variable_default_set_to_dictionary _________________ def test_match_variable_default_set_to_dictionary(): template = """ interface Port-Channel11 ip address 1.1.1.1/24 interface Loopback0 interface {{ interface }} ip address {{ ip | default({"defined": False}) }} """ > parser = ttp(template=template) ^^^^^^^^^^^^^^^^^^^^^^ test_match_functions.py:378: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError _____ test_match_variable_set_and_let_for_same_variable_with_special_chars _____ def test_match_variable_set_and_let_for_same_variable_with_special_chars(): template = """ interface Port-Channel11 ip address 1.1.1.1/24 interface Loopback0 ip address 1.1.2.1/24 shutdown interface {{ interface }} ip address {{ ip | default({"defined": False}) }} shutdown {{ enabled | set(False) | let("admin-status", "down") }} {{ link-up-down-trap-enable | set(enabled) }} {{ admin-status | set(up) }} """ > parser = ttp(template=template) ^^^^^^^^^^^^^^^^^^^^^^ test_match_functions.py:413: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError _______________________________ test_let_and_set _______________________________ def test_let_and_set(): data = """ interface Port-Channel11 ip address 1.1.1.1/24 description bla bla bla shutdown interface Port-Channel22 ip address 1.1.2.1/24 description bla bla2 bla2 """ template = """ interface {{ name }} description {{ description | re(".+") }} shutdown {{ enabled | set(False) | let("admin-status", "down") }} {{ link-up-down-trap-enable | set(enabled) }} {{ admin-status | set(up) }} """ > parser = ttp(data=data, template=template) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ test_match_functions.py:458: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError __________________________ test_line_with_joinmatches __________________________ def test_line_with_joinmatches(): """ Issue - when having to use sanitized variable names, joinmatches was failing to find variable in group re variables dictionary, as that dictionary was keyd byt sanitized variable name, but by the time joinmatches seeing results, results already have original variable name. """ data = """ Chassis id: 12346.1234.1234 Port id: Eth1/1 Local Port id: Eth6/1 Port Description: Uplink to vrf1 System Name: switch-name-1 System Description: Cisco Nexus Operating System (NX-OS) Software 21.324(3)N2(3.12b) TAC support: http://www.cisco.com/tac Copyright (c) 2002-2099, Cisco Systems, Inc. All rights reserved. Time remaining: 333 seconds System Capabilities: B, R Enabled Capabilities: B, R Management Address: 1.1.1.1 Vlan ID: 111 """ template = """ System Description: {{ system-description | re(".+") | joinmatches(" ") }} {{ system-description | _line_ | joinmatches(" ") }} Time remaining: {{ ignore }} seconds {{ _end_ }} """ > parser = ttp(data, template, log_level="error") ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ test_match_functions.py:513: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError __________________________________ test_raise __________________________________ def test_raise(): data = """ interface Port-Channel11 description bla """ template = """ interface {{ name }} description {{ description | raise("Error msg") }} """ > parser = ttp(data=data, template=template) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ test_match_functions.py:540: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError __________________________________ test_copy ___________________________________ def test_copy(): data = """ interface Port-Channel11 ip address 1.1.1.123 255.255.255.255 interface Port-Channel22 ip address 1.1.1.124 255.255.255.255 """ template = """ interface {{ name }} ip address {{ ip_last_octet | copy("ip_address") | split(".") | item(-1) }} {{ mask }} """ > parser = ttp(data=data, template=template) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ test_match_functions.py:559: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError _________________________ test_match_vars_with_hyphen __________________________ def test_match_vars_with_hyphen(): template = """ interface Port-Channel11 description Storage interface Loopback0 description RID interface Port-Channel12 description Management interface Vlan777 description Management interface {{ interface-name }} description {{ description-bla }} """ > parser = ttp(template=template) ^^^^^^^^^^^^^^^^^^^^^^ test_misc.py:33: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError ___________________________ test_match_vars_with_dot ___________________________ def test_match_vars_with_dot(): template = """ interface Port-Channel11 description Storage interface Loopback0 description RID interface Port-Channel12 description Management interface Vlan777 description Management interface {{ interface.name }} description {{ description.bla }} """ > parser = ttp(template=template) ^^^^^^^^^^^^^^^^^^^^^^ test_misc.py:70: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError ______________________ test_match_vars_starts_with_digit _______________________ def test_match_vars_starts_with_digit(): template = """ interface Port-Channel11 description Storage interface Loopback0 description RID interface Port-Channel12 description Management interface Vlan777 description Management interface {{ 77interface.name }} description {{ 77description.bla }} """ > parser = ttp(template=template) ^^^^^^^^^^^^^^^^^^^^^^ test_misc.py:104: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError ___________________ test_match_vars_multiple_non_alpha_chars ___________________ def test_match_vars_multiple_non_alpha_chars(): template = """ interface Port-Channel11 description Storage interface Loopback0 description RID interface Port-Channel12 description Management interface Vlan777 description Management interface {{ 77interface.#$%name }} description {{ 77description.*(-bla }} """ > parser = ttp(template=template) ^^^^^^^^^^^^^^^^^^^^^^ test_misc.py:141: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError _______________________ test_match_vars_set_with_hyphen ________________________ def test_match_vars_set_with_hyphen(): template = """ interface Port-Channel11 description Storage interface Loopback0 description RID interface Port-Channel12 description Management no switchport interface Vlan777 description Management interface Port-Channel27 no switchport interface {{ interface-name }} description {{ description-bla | default("Undefined") }} no switchport {{ no-switchport | set(True) }} {{ is-shutdown | set(False) }} """ > parser = ttp(template=template, log_level="ERROR") ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ test_misc.py:189: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError ____________________________ test_per_template_mode ____________________________ def test_per_template_mode(): data_1 = """ interface Port-Chanel11 description Storage Management interface Loopback0 description RID interface Vlan777 description Management """ data_2 = """ interface Port-Chane10 description Storage Management interface Loopback77 description RID interface Vlan321 description Management """ template = """ """ > parser = ttp(template=template, log_level="error") ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ test_misc.py:256: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError ______________________ test_newline_with_carriage_return _______________________ def test_newline_with_carriage_return(): data = b"\ninterface Port-Chanel11\r\n\r\n\r\n description Storage_Management\r\ninterface Loopback0\n description RID\ninterface Vlan777\n description Management\r\n".decode( "utf-8" ) template = """ interface {{ interface }} description {{ description }} """ > parser = ttp(data, template, log_level="ERROR") ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ test_misc.py:289: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError _____ test_groups_with_defaults_only_and_with_children_with_defaults_only ______ def test_groups_with_defaults_only_and_with_children_with_defaults_only(): template = """ device-hostame uptime is 27 weeks, 3 days, 10 hours, 46 minutes, 10 seconds device-hostame uptime is {{ uptime | PHRASE }} some line with {{ var1 | default("val1") }} Default domain is {{ fqdn }} ntp server {{ server | default('Unconfigured') }} ntp source {{ source | default("undefined") }} npt peer {{ val2 | default("None") }} another string {{ val5 }} my string {{ val4 }} npt peers {{ val3 }} ntp server {{ server }} ntp source {{ source | default("undefined") }} snmp community {{ community }} snmp acl {{ acl }} snmp community {{ community }} snmp acl {{ acl }} snmp source {{ ip }} snmp community {{ comm_val }} """ > parser = ttp(template=template, log_level="ERROR") ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ test_misc.py:365: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError ____________________________ test_hierarch_template ____________________________ def test_hierarch_template(): template = """ hostname='gethostname' router bgp {{ bgp_as | record("loca_as") }} router-id {{ rid }} vrf {{ VRF }} {{ hostname | set("hostname") }} {{ local_as | set("loca_as") }} address-family {{ AFI }} unicast network {{ network | joinmatches() }} redistribute direct route-map {{ redistr_direct_rpl }} neighbor {{ PEER }} remote-as {{ remote_as }} description {{ description }} address-family {{ AFI }} unicast shutdown {{ shutdown | set("True") }} allowas-in {{ allow_as_in | set("True") }} route-map {{ rpl_in }} in route-map {{ rpl_out }} out """ data = """ sw1# show run | sec bgp router bgp 65000 router-id 10.1.2.2 vrf cust1 address-family ipv4 unicast network 1.1.1.10/26 redistribute direct route-map VRF-DIRECT->BGP-V4 neighbor 1.1.1.1 remote-as 65001 description FIREWALLs no dynamic-capability address-family ipv4 unicast allowas-in route-map 65001-BGP-IMPORT-V4 in route-map 65001-BGP-EXPORT-V4 out neighbor 2.2.2.2 remote-as 65002 description SLB Front address-family ipv4 unicast allowas-in route-map SLB-BGP-IMPORT-V4 in route-map SLB-BGP-EXPORT-V4 out neighbor 3.3.3.3 remote-as 1234 description Internet BDR address-family ipv4 unicast route-map INTERNET-IMPORT-V4 in route-map INTERNET-EXPORT-V4 out vrf cust2 address-family ipv4 unicast redistribute direct route-map VRF-DIRECT->BGP-V4 neighbor 4.4.4.4 remote-as 4567 description SLB Back address-family ipv4 unicast allowas-in route-map SLBB-BGP-IMPORT-V4 in route-map SLBB-BGP-EXPORT-V4 out vrf cust3 router-id 10.227.146.9 address-family ipv4 unicast redistribute direct route-map C3-DIRECT->BGP-V4 neighbor 5.5.5.5 remote-as 65100 description cist2 core no dynamic-capability address-family ipv4 unicast route-map C3-BGP-IMPORT-V4 in route-map C3-BGP-EXPORT-V4 out neighbor 6.6.6.6 remote-as 65200 description C3: Firewalls address-family ipv4 unicast allowas-in 1 route-map C3-FW-BGP-IMPORT-V4 in route-map C3-FW-BGP-EXPORT-V4 out """ > parser = ttp(data=data, template=template, log_level="ERROR") ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ test_misc.py:502: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError ________________________ test_comments_with_indentation ________________________ def test_comments_with_indentation(): """ Need to manually run this test to see if log message generated: WARNING:ttp.ttp:group.get_regexes: variable not found in line: ' ## some comment line' it should not, if all working properly """ template = """ ## some comment line some string {{ var_1 }} """ > parser = ttp(template=template, log_level="warning") ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ test_misc.py:647: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError ___________________ test_TTP_CACHE_FOLDER_env_variable_usage ___________________ def test_TTP_CACHE_FOLDER_env_variable_usage(): """ Check that TTP_CACHE_FOLDER properly handled when it is set """ template = "some string {{ var_1 }}" os.environ["TTPCACHEFOLDER"] = "./assets/" > parser = ttp(template=template) ^^^^^^^^^^^^^^^^^^^^^^ test_misc.py:659: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError ______________ test_child_group_do_not_start_if_no_parent_started ______________ def test_child_group_do_not_start_if_no_parent_started(): """ This test tests that this wrong output is not produced: [[{'ospf_processes': {'1': {'external_lsa': {'age': '1604'}, 'local_rid': '10.0.1.1', 'router_lsa': [{'age': '406', 'area': 'area', 'originator_rid': '10.0.1.1', 'ptp_peers': [{'link_data': '0.0.0.12'}, {'link_data': '0.0.0.10'}, {'link_data': '0.0.0.52'}, {'link_data': '0.0.0.53'}]}]}}}]] Reason wrong output produced is because TTP parses "LS age: {{ age }}" for "external_lsa" even though "Type-5 AS External Link States {{ _start_ }}" does not math anything in the output. Next, once "LS age: 406" like lines matched by two "LS age: {{ age }}"start regexes from "name="router_lsa*" and "name="external_lsa"" groups, selection of match result happens in favour of "name="external_lsa"" group and it breaks the logic of saving results for "name="ptp_peers*"" group, leading to all ptp_ppers saved under same path, and "LS age: 1604" stored under "name="external_lsa"" wrong path. The fix is to make sure that group "name="external_lsa"" pattern "LS age: {{ age }}" will not be parsed if no "Type-5 AS External Link States {{ _start_ }}" pattern matched in the data text. """ template = """ OSPF Router with ID ({{ local_rid }}) (Process ID {{ pid }}) Router Link States (Area {{ area }}) LS age: {{ age }} Advertising Router: {{ originator_rid }} Link connected to: another Router (point-to-point) {{ _start_ }} (Link Data) Router Interface address: {{ link_data }} Type-5 AS External Link States {{ _start_ }} LS age: {{ age }} {{ _end_ }} """ data = """ RP/0/RP0/CPU0:router-1#show ospf database router OSPF Router with ID (10.0.1.1) (Process ID 1) Router Link States (Area 0.0.0.0) LS age: 406 Options: (No TOS-capability, DC) LS Type: Router Links Link State ID: 10.0.1.1 Advertising Router: 10.0.1.1 LS Seq Number: 8000010c Checksum: 0x24dd Length: 132 Number of Links: 9 Link connected to: another Router (point-to-point) (Link ID) Neighboring Router ID: 10.0.1.4 (Link Data) Router Interface address: 0.0.0.12 Number of TOS metrics: 0 TOS 0 Metrics: 1100 Link connected to: another Router (point-to-point) (Link ID) Neighboring Router ID: 10.0.1.2 (Link Data) Router Interface address: 0.0.0.10 Number of TOS metrics: 0 TOS 0 Metrics: 1100 Routing Bit Set on this LSA LS age: 1604 Options: (No TOS-capability, DC) LS Type: Router Links Link State ID: 10.0.1.2 Advertising Router: 10.0.1.2 LS Seq Number: 8000010b Checksum: 0xdc96 Length: 132 Number of Links: 9 Link connected to: another Router (point-to-point) (Link ID) Neighboring Router ID: 10.0.1.3 (Link Data) Router Interface address: 0.0.0.52 Number of TOS metrics: 0 TOS 0 Metrics: 1100 Link connected to: another Router (point-to-point) (Link ID) Neighboring Router ID: 10.0.1.4 (Link Data) Router Interface address: 0.0.0.53 Number of TOS metrics: 0 TOS 0 Metrics: 1100 """ > parser = ttp(data=data, template=template, log_level="warning") ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ test_misc.py:776: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError _______ test_group_end_indicator_when_last_start_is_bigger_than_last_end _______ def test_group_end_indicator_when_last_start_is_bigger_than_last_end(): """ Testcase when we have last end span is smaller than last start span, meaning we have start matches beyond last end match. Without fix TTP returns this data: [[{'ospf_processes': {'1': {'local_rid': '10.0.0.4', 'router_lsa': [{'area': '100', 'asbr': False, 'originator_rid': '10.0.0.4', 'ptp_peers': [{'link_data': '10.1.45.2', 'link_id': '10.0.5.101', 'metric': '10'}]}, {'area': '100', 'asbr': True, 'originator_rid': '10.0.5.101', 'ptp_peers': [{}]}]}}}]] ptp_peers did not match any group match regexes, this is due to data does have {{ _end_ }} matched before last start """ data = """ IOL4#show ip ospf database router OSPF Router with ID (10.0.0.4) (Process ID 1) Router Link States (Area 100) LS Type: Router Links Link State ID: 10.0.0.4 Advertising Router: 10.0.0.4 Link connected to: another Router (point-to-point) (Link ID) Neighboring Router ID: 10.0.5.101 (Link Data) Router Interface address: 10.1.45.2 Number of MTID metrics: 0 TOS 0 Metrics: 10 LS Type: Router Links Link State ID: 10.0.5.101 Advertising Router: 10.0.5.101 Link connected to: another Router (point-to-point) (Link ID) Neighboring Router ID: 10.0.0.4 (Link Data) Router Interface address: 10.1.45.3 Number of MTID metrics: 0 TOS 0 Metrics: 10""" template = """ OSPF Router with ID ({{ local_rid }}) (Process ID {{ pid }}) Router Link States (Area {{ area }}) LS Type: Router Links {{ _start_ }} Advertising Router: {{ originator_rid }} AS Boundary Router {{ asbr | set(True) | default(False) }} Link connected to: another Router (point-to-point) {{ _start_ }} (Link ID) Neighboring Router ID: {{ link_id }} (Link Data) Router Interface address: {{ link_data }} TOS 0 Metrics: {{ metric }} {{ _end_ }} """ > parser = ttp(data=data, template=template, log_level="warning") ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ test_misc.py:887: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError ____________________ test_tabs_and_spaces_mixed_within_line ____________________ def test_tabs_and_spaces_mixed_within_line(): data = """ Form Factor : QSFP28 Name : FS """ template_as_is = """ Form Factor : {{ form_factor }} Name : {{ vendor }} """ template_not_as_is = """ Form Factor : {{ form_factor }} Name : {{ vendor }} """ > parser1 = ttp(data=data, template=template_as_is, log_level="warning") ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ test_misc.py:946: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError ___________________ test_inner_group_strange_parsing_results ___________________ def test_inner_group_strange_parsing_results(): """ Turned out need to specify ! {{ _end_ }} for the interface group """ template = """ """ data = """ hostname ROUTER1234 interface GigabitEthernet0/0/0/23 description GigabitEthernet0/0/0/23 description vrf IPRAN-MGMT ipv4 address 10.1.1.253 255.255.255.252 load-interval 30 ! interface HundredGigE0/0/1/0 description Hu0/0/1/0 interface description bundle id 2 mode active ptp profile any ! load-interval 30 frequency synchronization selection input priority 20 wait-to-restore 0 ! ! interface HundredGigE0/0/2/0 description Hu0/0/2/0 interface description bundle id 1 mode active ptp profile slave ! load-interval 30 frequency synchronization selection input priority 10 wait-to-restore 0 ! ! interface preconfigure GigabitEthernet0/0/0/0/23 ipv4 address 10.1.1.253 255.255.255.252 ! """ > parser = ttp(data=data, template=template, log_level="warning") ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ test_misc.py:1037: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError ___________________________ test_in_threads_parsing ____________________________ def test_in_threads_parsing(): """ Function to test parsing in multiple threads """ res_data = {} max_workers = 800 template=""" interface {{ interface }} description {{ description | re(".+") }} vrf {{ vrf }} ipv4 address {{ ip }} {{ mask }} ! {{ _end_ }} """ def worker(): data=""" interface GigabitEthernet0/0/0/23 description GigabitEthernet0/0/0/23 description vrf IPRAN-MGMT ipv4 address 10.1.1.253 255.255.255.252 ! interface GigabitEthernet0/0/0/22 description GigabitEthernet0/0/0/22 description vrf IPRAN-MGMT ipv4 address 10.1.2.253 255.255.255.252 ! """ parser = ttp(data=data, template=template, log_level="warning") parser.parse(one=True) return parser.result(format="json") with ThreadPoolExecutor(max_workers=max_workers) as executor: futures = {executor.submit(worker): worker_id for worker_id in range(max_workers)} for future in as_completed(futures): worker_id = futures[future] > res_data[worker_id] = future.result() ^^^^^^^^^^^^^^^ test_misc.py:1108: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/concurrent/futures/_base.py:447: in result return self.__get_result() ^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/concurrent/futures/_base.py:396: in __get_result raise self._exception /usr/lib/python3.14/concurrent/futures/thread.py:86: in run result = ctx.run(self.task) ^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/concurrent/futures/thread.py:73: in run return fn(*args, **kwargs) ^^^^^^^^^^^^^^^^^^^ test_misc.py:1100: in worker parser = ttp(data=data, template=template, log_level="warning") ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError _____________________ test_ttp_templates_dir_env_variable ______________________ def test_ttp_templates_dir_env_variable(): os.environ["TTP_TEMPLATES_DIR"] = os.path.join( os.getcwd(), "assets", "TTP_TEMPLATES_DIR_TEST" ) data = """ vlan 1234 name some_vlan ! vlan 910 name one_more ! """ > parser = ttp(data=data, template="test_ttp_templates_dir_env_variable.txt") ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ test_misc.py:1150: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError ______________________ test_nested_group_processing_order ______________________ def test_nested_group_processing_order(): """ mac-address match comes after ipv4 group match, if we have contains="name" group function present, mac address not collected. """ data = """ interface Gig123 description foo mtu 1234 ipv4 address 1.2.3.4 255.255.255.0 arp timeout 123 mac-address 123.123.1 ! interface Gig321 description foo mtu 4321 ipv4 address 1.2.3.5 255.255.255.0 arp-timeout 4321 mac-address 123.123.2 ! """ template = """ interface {{ name }} description {{ description | re(".*") }} mtu {{ mtu | to_int }} mac-address {{ mac_address }} arp timeout {{ arp_timeout }} ipv4 address {{ ip | _exact_ }} {{ mask }} !{{ _end_ }} """ > parser = ttp(data=data, template=template) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ test_misc.py:1195: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError ____________________________ test_asterisk_issue_97 ____________________________ def test_asterisk_issue_97(): data = """ interface "port lag-4:1629" create sap lag-4:1629.* create exit """ template = """ interface "{{ interface | ORPHRASE | _start_ }}" {{ ignore }} sap {{ sap | _exact_ }} {{ ignore }} exit {{ _end_ }} """ > parser = ttp(data=data, template=template) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ test_misc.py:1227: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError ___________________ test_issue_98_special_char_in_match_path ___________________ def test_issue_98_special_char_in_match_path(): data = r""" routing-instances { "some_routing_instance_70\1" { instance-type vrf; } } """ template = """ routing-instances {{ ignore }} {{ ri | _start_ }} { } {{ _end_ }} """ > parser = ttp(data=data, template=template) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ test_misc.py:1252: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError ________________ test_tail_match_no_group_functions_processing _________________ def test_tail_match_no_group_functions_processing(): data = """ interface TenGigE0/0/0/42 description ELO ISP FCS1234456# bundle id 1 mode active lacp period short lldp enable transmit disable ! ! interface BVI200 description EPPINGHTHON office subnet mtu 1700 vrf DATA ipv4 address 10.231.2.2 255.255.255.0 ipv6 address fd51:231:2::2/64 ipv4 access-group OFFICE_IN_v4 ingress ipv6 access-group OFFICE_IN_v6 ingress ! """ template = """ """ > parser = ttp(data=data, template=template) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ test_misc.py:1359: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError ________________________________ test_issue_95 _________________________________ def test_issue_95(): data = """ interface Port-Chanel11 description Storage ! interface Loopback0 description RID ip address 10.0.0.3/24 ! interface Vlan777 description Management ip address 192.168.0.1/24 vrf MGMT ! """ template = """ def title(data): data['interface'] = data['interface'].upper() interface {{ interface }} description {{ description }} ip address {{ ip }}/{{ mask }} vrf {{ vrf }} !{{_end_}} """ > parser = ttp(data=data, template=template) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ test_misc.py:1417: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError __________________________ test_csv_formatter_simple ___________________________ def test_csv_formatter_simple(): template_1 = """ interface Port-Chanel11 vlan 10 interface Loopback0 vlan 20 interface {{ interface }} vlan {{ vlan | to_int }} """ > parser = ttp(template=template_1) ^^^^^^^^^^^^^^^^^^^^^^^^ test_output_formatters.py:33: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError _____________________ test_csv_formatter_simple_empty_tag ______________________ def test_csv_formatter_simple_empty_tag(): template_1 = """ interface Port-Chanel11 vlan 10 interface Loopback0 vlan 20 interface {{ interface }} vlan {{ vlan | to_int }} """ > parser = ttp(template=template_1) ^^^^^^^^^^^^^^^^^^^^^^^^ test_output_formatters.py:58: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError _______________________ test_csv_formatter_with_is_equal _______________________ def test_csv_formatter_with_is_equal(): template = """ interface GigabitEthernet3/3 switchport trunk allowed vlan add 138,166-173 description some description ! interface GigabitEthernet3/4 switchport trunk allowed vlan add 100-105 ! interface GigabitEthernet3/5 switchport trunk allowed vlan add 459,531,704-707 ip address 1.1.1.1 255.255.255.255 vrf forwarding ABC_VRF ! interface {{ interface }} switchport trunk allowed vlan add {{ trunk_vlans }} description {{ description | ORPHRASE }} vrf forwarding {{ vrf }} ip address {{ ip }} {{ mask }} !{{ _end_ }} name="out_csv2" path="interfaces2.trunks2" format="csv" sep="," missing="undefined" description="group specific csv outputter" "description","interface","ip","mask","trunk_vlans","vrf" "some description","GigabitEthernet3/3","undefined","undefined","138,166-173","undefined" "undefined","GigabitEthernet3/4","undefined","undefined","100-105","undefined" "undefined","GigabitEthernet3/5","1.1.1.1","255.255.255.255","459,531,704-707","ABC_VRF" """ > parser = ttp(template=template) ^^^^^^^^^^^^^^^^^^^^^^ test_output_formatters.py:114: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError _____________________________ test_excel_formatter _____________________________ def test_excel_formatter(): template = """ interface Loopback0 description Router-id-loopback ip address 192.168.0.113/24 ! interface Loopback1 description Router-id-loopback ip address 192.168.0.1/24 ! interface Vlan778 ip address 2002::fd37/124 ip vrf CPE1 ! interface Vlan779 ip address 2002::bbcd/124 ip vrf CPE2 ! interface {{ interface | contains("Loop") }} ip address {{ ip }}/{{ mask }} description {{ description }} ip vrf {{ vrf }} interface {{ interface | contains("Vlan") }} ip address {{ ip }}/{{ mask }} description {{ description }} ip vrf {{ vrf }} table: - headers: interface, ip, mask, vrf, description path: loopbacks key: interface tab_name: loopbacks - path: vlans """ > parser = ttp(template=template) ^^^^^^^^^^^^^^^^^^^^^^ test_output_formatters.py:180: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError ______________ test_excel_formatter_file_returner_incomplete_url _______________ def test_excel_formatter_file_returner_incomplete_url(): template = """ interface Loopback0 description Router-id-loopback ip address 192.168.0.113/24 ! interface Loopback1 description Router-id-loopback ip address 192.168.0.1/24 ! interface Vlan778 ip address 2002::fd37/124 ip vrf CPE1 ! interface Vlan779 ip address 2002::bbcd/124 ip vrf CPE2 ! interface {{ interface | contains("Loop") }} ip address {{ ip }}/{{ mask }} description {{ description }} ip vrf {{ vrf }} interface {{ interface | contains("Vlan") }} ip address {{ ip }}/{{ mask }} description {{ description }} ip vrf {{ vrf }} table: - headers: interface, ip, mask, vrf, description path: loopbacks key: interface tab_name: loopbacks - path: vlans """ > parser = ttp(template=template) ^^^^^^^^^^^^^^^^^^^^^^ test_output_formatters.py:262: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError _________________________ test_excel_formatter_update __________________________ def test_excel_formatter_update(): template = """ interface Loopback0 description Router-id-loopback ip address 192.168.0.113/24 ! interface Loopback1 description Router-id-loopback ip address 192.168.0.1/24 ! interface Vlan778 ip address 2002::fd37/124 ip vrf CPE1 ! interface Vlan779 ip address 2002::bbcd/124 ip vrf CPE2 ! interface {{ interface | contains("Loop") }} ip address {{ ip }}/{{ mask }} description {{ description }} ip vrf {{ vrf }} interface {{ interface | contains("Vlan") }} ip address {{ ip }}/{{ mask }} description {{ description }} ip vrf {{ vrf }} format: excel filename: excel_out_test_excel_formatter_update.xlsx returner: file update: True url: "./Output/" table: - headers: interface, ip, mask, vrf, description path: loopbacks_new key: interface tab_name: loopbacks_new - path: vlans """ # copy workbook to update it > copyfile( src="./assets/excel_out_test_excel_formatter_update_source.xlsx", dst="./Output/excel_out_test_excel_formatter_update.xlsx", ) test_output_formatters.py:347: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ src = './assets/excel_out_test_excel_formatter_update_source.xlsx' dst = './Output/excel_out_test_excel_formatter_update.xlsx' def copyfile(src, dst, *, follow_symlinks=True): """Copy data from src to dst in the most efficient way possible. If follow_symlinks is not set and src is a symbolic link, a new symlink will be created instead of copying the file it points to. """ sys.audit("shutil.copyfile", src, dst) if _samefile(src, dst): raise SameFileError("{!r} and {!r} are the same file".format(src, dst)) file_size = 0 for i, fn in enumerate([src, dst]): try: st = _stat(fn) except OSError: # File most likely does not exist pass else: # XXX What about other special files? (sockets, devices...) if stat.S_ISFIFO(st.st_mode): fn = fn.path if isinstance(fn, os.DirEntry) else fn raise SpecialFileError("`%s` is a named pipe" % fn) if _WINDOWS and i == 0: file_size = st.st_size if not follow_symlinks and _islink(src): os.symlink(os.readlink(src), dst) else: with open(src, 'rb') as fsrc: try: > with open(dst, 'wb') as fdst: ^^^^^^^^^^^^^^^ E FileNotFoundError: [Errno 2] No such file or directory: './Output/excel_out_test_excel_formatter_update.xlsx' /usr/lib/python3.14/shutil.py:316: FileNotFoundError _______________ test_excel_formatter_update_using_result_kwargs ________________ def test_excel_formatter_update_using_result_kwargs(): template = """ interface Loopback0 description Router-id-loopback ip address 192.168.0.113/24 ! interface Loopback1 description Router-id-loopback ip address 192.168.0.1/24 ! interface Vlan778 ip address 2002::fd37/124 ip vrf CPE1 ! interface Vlan779 ip address 2002::bbcd/124 ip vrf CPE2 ! interface {{ interface | contains("Loop") }} ip address {{ ip }}/{{ mask }} description {{ description }} ip vrf {{ vrf }} interface {{ interface | contains("Vlan") }} ip address {{ ip }}/{{ mask }} description {{ description }} ip vrf {{ vrf }} """ # copy workbook to update it > copyfile( src="./assets/excel_out_test_excel_formatter_update_source.xlsx", dst="./Output/excel_out_test_excel_formatter_update.xlsx", ) test_output_formatters.py:435: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ src = './assets/excel_out_test_excel_formatter_update_source.xlsx' dst = './Output/excel_out_test_excel_formatter_update.xlsx' def copyfile(src, dst, *, follow_symlinks=True): """Copy data from src to dst in the most efficient way possible. If follow_symlinks is not set and src is a symbolic link, a new symlink will be created instead of copying the file it points to. """ sys.audit("shutil.copyfile", src, dst) if _samefile(src, dst): raise SameFileError("{!r} and {!r} are the same file".format(src, dst)) file_size = 0 for i, fn in enumerate([src, dst]): try: st = _stat(fn) except OSError: # File most likely does not exist pass else: # XXX What about other special files? (sockets, devices...) if stat.S_ISFIFO(st.st_mode): fn = fn.path if isinstance(fn, os.DirEntry) else fn raise SpecialFileError("`%s` is a named pipe" % fn) if _WINDOWS and i == 0: file_size = st.st_size if not follow_symlinks and _islink(src): os.symlink(os.readlink(src), dst) else: with open(src, 'rb') as fsrc: try: > with open(dst, 'wb') as fdst: ^^^^^^^^^^^^^^^ E FileNotFoundError: [Errno 2] No such file or directory: './Output/excel_out_test_excel_formatter_update.xlsx' /usr/lib/python3.14/shutil.py:316: FileNotFoundError _____________ test_excel_formatter_no_results_at_path_strict_false _____________ def test_excel_formatter_no_results_at_path_strict_false(): template = """ interface Loopback0 description Router-id-loopback ip address 192.168.0.113/24 ! interface Loopback1 description Router-id-loopback ip address 192.168.0.1/24 interface {{ interface | contains("Loop") }} ip address {{ ip }}/{{ mask }} description {{ description }} ip vrf {{ vrf }} table: - headers: interface, ip, mask, vrf, description path: loopbacks key: interface tab_name: loopbacks - path: vlans strict: False """ > parser = ttp(template=template) ^^^^^^^^^^^^^^^^^^^^^^ test_output_formatters.py:538: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError _____________ test_excel_formatter_no_results_at_path_strict_true ______________ def test_excel_formatter_no_results_at_path_strict_true(): """ This test should raise key-error exception within traverse function as path: vlans not found in results """ template = """ interface Loopback0 description Router-id-loopback ip address 192.168.0.113/24 ! interface Loopback1 description Router-id-loopback ip address 192.168.0.1/24 interface {{ interface | contains("Loop") }} ip address {{ ip }}/{{ mask }} description {{ description }} ip vrf {{ vrf }} table: - headers: interface, ip, mask, vrf, description path: loopbacks key: interface tab_name: loopbacks - path: vlans strict: True """ > parser = ttp(template=template) ^^^^^^^^^^^^^^^^^^^^^^ test_output_formatters.py:608: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError ___________________________ test_tabulate_formatter ____________________________ def test_tabulate_formatter(): template = """ router bgp 65100 neighbor 10.145.1.9 description vic-mel-core1 ! neighbor 192.168.101.1 description qld-bri-core1 router bgp {{ bgp_as }} neighbor {{ peer }} description {{ description }} """ > parser = ttp(template=template) ^^^^^^^^^^^^^^^^^^^^^^ test_output_formatters.py:641: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError _____________________________ test_table_formatter _____________________________ def test_table_formatter(): template = """ router bgp 65100 neighbor 10.145.1.9 description vic-mel-core1 ! neighbor 192.168.101.1 description qld-bri-core1 router bgp {{ bgp_as }} neighbor {{ peer }} description {{ description }} """ > parser = ttp(template=template) ^^^^^^^^^^^^^^^^^^^^^^ test_output_formatters.py:685: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError ________________________ test_table_formatter_with_key _________________________ def test_table_formatter_with_key(): template = """ interface Loopback0 description Router-id-loopback ip address 192.168.0.113/24 ! interface Loopback1 description Router-id-loopback ip address 192.168.0.1/24 ! interface Vlan778 ip address 2002::fd37/124 ip vrf CPE1 ! interface Vlan779 ip address 2002::bbcd/124 ip vrf CPE2 ! interface {{ interface }} ip address {{ ip }}/{{ mask }} description {{ description }} ip vrf {{ vrf }} """ > parser = ttp(template=template) ^^^^^^^^^^^^^^^^^^^^^^ test_output_formatters.py:736: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError _____________________ test_table_formatter_multiple_input ______________________ def test_table_formatter_multiple_input(): template = """ interface Loopback0 ip address 192.168.0.113/24 ! interface Vlan778 ip address 2002::fd37/124 ! interface Loopback10 ip address 192.168.0.10/24 ! interface Vlan710 ip address 2002::fd10/124 ! interface {{ interface }} ip address {{ ip }}/{{ mask }} """ > parser = ttp(template=template) ^^^^^^^^^^^^^^^^^^^^^^ test_output_formatters.py:795: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError ____________________________ test_jinja2_formatter _____________________________ def test_jinja2_formatter(): template = """ interface Loopback0 ip address 192.168.0.113/24 ! interface Vlan778 ip address 2002::fd37/124 ! interface Loopback10 ip address 192.168.0.10/24 ! interface Vlan710 ip address 2002::fd10/124 ! interface {{ interface }} ip address {{ ip }}/{{ mask }} {{ _data_ }} """ > parser = ttp(template=template) ^^^^^^^^^^^^^^^^^^^^^^ test_output_formatters.py:840: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError _______________________ test_cerberus_validate_per_input _______________________ def test_cerberus_validate_per_input(): template = """ csw1# show run | sec ntp hostname csw1 ntp peer 1.2.3.4 ntp peer 1.2.3.5 csw2# show run | sec ntp hostname csw2 ntp peer 1.2.3.4 ntp peer 3.3.3.3 ntp_schema = { "ntp_peers": { 'type': 'list', 'schema': { 'type': 'dict', 'schema': { 'peer': { 'type': 'string', 'allowed': ['1.2.3.4', '1.2.3.5'] } } } } } hostname {{ host_name }} ntp peer {{ peer }} """ > parser = ttp(template=template, log_level="ERROR") ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ test_output_functions.py:56: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError _____________________ test_cerberus_validate_per_template ______________________ def test_cerberus_validate_per_template(): template = """ """ > parser = ttp(template=template, log_level="ERROR") ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ test_output_functions.py:115: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError _________________ test_global_output_deepdiff_with_var_before __________________ def test_global_output_deepdiff_with_var_before(): template = """ before = [[{'description': 'some info', 'interface': 'GigabitEthernet1', 'ip': '10.123.89.56', 'mask': '255.255.255.255'}, {'interface': 'GigabitEthernet2', 'ip': '10.123.89.55', 'mask': '255.255.255.0'}]] r1#show interfaces | inc line protocol: interface GigabitEthernet1 description some info vrf forwarding MGMT ip address 10.123.89.56 255.255.255.0 interface GigabitEthernet2 ip address 10.123.89.55 255.255.255.0 interface {{ interface }} description {{ description | ORPHRASE }} ip address {{ ip }} {{ mask }} """ > parser = ttp(template=template) ^^^^^^^^^^^^^^^^^^^^^^ test_output_functions.py:161: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError _____________ test_group_specific_output_deepdiff_with_var_before ______________ def test_group_specific_output_deepdiff_with_var_before(): template = """ before = {"interfaces": [{'description': 'some info', 'interface': 'GigabitEthernet1', 'ip': '10.123.89.56', 'mask': '255.255.255.255'}, {'interface': 'GigabitEthernet2', 'ip': '10.123.89.55', 'mask': '255.255.255.0'}]} r1#show interfaces | inc line protocol: interface GigabitEthernet1 description some info vrf forwarding MGMT ip address 10.123.89.56 255.255.255.0 interface GigabitEthernet2 ip address 10.123.89.55 255.255.255.0 interface {{ interface }} description {{ description | ORPHRASE }} ip address {{ ip }} {{ mask }} interface {{ interface }} vrf forwarding {{ vrf }} ip address {{ ip }} {{ mask }} """ > parser = ttp(template=template) ^^^^^^^^^^^^^^^^^^^^^^ test_output_functions.py:216: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError ______ test_group_specific_output_deepdiff_with_var_before_with_add_field ______ def test_group_specific_output_deepdiff_with_var_before_with_add_field(): template = """ before = {"interfaces": [{'description': 'some info', 'interface': 'GigabitEthernet1', 'ip': '10.123.89.56', 'mask': '255.255.255.255'}, {'interface': 'GigabitEthernet2', 'ip': '10.123.89.55', 'mask': '255.255.255.0'}]} r1#show interfaces | inc line protocol: interface GigabitEthernet1 description some info vrf forwarding MGMT ip address 10.123.89.56 255.255.255.0 interface GigabitEthernet2 ip address 10.123.89.55 255.255.255.0 interface {{ interface }} description {{ description | ORPHRASE }} ip address {{ ip }} {{ mask }} interface {{ interface }} vrf forwarding {{ vrf }} ip address {{ ip }} {{ mask }} """ > parser = ttp(template=template) ^^^^^^^^^^^^^^^^^^^^^^ test_output_functions.py:290: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError _______________________ test_output_condition_attribute ________________________ def test_output_condition_attribute(): data = """ interface GigabitEthernet1/3.251 description Customer #32148 encapsulation dot1q 251 ip address 172.16.33.10 255.255.255.128 shutdown ! interface GigabitEthernet1/4 description vCPEs access control ip address 172.16.33.10 255.255.255.128 """ template = """ interface {{ interface }} description {{ description }} encapsulation dot1q {{ vlan }} ip address {{ ip }} {{ mask }} """ > parser1 = ttp(data=data, template=template, vars={"convert_to_csv": False}) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ test_output_functions.py:1811: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError ________________________ test_file_returner_format_raw _________________________ def test_file_returner_format_raw(): template_1 = """ interface Port-Chanel11 vlan 10 interface Loopback0 vlan 20 interface {{ interface }} vlan {{ vlan | to_int }} """ > parser = ttp(template=template_1) ^^^^^^^^^^^^^^^^^^^^^^^^ test_output_returners.py:33: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError _________________ test_file_returner_format_raw_incomplete_url _________________ def test_file_returner_format_raw_incomplete_url(): template_1 = """ interface Port-Chanel11 vlan 10 interface Loopback0 vlan 20 interface {{ interface }} vlan {{ vlan | to_int }} """ > parser = ttp(template=template_1) ^^^^^^^^^^^^^^^^^^^^^^^^ test_output_returners.py:67: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError _______________________ test_file_returner_format_raw_1 ________________________ def test_file_returner_format_raw_1(): template_1 = """ interface Port-Chanel11 vlan 10 interface Loopback0 vlan 20 interface {{ interface }} vlan {{ vlan | to_int }} returner="file" url="./Output/" filename="out_test_file_returner_1.txt" """ > parser = ttp(template=template_1) ^^^^^^^^^^^^^^^^^^^^^^^^ test_output_returners.py:101: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError ______________________ test_file_returner_filename_format ______________________ def test_file_returner_filename_format(): template_1 = """ switch-sw1# show run interfaces interface Port-Chanel11 vlan 10 interface Loopback0 vlan 20 switch-sw2# show run interfaces interface Port-Chanel11 vlan 10 interface Loopback0 vlan 20 host_name = "gethostname" interface {{ interface }} vlan {{ vlan | to_int }} {{ hostname | set(host_name) }} returner="file" url="./Output/" filename="out_test_file_returner_{host_name}.txt" """ > parser = ttp(template=template_1) ^^^^^^^^^^^^^^^^^^^^^^^^ test_output_returners.py:146: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError ___________ test_file_returner_filename_format_group_specific_output ___________ def test_file_returner_filename_format_group_specific_output(): template_1 = """ switch-sw1# show run interfaces interface Port-Chanel11 vlan 10 interface Loopback0 vlan 20 switch-sw2# show run interfaces interface Port-Chanel11 vlan 10 interface Loopback0 vlan 20 host_name = "gethostname" interface {{ interface }} vlan {{ vlan | to_int }} returner="file" url="./Output/" filename="out_test_file_returner_{host_name}_group_specific_outputter.txt" """ > parser = ttp(template=template_1) ^^^^^^^^^^^^^^^^^^^^^^^^ test_output_returners.py:193: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError _________________________ test_pipe_separated_regexes __________________________ def test_pipe_separated_regexes(): template = """ Protocol Address Age (min) Hardware Addr Type Interface Internet 10.12.13.1 98 0950.5785.5cd1 ARPA FastEthernet2.13 Internet 10.12.13.2 98 0950.5785.5cd2 ARPA Loopback0 Internet 10.12.13.3 131 0150.7685.14d5 ARPA GigabitEthernet2.13 Internet 10.12.13.4 198 0950.5C8A.5c41 ARPA GigabitEthernet2.17 INTF_RE = r"GigabitEthernet\\S+|Fast\\S+" Internet {{ ip | re("IP")}} {{ age | re(r"\\d+") }} {{ mac }} ARPA {{ interface | re("INTF_RE") }} """ > parser = ttp(template=template) ^^^^^^^^^^^^^^^^^^^^^^ test_regexes.py:31: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError _________________________ test_multiple_inline_regexes _________________________ def test_multiple_inline_regexes(): template = """ Protocol Address Age (min) Hardware Addr Type Interface Internet 10.12.13.1 98 0950.5785.5cd1 ARPA FastEthernet2.13 Internet 10.12.13.2 98 0950.5785.5cd2 ARPA Loopback0 Internet 10.12.13.3 131 0150.7685.14d5 ARPA GigabitEthernet2.13 Internet 10.12.13.4 198 0950.5C8A.5c41 ARPA GigabitEthernet2.17 INTF_RE = r"GigabitEthernet\\S+|Fast\\S+" Internet {{ ip }} {{ age }} {{ mac }} ARPA {{ interface | re(r"GigabitEthernet\\S+") | re(r"Fast\\S+") }} """ > parser = ttp(template=template) ^^^^^^^^^^^^^^^^^^^^^^ test_regexes.py:84: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError ___________________________ test_MAC_regex_formatter ___________________________ def test_MAC_regex_formatter(): template = """ Protocol Address Age (min) Hardware Addr Type Interface Internet 10.12.13.2 98 0950:5785:5cd2 ARPA Loopback0 Internet 10.12.13.3 131 0150.7685.14d5 ARPA GigabitEthernet2.13 Internet 10.12.13.1 98 0950-5785-5cd1 ARPA FastEthernet2.13 Internet 10.12.13.4 198 09:50:5C:8A:5c:41 ARPA GigabitEthernet2.17 Internet 10.12.13.5 198 09.50.5C.8A.5c.41 ARPA GigabitEthernet2.17 Internet 10.12.13.6 198 09-50-5C-8A-5c-41 ARPA GigabitEthernet2.17 Internet 10.12.13.6 198 09505C8A5c41 ARPA GigabitEthernet2.will_not_match Internet 10.12.13.6 198 09505C8:A5c41 ARPA GigabitEthernet2.will_not_match Internet 10.12.13.6 198 09505C.8.A5c41 ARPA GigabitEthernet2.will_not_match Internet {{ ip }} {{ age }} {{ mac | MAC }} ARPA {{ interface }} """ > parser = ttp(template=template) ^^^^^^^^^^^^^^^^^^^^^^ test_regexes.py:138: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError _____________________________ test_list_structure ______________________________ def test_list_structure(): > parser = ttp(template=template_1) ^^^^^^^^^^^^^^^^^^^^^^^^ test_structure.py:104: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError ______________________ test_list_structure_with_outputter ______________________ def test_list_structure_with_outputter(): > parser = ttp(template=template_1) ^^^^^^^^^^^^^^^^^^^^^^^^ test_structure.py:111: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError __________________________ test_dictionary_structure ___________________________ def test_dictionary_structure(): > parser = ttp(template=template_2) ^^^^^^^^^^^^^^^^^^^^^^^^ test_structure.py:118: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError ___________________ test_dictionary_structure_with_outputter ___________________ def test_dictionary_structure_with_outputter(): > parser = ttp(template=template_2) ^^^^^^^^^^^^^^^^^^^^^^^^ test_structure.py:125: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError ___________________________ test_flat_list_structure ___________________________ def test_flat_list_structure(): > parser = ttp(template=template_1) ^^^^^^^^^^^^^^^^^^^^^^^^ test_structure.py:132: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError ___________________ test_flat_list_structure_with_outputter ____________________ def test_flat_list_structure_with_outputter(): > parser = ttp(template=template_1) ^^^^^^^^^^^^^^^^^^^^^^^^ test_structure.py:140: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError _____________________________ test_syslog_returner _____________________________ def test_syslog_returner(): template = """ router-2-lab#show ip arp Protocol Address Age (min) Hardware Addr Type Interface Internet 10.1.13.4 - 0050.5685.14d6 ARPA GigabitEthernet3.13 Internet 10.1.13.5 - 0050.5685.14d7 ARPA GigabitEthernet4.14 router-3-lab#show ip arp Protocol Address Age (min) Hardware Addr Type Interface Internet 10.1.13.1 98 0050.5685.5cd1 ARPA GigabitEthernet1.11 Internet 10.1.13.3 - 0050.5685.14d5 ARPA GigabitEthernet2.12 hostname="gethostname" Internet {{ ip }} {{ age | DIGIT }} {{ mac }} ARPA {{ interface }} Internet {{ ip }} - {{ mac }} ARPA {{ interface }} {{ hostname | set(hostname) }} servers=["192.168.1.175", "192.168.1.105"] port="10514" path="arp_table" iterate=True facility=77 """ > parser = ttp(template=template) ^^^^^^^^^^^^^^^^^^^^^^ test_syslog_returner.py:41: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError ___________________ test_include_attribute_with_yaml_loader ____________________ def test_include_attribute_with_yaml_loader(): template = """ Protocol Address Age (min) Hardware Addr Type Interface Internet 10.12.13.1 98 0950.5785.5cd1 ARPA FastEthernet2.13 Internet 10.12.13.2 98 0950.5785.5cd2 ARPA Loopback0 Internet 10.12.13.3 131 0150.7685.14d5 ARPA GigabitEthernet2.13 Internet 10.12.13.4 198 0950.5C8A.5c41 ARPA GigabitEthernet2.17 Internet {{ ip }} {{ age }} {{ mac }} ARPA {{ interface | re("INTF_RE") }} """ > parser = ttp(template=template) ^^^^^^^^^^^^^^^^^^^^^^ test_template_variables.py:25: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError _________________________ test_sros_gethostname_getter _________________________ def test_sros_gethostname_getter(): """ Test ALU SROS prompt matching using gethostname, reference: https://documentation.nokia.com/cgi-bin/dbaccessfilename.cgi/9300700701_V1_7750%20SR%20OS%20Basic%20System%20Configuration%20Guide%208.0r1.pdf """ data = [ """ A:ALA-12> show system information =============================================================================== System Information =============================================================================== System Name : A:ALA-12> System Contact : Fred Information Technology System Location : Bldg.1-floor 2-Room 201 """, """ A:ALA-12# show system information =============================================================================== System Information =============================================================================== System Name : A:ALA-12# System Contact : Fred Information Technology System Location : Bldg.1-floor 2-Room 201 """, """ *A:ALA-12> show system information =============================================================================== System Information =============================================================================== System Name : *A:ALA-12> System Contact : Fred Information Technology System Location : Bldg.1-floor 2-Room 201 """, """ *A:ALA-12# show system information =============================================================================== System Information =============================================================================== System Name : *A:ALA-12# System Contact : Fred Information Technology System Location : Bldg.1-floor 2-Room 201 """, """ *A:ALA-12>config>system# show system information =============================================================================== System Information =============================================================================== System Name : *A:ALA-12>config>system# System Contact : Fred Information Technology System Location : Bldg.1-floor 2-Room 201 """, """ A:ALA-12>config>system# show system information =============================================================================== System Information =============================================================================== System Name : A:ALA-12>config>system# System Contact : Fred Information Technology System Location : Bldg.1-floor 2-Room 201 """, ] template = """ hostname="gethostname" System Name : {{ sysname }} System Contact : {{ contacts | PHRASE }} System Location : {{ locarion | PHRASE }} """ > parser = ttp(template=template) ^^^^^^^^^^^^^^^^^^^^^^ test_template_variables.py:137: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError ____________________________ test_clear_result_all _____________________________ def test_clear_result_all(): template_1 = """ interface Lo0 ip address 124.171.238.50 32 ! interface Lo1 description this interface has description ip address 1.1.1.1 32 interface {{ interface }} description {{ description | ORPHRASE }} ip address {{ ip }} {{ mask }} """ > parser = ttp(template=template_1) ^^^^^^^^^^^^^^^^^^^^^^^^ test_ttp_parser_methods.py:30: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError __________________________ test_clear_result_by_name ___________________________ def test_clear_result_by_name(): template_2 = """ """ > parser = ttp(template=template_2) ^^^^^^^^^^^^^^^^^^^^^^^^ test_ttp_parser_methods.py:76: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError _____________________ test_add_input_with_default_options ______________________ def test_add_input_with_default_options(): data_1 = """ interface Lo0 ip address 124.171.238.50 32 ! interface Lo1 description this interface has description ip address 1.1.1.1 32 """ data_2 = """ interface Lo2 ip address 124.171.238.22 32 ! interface Lo3 description this interface has description ip address 2.2.2.2 32 """ template_1 = """ interface {{ interface }} description {{ description | ORPHRASE }} ip address {{ ip }} {{ mask }} """ > parser = ttp(template=template_1) ^^^^^^^^^^^^^^^^^^^^^^^^ test_ttp_parser_methods.py:120: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError ___________________ test_add_input_to_non_existing_template ____________________ def test_add_input_to_non_existing_template(): data_1 = """ interface Lo0 ip address 124.171.238.50 32 ! interface Lo1 description this interface has description ip address 1.1.1.1 32 """ data_2 = """ interface Lo2 ip address 124.171.238.22 32 ! interface Lo3 description this interface has description ip address 2.2.2.2 32 """ template_1 = """ interface {{ interface }} description {{ description | ORPHRASE }} ip address {{ ip }} {{ mask }} """ > parser = ttp(template=template_1) ^^^^^^^^^^^^^^^^^^^^^^^^ test_ttp_parser_methods.py:217: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError _________________ test_add_input_to_non_default_root_template __________________ def test_add_input_to_non_default_root_template(): data_1 = """ interface Lo0 ip address 124.171.238.50 32 ! interface Lo1 description this interface has description ip address 1.1.1.1 32 """ data_2 = """ interface Lo2 ip address 124.171.238.22 32 ! interface Lo3 description this interface has description ip address 2.2.2.2 32 """ template_1 = """ """ > parser = ttp(template=template_1) ^^^^^^^^^^^^^^^^^^^^^^^^ test_ttp_parser_methods.py:296: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError _______________ test_add_inputs_to_child_templates_default_input _______________ def test_add_inputs_to_child_templates_default_input(): data_1 = """ interface Lo0 ip address 124.171.238.50 32 ! interface Lo1 description this interface has description ip address 1.1.1.1 32 """ data_2 = """ interface Lo2 ip address 124.171.238.22 32 ! interface Lo3 description this interface has description ip address 2.2.2.2 32 """ data_3 = """ interface Lo4 ip address 124.171.238.33 32 ! interface Lo5 description this interface has description ip address 3.3.3.3 32 """ template_1 = """ """ > parser = ttp(template=template_1) ^^^^^^^^^^^^^^^^^^^^^^^^ test_ttp_parser_methods.py:387: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError _____________ test_add_inputs_to_child_templates_non_default_input _____________ def test_add_inputs_to_child_templates_non_default_input(): data_1 = """ interface Lo0 ip address 124.171.238.50 32 ! interface Lo1 description this interface has description ip address 1.1.1.1 32 """ data_2 = """ interface Lo2 ip address 124.171.238.22 32 ! interface Lo3 description this interface has description ip address 2.2.2.2 32 """ data_3 = """ interface Lo4 ip address 124.171.238.33 32 ! interface Lo5 description this interface has description ip address 3.3.3.3 32 """ template_1 = """ """ > parser = ttp(template=template_1) ^^^^^^^^^^^^^^^^^^^^^^^^ test_ttp_parser_methods.py:547: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError ______________________ test_set_input_for_child_template _______________________ def test_set_input_for_child_template(): data_1 = """ interface Lo0 ip address 124.171.238.50 32 ! interface Lo1 description this interface has description ip address 1.1.1.1 32 """ data_2 = """ interface Lo2 ip address 124.171.238.22 32 ! interface Lo3 description this interface has description ip address 2.2.2.2 32 """ data_3 = """ interface Lo4 ip address 124.171.238.33 32 ! interface Lo5 description this interface has description ip address 3.3.3.3 32 """ template_1 = """ """ > parser = ttp(template=template_1) ^^^^^^^^^^^^^^^^^^^^^^^^ test_ttp_parser_methods.py:682: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError ______________________________ test_add_template _______________________________ def test_add_template(): data_1 = """ interface Lo0 ip address 124.171.238.50 32 ! interface Lo1 description this interface has description ip address 1.1.1.1 32 """ data_2 = """ interface Lo2 ip address 124.171.238.22 32 ! interface Lo3 description this interface has description ip address 2.2.2.2 32 """ template_1 = """ """ template_2 = """ interface {{ interface }} description {{ description | ORPHRASE }} ip address {{ ip }} {{ mask }} """ > parser = ttp() ^^^^^ test_ttp_parser_methods.py:786: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError _____________________ test_get_input_load_default_template _____________________ def test_get_input_load_default_template(): template = """ my_params: key1: val1 key2: val2 more_params: - item1 - item2 - item3 {{ interface }} is up, line protocol is up {{ in_pkts}} packets input, 25963 bytes, 0 no buffer {{ out_pkts }} packets output, 26812 bytes, 0 underruns """ > parser = ttp(template=template) ^^^^^^^^^^^^^^^^^^^^^^ test_ttp_parser_methods.py:972: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError _____________________ test_get_input_load_child_templates ______________________ def test_get_input_load_child_templates(): template = """ """ > parser = ttp(template=template) ^^^^^^^^^^^^^^^^^^^^^^ test_ttp_parser_methods.py:1015: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError _________________ test_default_behaviour_with_named_templates __________________ def test_default_behaviour_with_named_templates(): """ This templates testthat datacorrectly added to all templates if data and template supplied on TTP parser object instantiation """ data = """ # show service Name Protocol Dst-Port/Type DISCARD UDP 9 DNS UDP 53 TCP 53 ECHO UDP 7 """ template = """ """ > parser = ttp(data, template) ^^^^^^^^^^^^^^^^^^^ test_ttp_parser_methods.py:1045: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError ______________________ test_add_function_method_match_var ______________________ def test_add_function_method_match_var(): template_1 = """ interface Lo0 ip address 124.171.238.50 32 ! interface Lo1 description this interface has description ip address 1.1.1.1 32 interface {{ interface | myFun }} description {{ description | ORPHRASE | myFun }} ip address {{ ip }} {{ mask }} """ > parser = ttp(template=template_1) ^^^^^^^^^^^^^^^^^^^^^^^^ test_ttp_parser_methods.py:1080: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError _________________ test_add_function_method_match_var_multiproc _________________ def test_add_function_method_match_var_multiproc(): template_1 = """ interface Lo0 ip address 124.171.238.50 32 ! interface Lo1 description this interface has description ip address 1.1.1.1 32 interface Lo10 ip address 124.171.238.50 32 ! interface Lo11 description this interface has description ip address 1.1.1.1 32 interface Lo12 ip address 124.171.238.50 32 ! interface Lo13 description this interface has description ip address 1.1.1.1 32 interface {{ interface | myFun }} description {{ description | ORPHRASE | myFun }} ip address {{ ip }} {{ mask }} """ > parser = ttp(template=template_1) ^^^^^^^^^^^^^^^^^^^^^^^^ test_ttp_parser_methods.py:1138: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError ________________________ test_add_function_method_group ________________________ def test_add_function_method_group(): template_1 = """ interface Lo0 ip address 124.171.238.50 32 ! interface Lo1 description this interface has description ip address 1.1.1.1 32 interface {{ interface }} description {{ description | ORPHRASE }} ip address {{ ip }} {{ mask }} """ > parser = ttp(template=template_1, log_level="ERROR") ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ test_ttp_parser_methods.py:1207: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError ________________________ test_add_function_method_input ________________________ def test_add_function_method_input(): template_1 = """ interface Lo0 ip address 124.171.238.50 32 ! interface Lo1 description this interface has description ip address 1.1.1.1 32 interface {{ interface }} description {{ description | ORPHRASE }} ip address {{ ip }} {{ mask }} """ > parser = ttp(log_level="ERROR") ^^^^^^^^^^^^^^^^^^^^^^ test_ttp_parser_methods.py:1257: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError _______________________ test_add_function_method_output ________________________ def test_add_function_method_output(): template_1 = """ interface Lo0 ip address 124.171.238.50 32 ! interface Lo1 description this interface has description ip address 1.1.1.1 32 interface {{ interface }} description {{ description | ORPHRASE }} ip address {{ ip }} {{ mask }} """ > parser = ttp(log_level="ERROR") ^^^^^^^^^^^^^^^^^^^^^^ test_ttp_parser_methods.py:1308: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError ___________________ test_add_function_method_output_returner ___________________ def test_add_function_method_output_returner(): template_1 = """ interface Lo0 ip address 124.171.238.50 32 ! interface Lo1 description this interface has description ip address 1.1.1.1 32 interface {{ interface }} description {{ description | ORPHRASE }} ip address {{ ip }} {{ mask }} """ > parser = ttp(log_level="ERROR") ^^^^^^^^^^^^^^^^^^^^^^ test_ttp_parser_methods.py:1348: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError __________________ test_add_function_method_output_formatter ___________________ def test_add_function_method_output_formatter(): template_1 = """ interface Lo0 ip address 124.171.238.50 32 ! interface Lo1 description this interface has description ip address 1.1.1.1 32 interface {{ interface }} description {{ description | ORPHRASE }} ip address {{ ip }} {{ mask }} """ > parser = ttp(log_level="ERROR") ^^^^^^^^^^^^^^^^^^^^^^ test_ttp_parser_methods.py:1387: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError ___________________ test_add_function_method_variable_getter ___________________ def test_add_function_method_variable_getter(): template_1 = """ var_1 = "custom_getter" interface Lo0 ip address 124.171.238.50 32 ! interface Lo1 description this interface has description ip address 1.1.1.1 32 interface {{ interface }} description {{ description | ORPHRASE }} ip address {{ ip }} {{ mask }} """ > parser = ttp(log_level="ERROR") ^^^^^^^^^^^^^^^^^^^^^^ test_ttp_parser_methods.py:1426: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError ___________________ test_add_function_method_macro_match_var ___________________ def test_add_function_method_macro_match_var(): template_1 = """ interface Lo0 ip address 124.171.238.50 32 ! interface Lo1 description this interface has description ip address 1.1.1.1 32 interface {{ interface | macro("custM") }} description {{ description | ORPHRASE }} ip address {{ ip }} {{ mask }} """ > parser = ttp(log_level="ERROR") ^^^^^^^^^^^^^^^^^^^^^^ test_ttp_parser_methods.py:1472: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError ____________________ test_add_function_method_macro_output _____________________ def test_add_function_method_macro_output(): template_1 = """ interface Lo0 ip address 124.171.238.50 32 ! interface Lo1 description this interface has description ip address 1.1.1.1 32 interface {{ interface }} description {{ description | ORPHRASE }} ip address {{ ip }} {{ mask }} """ > parser = ttp(log_level="ERROR") ^^^^^^^^^^^^^^^^^^^^^^ test_ttp_parser_methods.py:1519: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError ____________________ test_get_input_load_anonymous_template ____________________ def test_get_input_load_anonymous_template(): template = """ {{ interface }} is up, line protocol is up {{ in_pkts}} packets input, 25963 bytes, 0 no buffer {{ out_pkts }} packets output, 26812 bytes, 0 underruns """ data = """ some data """ > parser = ttp(data, template=template) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ test_ttp_parser_methods.py:1544: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError _______________ test_add_function_method_group_globals_injection _______________ def test_add_function_method_group_globals_injection(): template_1 = """ interface Lo0 ip address 124.171.238.50 32 ! interface Lo1 description this interface has description ip address 1.1.1.1 32 interface {{ interface }} description {{ description | ORPHRASE }} ip address {{ ip }} {{ mask }} """ > parser = ttp(template=template_1, log_level="ERROR") ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ test_ttp_parser_methods.py:1576: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError _____________________ test_add_input_structured_data_list ______________________ def test_add_input_structured_data_list(): data_list = [ """ interface Lo0 ip address 124.171.238.50 32 """, """ interface Lo1 description this interface has description ip address 1.1.1.1 32 """, ] template = """ def pre_process(data): return r'\\n'.join(data) interface {{ interface }} description {{ description | ORPHRASE }} ip address {{ ip }} {{ mask }} """ > parser = ttp(template=template, log_level="ERROR") ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ test_ttp_parser_methods.py:1628: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError ___________________ test_loading_template_from_ttp_templates ___________________ def test_loading_template_from_ttp_templates(): data1 = """ interface Lo0 ip address 124.171.238.50 32 ! interface Lo1 description this interface has description ip address 1.1.1.1 32 """ > parser = ttp( data=data1, template="ttp://platform/test_platform_show_run_pipe_sec_interface.txt", ) test_ttp_parser_methods.py:1657: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError __________________________ test_quick_parse_function ___________________________ def test_quick_parse_function(): from ttp import quick_parse template = """ interface {{ interface }} description {{ description | ORPHRASE }} ip address {{ ip }} {{ mask }} """ data = """ interface Lo0 ip address 124.171.238.50 32 ! interface Lo1 description this interface has description ip address 1.1.1.1 32 """ > res = quick_parse(data, template) ^^^^^^^^^^^^^^^^^^^^^^^^^^^ test_ttp_parser_methods.py:1700: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/utils/quick_parse.py:44: in quick_parse parser = ttp(data=data, template=template, **ttp_kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError ____________________ test_quick_parse_function_with_kwargs _____________________ def test_quick_parse_function_with_kwargs(): from ttp import quick_parse template = """ interface {{ interface }} description {{ description | ORPHRASE }} ip address {{ ip }} {{ mask }} """ data = """ interface Lo0 ip address 124.171.238.50 32 ! interface Lo1 description this interface has description ip address 1.1.1.1 32 """ > res = quick_parse( data, template, ttp_kwargs={"vars": {"a": 1}}, parse_kwargs={"one": True}, result_kwargs={"structure": "flat_list"}, ) test_ttp_parser_methods.py:1738: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/utils/quick_parse.py:44: in quick_parse parser = ttp(data=data, template=template, **ttp_kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError ___________________ test_quick_parse_function_template_only ____________________ def test_quick_parse_function_template_only(): from ttp import quick_parse template = """ interface Lo0 ip address 124.171.238.50 32 ! interface Lo1 description this interface has description ip address 1.1.1.1 32 interface {{ interface }} description {{ description | ORPHRASE }} ip address {{ ip }} {{ mask }} """ > res = quick_parse(template=template) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ test_ttp_parser_methods.py:1779: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/utils/quick_parse.py:46: in quick_parse parser = ttp(template=template, **ttp_kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError ___________________________ test_get_template_method ___________________________ def test_get_template_method(): template = """ interface {{ interface }} description {{ description | ORPHRASE }} ip address {{ ip }} {{ mask }} """ > parser = ttp(template=template) ^^^^^^^^^^^^^^^^^^^^^^ test_ttp_parser_methods.py:1807: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError __________________ test_get_template_method_nested_templates ___________________ def test_get_template_method_nested_templates(): template = """ def indent1(template_text): return "\\n".join(f" {line}" for line in template_text.splitlines()) def indent2(template_text): return "\\n".join(f" {line}" for line in template_text.splitlines()) router bgp {{ asn }} vrf {{ vrf }} rd {{ rd }} interface {{ interface }} description {{ description | ORPHRASE }} ip address {{ ip }} {{ mask }} """ > parser = ttp(template=template) ^^^^^^^^^^^^^^^^^^^^^^ test_ttp_parser_methods.py:1854: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../ttp/ttp.py:240: in __init__ self._ttp_ = lazy_import_functions() ^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def lazy_import_functions(): """function to collect a list of all files/directories within ttp module, parse .py files using ast and extract information about all functions to cache them within _ttp_ dictionary """ _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, } log.info("ttp.lazy_import_functions: starting functions lazy import") # try to load previously pickled/cached _ttp_ dictionary path_to_cache = os.getenv("TTPCACHEFOLDER", os.path.dirname(__file__)) cache_file = os.path.join(path_to_cache, "ttp_dict_cache.pickle") try: if os.path.isfile(cache_file): with open(cache_file, "rb") as f: _ttp_ = pickle.load(f) # use unpickled _ttp_ dictionary if it of the same python version if ( _ttp_["python_major_version"] == version_info.major and _ttp_.get("__version__") == __version__ ): log.info( "ttp.lazy_import_functions: loaded _ttp_ dictionary from ttp_dict_cache.pickle" ) return _ttp_ # rebuilt _ttp_ dictionary as it is of different version else: _ttp_ = { "macro": {}, "python_major_version": version_info.major, "global_vars": {}, "template_obj": {}, "vars": {}, "__version__": __version__, } except Exception as e: log.warning( "ttp.lazy_import_functions: failed load ttp_dict_cache.pickle, loading functions directly, error '{}'".format( e ) ) # load functions from files instead exclude = "_py3.py" if _ttp_["python_major_version"] == 2 else "_py2.py" exclude_modules = ["ttp.py"] # load and parse files log.info("ttp.lazy_import_functions: loading files for ast parsing") for item in os.walk(os.path.dirname(__file__)): root, dirs, files = item for f in files: if not ( f.endswith(".py") and not f.startswith("_") and not f.endswith(exclude) and f not in exclude_modules ): continue try: module_file = open("{}/{}".format(root, f), mode="r", encoding="utf-8") except: # in some versions of python open() does not support encoding module_file = open("{}/{}".format(root, f), mode="r") node = ast.parse(module_file.read()) assignments = [n for n in node.body if isinstance(n, ast.Assign)] functions = [n.name for n in node.body if isinstance(n, ast.FunctionDef)] functions = [f for f in functions if (not f.startswith("_"))] # get _name_map_ _name_map_ = {} for assignment in assignments: # stop if _name_map_ already found if _name_map_: break for target in assignment.targets: if target.id == "_name_map_": _name_map_.update( { > key.s: assignment.value.values[index].s ^^^^^ for index, key in enumerate(assignment.value.keys) } ) E AttributeError: 'Constant' object has no attribute 's' ../../ttp/ttp.py:152: AttributeError =============================== warnings summary =============================== test_answers_and_docs.py:6750 /usr/src/RPM/BUILD/ttp-0.9.5/test/pytest/test_answers_and_docs.py:6750: SyntaxWarning: "\s" is an invalid escape sequence. Such sequences will not work in the future. Did you mean "\\s"? A raw string is also an option. {{ ignore(r'\s+') }}received{{ ignore('.*') }} -- Docs: https://docs.pytest.org/en/stable/how-to/capture-warnings.html =========================== short test summary info ============================ FAILED test_anonymous_group.py::test_simple_anonymous_template - AttributeErr... FAILED test_anonymous_group.py::test_anonymous_group_with_vars - AttributeErr... FAILED test_anonymous_group.py::test_anonymous_group_with_child_group_empty_absolute_path FAILED test_anonymous_group.py::test_anonymous_group_with_per_template_mode FAILED test_answers_and_docs.py::test_answer_1 - AttributeError: 'Constant' o... FAILED test_answers_and_docs.py::test_answer_2 - AttributeError: 'Constant' o... FAILED test_answers_and_docs.py::test_issue_20_answer - AttributeError: 'Cons... FAILED test_answers_and_docs.py::test_answer_3 - AttributeError: 'Constant' o... FAILED test_answers_and_docs.py::test_answer_4 - AttributeError: 'Constant' o... FAILED test_answers_and_docs.py::test_issue_20_answer_2 - AttributeError: 'Co... FAILED test_answers_and_docs.py::test_docs_ttp_dictionary_usage_example - Att... FAILED test_answers_and_docs.py::test_github_issue_21_answer - AttributeError... FAILED test_answers_and_docs.py::test_github_issue_22 - AttributeError: 'Cons... FAILED test_answers_and_docs.py::test_github_issue_24 - AttributeError: 'Cons... FAILED test_answers_and_docs.py::test_reddit_answer_1 - AttributeError: 'Cons... FAILED test_answers_and_docs.py::test_reddit_answer_2 - AttributeError: 'Cons... FAILED test_answers_and_docs.py::test_github_issue_32 - AttributeError: 'Cons... FAILED test_answers_and_docs.py::test_slack_answer_1 - AttributeError: 'Const... FAILED test_answers_and_docs.py::test_group_default_docs - AttributeError: 'C... FAILED test_answers_and_docs.py::test_github_issue_34_answer - AttributeError... FAILED test_answers_and_docs.py::test_github_issue_33_answer_1 - AttributeErr... FAILED test_answers_and_docs.py::test_issue_36 - AttributeError: 'Constant' o... FAILED test_answers_and_docs.py::test_github_issue_37_original_data_template FAILED test_answers_and_docs.py::test_github_issue_37_cleaned_up_data - Attri... FAILED test_answers_and_docs.py::test_github_issue_37_cleaned_data_template FAILED test_answers_and_docs.py::test_github_issue_42 - AttributeError: 'Cons... FAILED test_answers_and_docs.py::test_github_issue_42_answer - AttributeError... FAILED test_answers_and_docs.py::test_issue_45 - AttributeError: 'Constant' o... FAILED test_answers_and_docs.py::test_issue_45_1 - AttributeError: 'Constant'... FAILED test_answers_and_docs.py::test_issue_45_filtering_fix - AttributeError... FAILED test_answers_and_docs.py::test_issue_47_answer - AttributeError: 'Cons... FAILED test_answers_and_docs.py::test_issue_48_answer - AttributeError: 'Cons... FAILED test_answers_and_docs.py::test_issue_48_answer_more - AttributeError: ... FAILED test_answers_and_docs.py::test_slack_channel_answer_for_Noif - Attribu... FAILED test_answers_and_docs.py::test_slack_answer_2 - AttributeError: 'Const... FAILED test_answers_and_docs.py::test_slack_answer_3 - AttributeError: 'Const... FAILED test_answers_and_docs.py::test_slack_answer_3_full - AttributeError: '... FAILED test_answers_and_docs.py::test_issue_45_for_junos_cfg - AttributeError... FAILED test_answers_and_docs.py::test_faq_multiline_output_matching - Attribu... FAILED test_answers_and_docs.py::test_issue_52_answer - AttributeError: 'Cons... FAILED test_answers_and_docs.py::test_issue_51_answer - AttributeError: 'Cons... FAILED test_answers_and_docs.py::test_issue_50 - AttributeError: 'Constant' o... FAILED test_answers_and_docs.py::test_start_with_set - AttributeError: 'Const... FAILED test_answers_and_docs.py::test_ios_bgp_pers_pars - AttributeError: 'Co... FAILED test_answers_and_docs.py::test_ip_address_parsing - AttributeError: 'C... FAILED test_answers_and_docs.py::test_vlans_parsing - AttributeError: 'Consta... FAILED test_answers_and_docs.py::test_asa_acls_issue_55_uses_itemize_with_dynamic_path FAILED test_answers_and_docs.py::test_asa_acls_issue_55 - AttributeError: 'Co... FAILED test_answers_and_docs.py::test_issue_57_headers_parsing - AttributeErr... FAILED test_answers_and_docs.py::test_issue_57_headers_parsing_using_columns FAILED test_answers_and_docs.py::test_interface_template_not_collecting_all_data_solution FAILED test_answers_and_docs.py::test_interface_template_not_collecting_all_data_reduced FAILED test_answers_and_docs.py::test_issue_61 - AttributeError: 'Constant' o... FAILED test_answers_and_docs.py::test_fortigate_intf_parsing - AttributeError... FAILED test_answers_and_docs.py::test_issue_57_one_more - AttributeError: 'Co... FAILED test_answers_and_docs.py::test_issue_57_one_more_answer - AttributeErr... FAILED test_answers_and_docs.py::test_issue_57_one_more_empty_dict_in_res - A... FAILED test_answers_and_docs.py::test_issue_62 - AttributeError: 'Constant' o... FAILED test_answers_and_docs.py::test_issue_62_fix - AttributeError: 'Constan... FAILED test_answers_and_docs.py::test_lookup_crosstemplates - AttributeError:... FAILED test_answers_and_docs.py::test_answer_hpe_bgp - AttributeError: 'Const... FAILED test_answers_and_docs.py::test_stackoverflow_62421344_python_parse_text FAILED test_answers_and_docs.py::test_same_config_different_contexts - Attrib... FAILED test_answers_and_docs.py::test_to_int_with_dynamic_path_issue_67 - Att... FAILED test_answers_and_docs.py::test_to_int_with_dynamic_path_issue_67_multiptocess_mode FAILED test_answers_and_docs.py::test_issue_69_fix - AttributeError: 'Constan... FAILED test_answers_and_docs.py::test_issue_77 - AttributeError: 'Constant' o... FAILED test_answers_and_docs.py::test_issue_94 - AttributeError: 'Constant' o... FAILED test_answers_and_docs.py::test_issue_94_1 - AttributeError: 'Constant'... FAILED test_answers_and_docs.py::test_issue_89 - AttributeError: 'Constant' o... FAILED test_empty_group_results.py::test_empty_group_results - AttributeError... FAILED test_extend_tag.py::test_extend_tag_from_file - AttributeError: 'Const... FAILED test_extend_tag.py::test_extend_tag_from_file_anonymous - AttributeErr... FAILED test_extend_tag.py::test_extend_tag_from_file_with_template_tag - Attr... FAILED test_extend_tag.py::test_extend_tag_from_file_wrong_path - AttributeEr... FAILED test_extend_tag.py::test_extend_tag_from_ttp_templates - AttributeErro... FAILED test_extend_tag.py::test_extend_tag_from_file_vars_and_lookup - Attrib... FAILED test_extend_tag.py::test_extend_tag_within_group - AttributeError: 'Co... FAILED test_extend_tag.py::test_extend_tag_within_group_with_child_groups_above FAILED test_extend_tag.py::test_extend_tag_within_group_with_non_hierarch_template FAILED test_extend_tag.py::test_extend_tag_within_group_with_anonymous_group FAILED test_extend_tag.py::test_extend_tag_within_group_with_multiple_groups FAILED test_extend_tag.py::test_extend_tag_from_file_group_name_filter - Attr... FAILED test_extend_tag.py::test_extend_tag_from_file_group_index_filter - Att... FAILED test_extend_tag.py::test_extend_tag_from_file_vars_filter - AttributeE... FAILED test_extend_tag.py::test_extend_tag_from_file_with_vars_inputs_filter FAILED test_extend_tag.py::test_extend_tag_from_file_lookups_filter - Attribu... FAILED test_extend_tag.py::test_extend_tag_from_file_output_filter - Attribut... FAILED test_extend_tag.py::test_extend_tag_from_file_nested_group_filter - At... FAILED test_extend_tag.py::test_extend_tag_groups_recursive_extend_load - Att... FAILED test_extend_tag.py::test_extend_tag_groups_recursive_extend_load_several_top_groups FAILED test_extend_tag.py::test_extend_tag_from_file_with_macro - AttributeEr... FAILED test_extend_tag.py::test_ttp_templates_dir_env_variable_with_extend - ... FAILED test_group_chain_attribute.py::test_group_chain_attribute_list - Attri... FAILED test_group_chain_attribute.py::test_group_chain_attribute_list_multi_func FAILED test_group_chain_attribute.py::test_group_chain_attribute_string_var FAILED test_group_chain_attribute.py::test_group_chain_attribute_string_inline FAILED test_group_functions.py::test_group_validate_function - AttributeError... FAILED test_group_functions.py::test_group_default_referencing_variable_parent_group_no_re_two_inputs FAILED test_group_functions.py::test_group_default_referencing_variable_parent_group_no_re_one_input FAILED test_group_functions.py::test_top_group_default_referencing_variable_dictionary FAILED test_group_functions.py::test_group_default - AttributeError: 'Constan... FAILED test_group_functions.py::test_child_group_default_referencing_variable FAILED test_group_functions.py::test_group_set_function_source_from_global_vars FAILED test_group_functions.py::test_group_macro_returns_false - AttributeErr... FAILED test_group_functions.py::test_group_macro_returns_true - AttributeErro... FAILED test_group_functions.py::test_group_macro_returns_none - AttributeErro... FAILED test_group_functions.py::test_group_macro_chaining - AttributeError: '... FAILED test_group_functions.py::test_group_macro_chaining_returns_dictionary FAILED test_group_functions.py::test_itemize - AttributeError: 'Constant' obj... FAILED test_group_functions.py::test_itemize_dynamic_path - AttributeError: '... FAILED test_group_functions.py::test_itemize_dynamic_path_attribute - Attribu... FAILED test_group_functions.py::test_items2dict_function - AttributeError: 'C... FAILED test_group_functions.py::test_expand - AttributeError: 'Constant' obje... FAILED test_group_functions.py::test_expand_issue_65 - AttributeError: 'Const... FAILED test_group_functions.py::test_group_to_int_for_non_integer - Attribute... FAILED test_group_functions.py::test_group_to_int_missing_key_issue_109 - Att... FAILED test_group_functions.py::test_group_to_int_with_intlist_true_issue_109 FAILED test_group_functions.py::test_group_to_int_with_intlist_false_issue_109 FAILED test_group_lookup.py::test_group_lookup_using_lookup_table_action_replace FAILED test_group_lookup.py::test_group_lookup_using_lookup_table_action_add_field FAILED test_group_lookup.py::test_group_lookup_using_lookup_table_action_update FAILED test_group_lookup.py::test_group_lookup_using_group_in_same_input_action_update FAILED test_group_lookup.py::test_group_lookup_using_group_from_another_input_action_update FAILED test_group_lookup.py::test_group_lookup_in_template_results_per_input_action_update FAILED test_group_lookup.py::test_group_lookup_in_template_results_per_template_action_add_field FAILED test_group_name_attribute.py::test_group_same_null_path_for_several_groups FAILED test_headers_indicator.py::test_headers_indicator_left_aligned - Attri... FAILED test_headers_indicator.py::test_headers_indicator_space_indented_header FAILED test_headers_indicator.py::test_headers_indicator_multiline_header - A... FAILED test_headers_indicator.py::test_headers_indicator_columns_merged - Att... FAILED test_headers_indicator.py::test_headers_indicator_tab_indented_header FAILED test_headers_indicator.py::test_headers_docs_example - AttributeError:... FAILED test_headers_indicator.py::test_headers_shorter_lines - AttributeError... FAILED test_headers_indicator.py::test_headers_last_column_empty - AttributeE... FAILED test_headers_indicator.py::test_with_garbage - AttributeError: 'Consta... FAILED test_headers_indicator.py::test_headers_with_column - AttributeError: ... FAILED test_headers_indicator.py::test_headers_on_tabular_output - AttributeE... FAILED test_line_indicator.py::test_line_when_its_start_re - AttributeError: ... FAILED test_lookups.py::test_lookup_include_csv - AttributeError: 'Constant' ... FAILED test_lookups.py::test_lookup_include_yaml - AttributeError: 'Constant'... FAILED test_match_condition_fun.py::test_contains_re_inline - AttributeError:... FAILED test_match_condition_fun.py::test_contains_re_from_vars - AttributeErr... FAILED test_match_condition_fun.py::test_startswith_re_inline - AttributeErro... FAILED test_match_condition_fun.py::test_startswith_re_from_vars - AttributeE... FAILED test_match_condition_fun.py::test_endswith_re_inline - AttributeError:... FAILED test_match_condition_fun.py::test_endswith_re_from_vars - AttributeErr... FAILED test_match_condition_fun.py::test_notstartswith_re_inline - AttributeE... FAILED test_match_condition_fun.py::test_notstartswith_re_from_vars - Attribu... FAILED test_match_condition_fun.py::test_notendswith_re_inline - AttributeErr... FAILED test_match_condition_fun.py::test_notendswith_re_from_vars - Attribute... FAILED test_match_condition_fun.py::test_exclude_re_inline - AttributeError: ... FAILED test_match_condition_fun.py::test_exclude_re_from_vars - AttributeErro... FAILED test_match_condition_fun.py::test_exclude_inline - AttributeError: 'Co... FAILED test_match_condition_fun.py::test_exclude_from_vars - AttributeError: ... FAILED test_match_condition_fun.py::test_contains_inline - AttributeError: 'C... FAILED test_match_condition_fun.py::test_contains_from_vars - AttributeError:... FAILED test_match_condition_fun.py::test_contains_multi - AttributeError: 'Co... FAILED test_match_condition_fun.py::test_equal_inline - AttributeError: 'Cons... FAILED test_match_condition_fun.py::test_equal_from_vars - AttributeError: 'C... FAILED test_match_condition_fun.py::test_notequal_inline - AttributeError: 'C... FAILED test_match_condition_fun.py::test_notequal_from_vars - AttributeError:... FAILED test_match_functions.py::test_sformat_inline - AttributeError: 'Consta... FAILED test_match_functions.py::test_sformat_from_vars - AttributeError: 'Con... FAILED test_match_functions.py::test_to_list_with_joinmatches - AttributeErro... FAILED test_match_functions.py::test_multiple_joinmatches - AttributeError: '... FAILED test_match_functions.py::test_joinmatches_with_ignore - AttributeError... FAILED test_match_functions.py::test_match_variable_default_set_to_list - Att... FAILED test_match_functions.py::test_match_variable_default_set_to_string - A... FAILED test_match_functions.py::test_match_variable_default_for_start_regex FAILED test_match_functions.py::test_match_variable_default_set_to_dictionary FAILED test_match_functions.py::test_match_variable_set_and_let_for_same_variable_with_special_chars FAILED test_match_functions.py::test_let_and_set - AttributeError: 'Constant'... FAILED test_match_functions.py::test_line_with_joinmatches - AttributeError: ... FAILED test_match_functions.py::test_raise - AttributeError: 'Constant' objec... FAILED test_match_functions.py::test_copy - AttributeError: 'Constant' object... FAILED test_misc.py::test_match_vars_with_hyphen - AttributeError: 'Constant'... FAILED test_misc.py::test_match_vars_with_dot - AttributeError: 'Constant' ob... FAILED test_misc.py::test_match_vars_starts_with_digit - AttributeError: 'Con... FAILED test_misc.py::test_match_vars_multiple_non_alpha_chars - AttributeErro... FAILED test_misc.py::test_match_vars_set_with_hyphen - AttributeError: 'Const... FAILED test_misc.py::test_per_template_mode - AttributeError: 'Constant' obje... FAILED test_misc.py::test_newline_with_carriage_return - AttributeError: 'Con... FAILED test_misc.py::test_groups_with_defaults_only_and_with_children_with_defaults_only FAILED test_misc.py::test_hierarch_template - AttributeError: 'Constant' obje... FAILED test_misc.py::test_comments_with_indentation - AttributeError: 'Consta... FAILED test_misc.py::test_TTP_CACHE_FOLDER_env_variable_usage - AttributeErro... FAILED test_misc.py::test_child_group_do_not_start_if_no_parent_started - Att... FAILED test_misc.py::test_group_end_indicator_when_last_start_is_bigger_than_last_end FAILED test_misc.py::test_tabs_and_spaces_mixed_within_line - AttributeError:... FAILED test_misc.py::test_inner_group_strange_parsing_results - AttributeErro... FAILED test_misc.py::test_in_threads_parsing - AttributeError: 'Constant' obj... FAILED test_misc.py::test_ttp_templates_dir_env_variable - AttributeError: 'C... FAILED test_misc.py::test_nested_group_processing_order - AttributeError: 'Co... FAILED test_misc.py::test_asterisk_issue_97 - AttributeError: 'Constant' obje... FAILED test_misc.py::test_issue_98_special_char_in_match_path - AttributeErro... FAILED test_misc.py::test_tail_match_no_group_functions_processing - Attribut... FAILED test_misc.py::test_issue_95 - AttributeError: 'Constant' object has no... FAILED test_output_formatters.py::test_csv_formatter_simple - AttributeError:... FAILED test_output_formatters.py::test_csv_formatter_simple_empty_tag - Attri... FAILED test_output_formatters.py::test_csv_formatter_with_is_equal - Attribut... FAILED test_output_formatters.py::test_excel_formatter - AttributeError: 'Con... FAILED test_output_formatters.py::test_excel_formatter_file_returner_incomplete_url FAILED test_output_formatters.py::test_excel_formatter_update - FileNotFoundE... FAILED test_output_formatters.py::test_excel_formatter_update_using_result_kwargs FAILED test_output_formatters.py::test_excel_formatter_no_results_at_path_strict_false FAILED test_output_formatters.py::test_excel_formatter_no_results_at_path_strict_true FAILED test_output_formatters.py::test_tabulate_formatter - AttributeError: '... FAILED test_output_formatters.py::test_table_formatter - AttributeError: 'Con... FAILED test_output_formatters.py::test_table_formatter_with_key - AttributeEr... FAILED test_output_formatters.py::test_table_formatter_multiple_input - Attri... FAILED test_output_formatters.py::test_jinja2_formatter - AttributeError: 'Co... FAILED test_output_functions.py::test_cerberus_validate_per_input - Attribute... FAILED test_output_functions.py::test_cerberus_validate_per_template - Attrib... FAILED test_output_functions.py::test_global_output_deepdiff_with_var_before FAILED test_output_functions.py::test_group_specific_output_deepdiff_with_var_before FAILED test_output_functions.py::test_group_specific_output_deepdiff_with_var_before_with_add_field FAILED test_output_functions.py::test_output_condition_attribute - AttributeE... FAILED test_output_returners.py::test_file_returner_format_raw - AttributeErr... FAILED test_output_returners.py::test_file_returner_format_raw_incomplete_url FAILED test_output_returners.py::test_file_returner_format_raw_1 - AttributeE... FAILED test_output_returners.py::test_file_returner_filename_format - Attribu... FAILED test_output_returners.py::test_file_returner_filename_format_group_specific_output FAILED test_regexes.py::test_pipe_separated_regexes - AttributeError: 'Consta... FAILED test_regexes.py::test_multiple_inline_regexes - AttributeError: 'Const... FAILED test_regexes.py::test_MAC_regex_formatter - AttributeError: 'Constant'... FAILED test_structure.py::test_list_structure - AttributeError: 'Constant' ob... FAILED test_structure.py::test_list_structure_with_outputter - AttributeError... FAILED test_structure.py::test_dictionary_structure - AttributeError: 'Consta... FAILED test_structure.py::test_dictionary_structure_with_outputter - Attribut... FAILED test_structure.py::test_flat_list_structure - AttributeError: 'Constan... FAILED test_structure.py::test_flat_list_structure_with_outputter - Attribute... FAILED test_syslog_returner.py::test_syslog_returner - AttributeError: 'Const... FAILED test_template_variables.py::test_include_attribute_with_yaml_loader - ... FAILED test_template_variables.py::test_sros_gethostname_getter - AttributeEr... FAILED test_ttp_parser_methods.py::test_clear_result_all - AttributeError: 'C... FAILED test_ttp_parser_methods.py::test_clear_result_by_name - AttributeError... FAILED test_ttp_parser_methods.py::test_add_input_with_default_options - Attr... FAILED test_ttp_parser_methods.py::test_add_input_to_non_existing_template - ... FAILED test_ttp_parser_methods.py::test_add_input_to_non_default_root_template FAILED test_ttp_parser_methods.py::test_add_inputs_to_child_templates_default_input FAILED test_ttp_parser_methods.py::test_add_inputs_to_child_templates_non_default_input FAILED test_ttp_parser_methods.py::test_set_input_for_child_template - Attrib... FAILED test_ttp_parser_methods.py::test_add_template - AttributeError: 'Const... FAILED test_ttp_parser_methods.py::test_get_input_load_default_template - Att... FAILED test_ttp_parser_methods.py::test_get_input_load_child_templates - Attr... FAILED test_ttp_parser_methods.py::test_default_behaviour_with_named_templates FAILED test_ttp_parser_methods.py::test_add_function_method_match_var - Attri... FAILED test_ttp_parser_methods.py::test_add_function_method_match_var_multiproc FAILED test_ttp_parser_methods.py::test_add_function_method_group - Attribute... FAILED test_ttp_parser_methods.py::test_add_function_method_input - Attribute... FAILED test_ttp_parser_methods.py::test_add_function_method_output - Attribut... FAILED test_ttp_parser_methods.py::test_add_function_method_output_returner FAILED test_ttp_parser_methods.py::test_add_function_method_output_formatter FAILED test_ttp_parser_methods.py::test_add_function_method_variable_getter FAILED test_ttp_parser_methods.py::test_add_function_method_macro_match_var FAILED test_ttp_parser_methods.py::test_add_function_method_macro_output - At... FAILED test_ttp_parser_methods.py::test_get_input_load_anonymous_template - A... FAILED test_ttp_parser_methods.py::test_add_function_method_group_globals_injection FAILED test_ttp_parser_methods.py::test_add_input_structured_data_list - Attr... FAILED test_ttp_parser_methods.py::test_loading_template_from_ttp_templates FAILED test_ttp_parser_methods.py::test_quick_parse_function - AttributeError... FAILED test_ttp_parser_methods.py::test_quick_parse_function_with_kwargs - At... FAILED test_ttp_parser_methods.py::test_quick_parse_function_template_only - ... FAILED test_ttp_parser_methods.py::test_get_template_method - AttributeError:... FAILED test_ttp_parser_methods.py::test_get_template_method_nested_templates ========== 266 failed, 3 skipped, 15 deselected, 1 warning in 13.24s =========== error: Bad exit status from /usr/src/tmp/rpmb-tmp.q1b9QU (%check) RPM build errors: Bad exit status from /usr/src/tmp/rpmb-tmp.q1b9QU (%check) Command exited with non-zero status 1 14.09user 1.11system 0:14.67elapsed 103%CPU (0avgtext+0avgdata 145584maxresident)k 0inputs+0outputs (0major+257415minor)pagefaults 0swaps hsh-rebuild: rebuild of `python3-module-ttp-0.9.5-alt2.src.rpm' failed. Command exited with non-zero status 1 3.17user 1.01system 0:23.37elapsed 17%CPU (0avgtext+0avgdata 145604maxresident)k 11504inputs+0outputs (0major+338327minor)pagefaults 0swaps