All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 1/9] packagegroup-meta-python: add poetry-core and unattended-upgrade
@ 2022-03-10 13:25 Ross Burton
  2022-03-10 13:25 ` [PATCH 2/9] python3-pystache: remove, unmaintained Ross Burton
                   ` (7 more replies)
  0 siblings, 8 replies; 9+ messages in thread
From: Ross Burton @ 2022-03-10 13:25 UTC (permalink / raw)
  To: openembedded-devel

These were missing from the packagegroup.

Signed-off-by: Ross Burton <ross.burton@arm.com>
---
 .../recipes-core/packagegroups/packagegroup-meta-python.bb      | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/meta-python/recipes-core/packagegroups/packagegroup-meta-python.bb b/meta-python/recipes-core/packagegroups/packagegroup-meta-python.bb
index 9626231bba..86bf6db30b 100644
--- a/meta-python/recipes-core/packagegroups/packagegroup-meta-python.bb
+++ b/meta-python/recipes-core/packagegroups/packagegroup-meta-python.bb
@@ -280,6 +280,7 @@ RDEPENDS:packagegroup-meta-python3 = "\
     python3-pkcs11 \
     python3-pkgconfig \
     python3-ply \
+    python3-poetry-core \
     python3-pocketsphinx \
     python3-polyline \
     python3-portalocker \
@@ -475,6 +476,7 @@ RDEPENDS:packagegroup-meta-python3 = "\
     python3-yarl \
     python3-zopeinterface \
     telepathy-python3 \
+    unattended-upgrades \
 "
 RDEPENDS:packagegroup-meta-python3:remove:libc-musl:powerpc64le = "python3-grpcio python3-grpcio-tools"
 
-- 
2.25.1



^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH 2/9] python3-pystache: remove, unmaintained
  2022-03-10 13:25 [PATCH 1/9] packagegroup-meta-python: add poetry-core and unattended-upgrade Ross Burton
@ 2022-03-10 13:25 ` Ross Burton
  2022-03-10 13:25 ` [PATCH 3/9] python3-configparser: remove, not needed for Python 3 Ross Burton
                   ` (6 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Ross Burton @ 2022-03-10 13:25 UTC (permalink / raw)
  To: openembedded-devel

Pystache hasn't been maintained since 2014.  One maintained alternative
is https://github.com/noahmorrison/chevron.

Signed-off-by: Ross Burton <ross.burton@arm.com>
---
 .../packagegroups/packagegroup-meta-python.bb |    1 -
 ...-versions-remove-py2x-and-fix-tests-.patch | 4150 -----------------
 .../python/python3-pystache_0.5.4.bb          |   17 -
 3 files changed, 4168 deletions(-)
 delete mode 100644 meta-python/recipes-devtools/python/python3-pystache/0001-Modernize-python-versions-remove-py2x-and-fix-tests-.patch
 delete mode 100644 meta-python/recipes-devtools/python/python3-pystache_0.5.4.bb

diff --git a/meta-python/recipes-core/packagegroups/packagegroup-meta-python.bb b/meta-python/recipes-core/packagegroups/packagegroup-meta-python.bb
index 86bf6db30b..ae454e789b 100644
--- a/meta-python/recipes-core/packagegroups/packagegroup-meta-python.bb
+++ b/meta-python/recipes-core/packagegroups/packagegroup-meta-python.bb
@@ -347,7 +347,6 @@ RDEPENDS:packagegroup-meta-python3 = "\
     python3-pyserial \
     python3-pysocks \
     python3-pysonos \
-    python3-pystache \
     python3-pystemd \
     python3-pytest-asyncio \
     python3-pytest-benchmark \
diff --git a/meta-python/recipes-devtools/python/python3-pystache/0001-Modernize-python-versions-remove-py2x-and-fix-tests-.patch b/meta-python/recipes-devtools/python/python3-pystache/0001-Modernize-python-versions-remove-py2x-and-fix-tests-.patch
deleted file mode 100644
index d268cc5cd9..0000000000
--- a/meta-python/recipes-devtools/python/python3-pystache/0001-Modernize-python-versions-remove-py2x-and-fix-tests-.patch
+++ /dev/null
@@ -1,4150 +0,0 @@
-From 8bb1ac2d81f697598a766714f2c439d78c85d71e Mon Sep 17 00:00:00 2001
-From: Stephen L Arnold <nerdboy@gentoo.org>
-Date: Sat, 7 Nov 2020 12:38:33 -0800
-Subject: [PATCH] Modernize python versions (remove py2x) and fix tests, update
- spec
-
-* migrate to github actions for CI, add conda recipe/workflow
-* fix document processing, update pandoc args and history
-* convert doctests and modules to py3
-* convert packaging/setup.py to pep517, keep doc processing
-* cleanup tox cfg, add coverage, readme status
-* add pep8speaks cfg, cleanup warnings, use correct env
-* update setup_description.rst for packaging
-* set version for test release => 0.6.0 and deploy
-
-Upstream-Status: Backport [https://github.com/defunkt/pystache/pull/214]
-Signed-off-by: Stephen L Arnold <nerdboy@gentoo.org>
----
- .coveragerc                               |  38 +++
- .gitchangelog.rc                          | 295 +++++++++++++++++++++
- .github/workflows/ci.yml                  |  73 ++++++
- .github/workflows/conda.yml               |  55 ++++
- .github/workflows/release.yml             |  94 +++++++
- .github/workflows/wheels.yml              |  82 ++++++
- .pep8speaks.yml                           |  15 ++
- HISTORY.md                                |  37 ++-
- MANIFEST.in                               |   8 +-
- README.md                                 | 141 +++++-----
- TODO.md                                   |   5 +-
- conda/meta.yaml                           |  50 ++++
- pyproject.toml                            |   3 +
- pystache/__init__.py                      |   2 +-
- pystache/commands/render.py               |   4 +-
- pystache/common.py                        |  13 +-
- pystache/defaults.py                      |   2 +-
- pystache/loader.py                        |  14 +-
- pystache/parsed.py                        |   6 +-
- pystache/parser.py                        |  20 +-
- pystache/renderengine.py                  |   2 +-
- pystache/renderer.py                      |  22 +-
- pystache/specloader.py                    |   2 +-
- pystache/tests/benchmark.py               |  15 +-
- pystache/tests/common.py                  |  10 +-
- pystache/tests/examples/unicode_output.py |   2 +-
- pystache/tests/main.py                    |  28 +-
- pystache/tests/spectesting.py             |  16 +-
- pystache/tests/test___init__.py           |   4 +-
- pystache/tests/test_commands.py           |   2 +-
- pystache/tests/test_defaults.py           |  18 +-
- pystache/tests/test_examples.py           |  40 +--
- pystache/tests/test_loader.py             |  46 ++--
- pystache/tests/test_pystache.py           |   6 +-
- pystache/tests/test_renderengine.py       | 148 +++++------
- pystache/tests/test_renderer.py           |  86 +++----
- pystache/tests/test_simple.py             |  20 +-
- pystache/tests/test_specloader.py         |  60 ++---
- setup.cfg                                 |  74 +++++-
- setup.py                                  | 134 +---------
- setup_description.rst                     | 297 +++++++++++++---------
- tox.ini                                   | 118 +++++++--
- travis.yml_disabled                       |  52 ++++
- 43 files changed, 1487 insertions(+), 672 deletions(-)
- create mode 100644 .coveragerc
- create mode 100644 .gitchangelog.rc
- create mode 100644 .github/workflows/ci.yml
- create mode 100644 .github/workflows/conda.yml
- create mode 100644 .github/workflows/release.yml
- create mode 100644 .github/workflows/wheels.yml
- create mode 100644 .pep8speaks.yml
- create mode 100644 conda/meta.yaml
- create mode 100644 pyproject.toml
- create mode 100644 travis.yml_disabled
-
-diff --git a/.coveragerc b/.coveragerc
-new file mode 100644
-index 0000000..9a336dd
---- /dev/null
-+++ b/.coveragerc
-@@ -0,0 +1,38 @@
-+# .coveragerc to control coverage.py
-+[run]
-+branch = True
-+
-+source = pystache
-+
-+omit =
-+    .tox/*
-+    setup.py
-+    pystache/tests/*
-+
-+#plugins =
-+#    coverage_python_version
-+
-+[report]
-+# must set this to True to see missing
-+#show_missing = True
-+
-+# Regexes for lines to exclude from consideration
-+exclude_lines =
-+    # Have to re-enable the standard pragma
-+    pragma: no cover
-+
-+    # Don't complain about missing debug-only code:
-+    def __repr__
-+    if self\.debug
-+
-+    # Don't complain if tests don't hit defensive assertion code:
-+    raise AssertionError
-+    raise NotImplementedError
-+
-+    # Don't complain if non-runnable code isn't run:
-+    if 0:
-+
-+ignore_errors = True
-+
-+[html]
-+directory = cover
-diff --git a/.gitchangelog.rc b/.gitchangelog.rc
-new file mode 100644
-index 0000000..5cf63a0
---- /dev/null
-+++ b/.gitchangelog.rc
-@@ -0,0 +1,295 @@
-+# -*- coding: utf-8; mode: python -*-
-+##
-+## Format
-+##
-+##   ACTION: [AUDIENCE:] COMMIT_MSG [!TAG ...]
-+##
-+## Description
-+##
-+##   ACTION is one of 'chg', 'fix', 'new'
-+##
-+##       Is WHAT the change is about.
-+##
-+##       'chg' is for refactor, small improvement, cosmetic changes...
-+##       'fix' is for bug fixes
-+##       'new' is for new features, big improvement
-+##
-+##   AUDIENCE is optional and one of 'dev', 'usr', 'pkg', 'test', 'doc'
-+##
-+##       Is WHO is concerned by the change.
-+##
-+##       'dev'  is for developpers (API changes, refactors...)
-+##       'usr'  is for final users (UI changes)
-+##       'pkg'  is for packagers   (packaging changes)
-+##       'test' is for testers     (test only related changes)
-+##       'doc'  is for doc guys    (doc only changes)
-+##
-+##   COMMIT_MSG is ... well ... the commit message itself.
-+##
-+##   TAGs are additionnal adjective as 'refactor' 'minor' 'cosmetic'
-+##
-+##       They are preceded with a '!' or a '@' (prefer the former, as the
-+##       latter is wrongly interpreted in github.) Commonly used tags are:
-+##
-+##       'refactor' is obviously for refactoring code only
-+##       'minor' is for a very meaningless change (a typo, adding a comment)
-+##       'cosmetic' is for cosmetic driven change (re-indentation, 80-col...)
-+##       'wip' is for partial functionality but complete subfunctionality.
-+##
-+## Example:
-+##
-+##   new: usr: support of bazaar implemented
-+##   chg: re-indentend some lines !cosmetic
-+##   new: dev: updated code to be compatible with last version of killer lib.
-+##   fix: pkg: updated year of licence coverage.
-+##   new: test: added a bunch of test around user usability of feature X.
-+##   fix: typo in spelling my name in comment. !minor
-+##
-+##   Please note that multi-line commit message are supported, and only the
-+##   first line will be considered as the "summary" of the commit message. So
-+##   tags, and other rules only applies to the summary.  The body of the commit
-+##   message will be displayed in the changelog without reformatting.
-+
-+
-+##
-+## ``ignore_regexps`` is a line of regexps
-+##
-+## Any commit having its full commit message matching any regexp listed here
-+## will be ignored and won't be reported in the changelog.
-+##
-+ignore_regexps = [
-+    r'@minor', r'!minor',
-+    r'@cosmetic', r'!cosmetic',
-+    r'@refactor', r'!refactor',
-+    r'@wip', r'!wip',
-+    r'^([cC]hg|[fF]ix|[nN]ew)\s*:\s*[p|P]kg:',
-+    r'^([cC]hg|[fF]ix|[nN]ew)\s*:\s*[d|D]ev:',
-+    r'^(.{3,3}\s*:)?\s*[fF]irst commit.?\s*$',
-+    r'^$',  ## ignore commits with empty messages
-+]
-+
-+
-+## ``section_regexps`` is a list of 2-tuples associating a string label and a
-+## list of regexp
-+##
-+## Commit messages will be classified in sections thanks to this. Section
-+## titles are the label, and a commit is classified under this section if any
-+## of the regexps associated is matching.
-+##
-+## Please note that ``section_regexps`` will only classify commits and won't
-+## make any changes to the contents. So you'll probably want to go check
-+## ``subject_process`` (or ``body_process``) to do some changes to the subject,
-+## whenever you are tweaking this variable.
-+##
-+section_regexps = [
-+    ('New', [
-+        r'^[nN]ew\s*:\s*((dev|use?r|pkg|test|doc)\s*:\s*)?([^\n]*)$',
-+     ]),
-+    ('Features', [
-+       r'^([nN]ew|[fF]eat)\s*:\s*((dev|use?r|pkg|test|doc)\s*:\s*)?([^\n]*)$',
-+     ]),
-+    ('Changes', [
-+        r'^[cC]hg\s*:\s*((dev|use?r|pkg|test|doc)\s*:\s*)?([^\n]*)$',
-+     ]),
-+    ('Fixes', [
-+        r'^[fF]ix\s*:\s*((dev|use?r|pkg|test|doc)\s*:\s*)?([^\n]*)$',
-+     ]),
-+
-+    ('Other', None ## Match all lines
-+     ),
-+]
-+
-+
-+## ``body_process`` is a callable
-+##
-+## This callable will be given the original body and result will
-+## be used in the changelog.
-+##
-+## Available constructs are:
-+##
-+##   - any python callable that take one txt argument and return txt argument.
-+##
-+##   - ReSub(pattern, replacement): will apply regexp substitution.
-+##
-+##   - Indent(chars="  "): will indent the text with the prefix
-+##     Please remember that template engines gets also to modify the text and
-+##     will usually indent themselves the text if needed.
-+##
-+##   - Wrap(regexp=r"\n\n"): re-wrap text in separate paragraph to fill 80-Columns
-+##
-+##   - noop: do nothing
-+##
-+##   - ucfirst: ensure the first letter is uppercase.
-+##     (usually used in the ``subject_process`` pipeline)
-+##
-+##   - final_dot: ensure text finishes with a dot
-+##     (usually used in the ``subject_process`` pipeline)
-+##
-+##   - strip: remove any spaces before or after the content of the string
-+##
-+##   - SetIfEmpty(msg="No commit message."): will set the text to
-+##     whatever given ``msg`` if the current text is empty.
-+##
-+## Additionally, you can `pipe` the provided filters, for instance:
-+#body_process = Wrap(regexp=r'\n(?=\w+\s*:)') | Indent(chars="  ")
-+#body_process = Wrap(regexp=r'\n(?=\w+\s*:)')
-+#body_process = noop
-+body_process = ReSub(r'((^|\n)[A-Z]\w+(-\w+)*: .*(\n\s+.*)*)+$', r'') | strip
-+
-+
-+## ``subject_process`` is a callable
-+##
-+## This callable will be given the original subject and result will
-+## be used in the changelog.
-+##
-+## Available constructs are those listed in ``body_process`` doc.
-+subject_process = (strip |
-+    ReSub(r'^([cC]hg|[fF]ix|[nN]ew)\s*:\s*((dev|use?r|pkg|test|doc)\s*:\s*)?([^\n@]*)(@[a-z]+\s+)*$', r'\4') |
-+    SetIfEmpty("No commit message.") | ucfirst | final_dot)
-+
-+
-+## ``tag_filter_regexp`` is a regexp
-+##
-+## Tags that will be used for the changelog must match this regexp.
-+##
-+#tag_filter_regexp = r'^v?[0-9]+\.[0-9]+(\.[0-9]+)?$'
-+tag_filter_regexp = r'^[0-9]+\.[0-9]+(\.[0-9]+)?$'
-+
-+
-+## ``unreleased_version_label`` is a string or a callable that outputs a string
-+##
-+## This label will be used as the changelog Title of the last set of changes
-+## between last valid tag and HEAD if any.
-+unreleased_version_label = "(unreleased)"
-+#unreleased_version_label = lambda: swrap(
-+#    ["git", "describe", "--tags"],
-+#shell=False)
-+
-+
-+## ``output_engine`` is a callable
-+##
-+## This will change the output format of the generated changelog file
-+##
-+## Available choices are:
-+##
-+##   - rest_py
-+##
-+##        Legacy pure python engine, outputs ReSTructured text.
-+##        This is the default.
-+##
-+##   - mustache(<template_name>)
-+##
-+##        Template name could be any of the available templates in
-+##        ``templates/mustache/*.tpl``.
-+##        Requires python package ``pystache``.
-+##        Examples:
-+##           - mustache("markdown")
-+##           - mustache("restructuredtext")
-+##
-+##   - makotemplate(<template_name>)
-+##
-+##        Template name could be any of the available templates in
-+##        ``templates/mako/*.tpl``.
-+##        Requires python package ``mako``.
-+##        Examples:
-+##           - makotemplate("restructuredtext")
-+##
-+#output_engine = rest_py
-+#output_engine = mustache("restructuredtext")
-+output_engine = mustache("markdown")
-+#output_engine = makotemplate("restructuredtext")
-+
-+
-+## ``include_merge`` is a boolean
-+##
-+## This option tells git-log whether to include merge commits in the log.
-+## The default is to include them.
-+include_merge = True
-+
-+
-+## ``log_encoding`` is a string identifier
-+##
-+## This option tells gitchangelog what encoding is outputed by ``git log``.
-+## The default is to be clever about it: it checks ``git config`` for
-+## ``i18n.logOutputEncoding``, and if not found will default to git's own
-+## default: ``utf-8``.
-+#log_encoding = 'utf-8'
-+
-+
-+## ``publish`` is a callable
-+##
-+## Sets what ``gitchangelog`` should do with the output generated by
-+## the output engine. ``publish`` is a callable taking one argument
-+## that is an interator on lines from the output engine.
-+##
-+## Some helper callable are provided:
-+##
-+## Available choices are:
-+##
-+##   - stdout
-+##
-+##        Outputs directly to standard output
-+##        (This is the default)
-+##
-+##   - FileInsertAtFirstRegexMatch(file, pattern, idx=lamda m: m.start(), flags)
-+##
-+##        Creates a callable that will parse given file for the given
-+##        regex pattern and will insert the output in the file.
-+##        ``idx`` is a callable that receive the matching object and
-+##        must return a integer index point where to insert the
-+##        the output in the file. Default is to return the position of
-+##        the start of the matched string.
-+##
-+##   - FileRegexSubst(file, pattern, replace, flags)
-+##
-+##        Apply a replace inplace in the given file. Your regex pattern must
-+##        take care of everything and might be more complex. Check the README
-+##        for a complete copy-pastable example.
-+##
-+# publish = FileInsertIntoFirstRegexMatch(
-+#     "CHANGELOG.rst",
-+#     r'/(?P<rev>[0-9]+\.[0-9]+(\.[0-9]+)?)\s+\([0-9]+-[0-9]{2}-[0-9]{2}\)\n--+\n/',
-+#     idx=lambda m: m.start(1)
-+# )
-+#publish = stdout
-+
-+
-+## ``revs`` is a list of callable or a list of string
-+##
-+## callable will be called to resolve as strings and allow dynamical
-+## computation of these. The result will be used as revisions for
-+## gitchangelog (as if directly stated on the command line). This allows
-+## to filter exaclty which commits will be read by gitchangelog.
-+##
-+## To get a full documentation on the format of these strings, please
-+## refer to the ``git rev-list`` arguments. There are many examples.
-+##
-+## Using callables is especially useful, for instance, if you
-+## are using gitchangelog to generate incrementally your changelog.
-+##
-+## Some helpers are provided, you can use them::
-+##
-+##   - FileFirstRegexMatch(file, pattern): will return a callable that will
-+##     return the first string match for the given pattern in the given file.
-+##     If you use named sub-patterns in your regex pattern, it'll output only
-+##     the string matching the regex pattern named "rev".
-+##
-+##   - Caret(rev): will return the rev prefixed by a "^", which is a
-+##     way to remove the given revision and all its ancestor.
-+##
-+## Please note that if you provide a rev-list on the command line, it'll
-+## replace this value (which will then be ignored).
-+##
-+## If empty, then ``gitchangelog`` will act as it had to generate a full
-+## changelog.
-+##
-+## The default is to use all commits to make the changelog.
-+#revs = ["^1.0.3", ]
-+#revs = [
-+#    Caret(
-+#        FileFirstRegexMatch(
-+#            "CHANGELOG.rst",
-+#            r"(?P<rev>[0-9]+\.[0-9]+(\.[0-9]+)?)\s+\([0-9]+-[0-9]{2}-[0-9]{2}\)\n--+\n")),
-+#    "HEAD"
-+#]
-+revs = []
-diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
-new file mode 100644
-index 0000000..356dd2c
---- /dev/null
-+++ b/.github/workflows/ci.yml
-@@ -0,0 +1,73 @@
-+# This workflow will install Python dependencies, run tests and lint with a variety of Python versions
-+# For more information see: https://help.github.com/actions/language-and-framework-guides/using-python-with-github-actions
-+
-+name: ci
-+
-+on:
-+  push:
-+    branches: [ master ]
-+  pull_request:
-+    branches: [ master ]
-+
-+jobs:
-+  build:
-+
-+    runs-on: ${{ matrix.os }}
-+    defaults:
-+      run:
-+        shell: bash
-+    env:
-+      OS: ${{ matrix.os }}
-+      PYTHON: ${{ matrix.python-version }}
-+      PYTHONIOENCODING: utf-8
-+      PIP_DOWNLOAD_CACHE: ${{ github.workspace }}/../.pip_download_cache
-+    strategy:
-+      fail-fast: false
-+      matrix:
-+        os: [ubuntu-20.04, macos-latest, windows-latest]
-+        python-version: [3.6, 3.7, 3.8, 3.9]
-+    steps:
-+    - name: Set git crlf/eol
-+      run: |
-+        git config --global core.autocrlf false
-+        git config --global core.eol lf
-+
-+    - uses: actions/checkout@v2
-+      with:
-+        submodules: True
-+
-+    - name: Set up Python ${{ matrix.python-version }}
-+      uses: actions/setup-python@v2
-+      with:
-+        python-version: ${{ matrix.python-version }}
-+
-+    - name: Install dependencies
-+      run: |
-+        python -m pip install --upgrade pip
-+        pip install tox tox-gh-actions
-+
-+    - name: Run tests with coverage
-+      run: |
-+        tox
-+      env:
-+        PLATFORM: ${{ matrix.os }}
-+
-+    - name: Upload coverage to Codecov
-+      uses: codecov/codecov-action@v1
-+      with:
-+        env_vars: OS,PYTHON
-+
-+    - name: Test with specs and pystache-test
-+      run: |
-+        tox -e setup . ext/spec/specs
-+
-+    - name: Check pkg builds
-+      run: |
-+        tox -e deploy
-+
-+    - name: Check docs
-+      if: runner.os == 'Linux'
-+      run: |
-+        sudo apt-get -qq update
-+        sudo apt-get install -y pandoc
-+        tox -e docs
-diff --git a/.github/workflows/conda.yml b/.github/workflows/conda.yml
-new file mode 100644
-index 0000000..261f9ad
---- /dev/null
-+++ b/.github/workflows/conda.yml
-@@ -0,0 +1,55 @@
-+name: Conda
-+
-+on:
-+  workflow_dispatch:
-+  pull_request:
-+  push:
-+    branches:
-+      - master
-+
-+jobs:
-+  build:
-+    strategy:
-+      fail-fast: false
-+      matrix:
-+        platform: [ubuntu-18.04, windows-latest, macos-latest]
-+        python-version: [3.6, 3.7, 3.8, 3.9]
-+
-+    runs-on: ${{ matrix.platform }}
-+
-+    # The setup-miniconda action needs this to activate miniconda
-+    defaults:
-+      run:
-+        shell: "bash -l {0}"
-+
-+    steps:
-+      - uses: actions/checkout@v2
-+        with:
-+          fetch-depth: 0
-+
-+      - name: Cache conda
-+        uses: actions/cache@v1
-+        with:
-+          path: ~/conda_pkgs_dir
-+          key: ${{matrix.os}}-conda-pkgs-${{hashFiles('**/conda/meta.yaml')}}
-+
-+      - name: Get conda
-+        uses: conda-incubator/setup-miniconda@v2
-+        with:
-+          python-version: ${{ matrix.python-version }}
-+          channels: conda-forge
-+          channel-priority: strict
-+          use-only-tar-bz2: true
-+          auto-activate-base: true
-+
-+      - name: Prepare
-+        run: conda install conda-build conda-verify
-+
-+      - name: Build
-+        run: conda build conda
-+
-+      - name: Install
-+        run: conda install -c ${CONDA_PREFIX}/conda-bld/ pystache
-+
-+      - name: Test
-+        run: python test_pystache.py
-diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
-new file mode 100644
-index 0000000..f33c4b5
---- /dev/null
-+++ b/.github/workflows/release.yml
-@@ -0,0 +1,94 @@
-+name: Release
-+
-+on:
-+  push:
-+    # release on tag push
-+    tags:
-+      - '*'
-+
-+jobs:
-+  wheels:
-+
-+    runs-on: ${{ matrix.os }}
-+    defaults:
-+      run:
-+        shell: bash
-+    env:
-+      PYTHONIOENCODING: utf-8
-+    strategy:
-+      fail-fast: false
-+      matrix:
-+        os: [ubuntu-18.04, macos-latest, windows-latest]
-+        python-version: [3.6, 3.7, 3.8, 3.9]
-+        exclude:
-+          - os: windows-latest
-+            python-version: 2.7
-+
-+    steps:
-+    - name: Set git crlf/eol
-+      run: |
-+        git config --global core.autocrlf false
-+        git config --global core.eol lf
-+
-+    - uses: actions/checkout@v2
-+      with:
-+        fetch-depth: 0
-+
-+    - name: Set up Python ${{ matrix.python-version }}
-+      uses: actions/setup-python@v2
-+      with:
-+        python-version: ${{ matrix.python-version }}
-+
-+    - name: Install dependencies
-+      run: |
-+        python -m pip install --upgrade pip wheel
-+        pip install tox tox-gh-actions
-+
-+    - name: Build dist pkgs
-+      run: |
-+        tox -e deploy
-+
-+    - name: Upload artifacts
-+      if: matrix.python-version == 3.7 && runner.os == 'Linux'
-+      uses: actions/upload-artifact@v2
-+      with:
-+        name: wheels
-+        path: ./dist/*.whl
-+
-+  create_release:
-+    name: Create Release
-+    needs: [wheels]
-+    runs-on: ubuntu-18.04
-+
-+    steps:
-+      - name: Get version
-+        id: get_version
-+        run: |
-+          echo "VERSION=${GITHUB_REF/refs\/tags\//}" >> $GITHUB_ENV
-+          echo ${{ env.VERSION }}
-+
-+      - uses: actions/checkout@v2
-+        with:
-+          fetch-depth: 0
-+
-+      # download all artifacts to project dir
-+      - uses: actions/download-artifact@v2
-+
-+      - name: Generate changes file
-+        uses: sarnold/gitchangelog-action@master
-+        with:
-+          github_token: ${{ secrets.GITHUB_TOKEN}}
-+
-+      - name: Create release
-+        id: create_release
-+        uses: softprops/action-gh-release@v1
-+        env:
-+          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
-+        with:
-+          tag_name: ${{ env.VERSION }}
-+          name: Release v${{ env.VERSION }}
-+          body_path: CHANGES.md
-+          draft: false
-+          prerelease: false
-+          files: |
-+            wheels/pystache*.whl
-diff --git a/.github/workflows/wheels.yml b/.github/workflows/wheels.yml
-new file mode 100644
-index 0000000..58f0c5e
---- /dev/null
-+++ b/.github/workflows/wheels.yml
-@@ -0,0 +1,82 @@
-+name: Wheels
-+
-+on:
-+  workflow_dispatch:
-+  pull_request:
-+  #push:
-+    #branches: [ master ]
-+
-+jobs:
-+  build:
-+
-+    runs-on: ${{ matrix.os }}
-+    defaults:
-+      run:
-+        shell: bash
-+    env:
-+      PYTHONIOENCODING: utf-8
-+    strategy:
-+      fail-fast: false
-+      matrix:
-+        os: [ubuntu-18.04, macos-latest, windows-latest]
-+        python-version: [3.6, 3.7, 3.8, 3.9]
-+
-+    steps:
-+      - name: Set git crlf/eol
-+        run: |
-+          git config --global core.autocrlf false
-+          git config --global core.eol lf
-+
-+      - uses: actions/checkout@v2
-+        with:
-+          fetch-depth: 0
-+
-+      - name: Set up Python ${{ matrix.python-version }}
-+        uses: actions/setup-python@v2
-+        with:
-+          python-version: ${{ matrix.python-version }}
-+
-+      - name: Install dependencies
-+        run: |
-+          python -m pip install --upgrade pip wheel
-+          pip install tox tox-gh-actions
-+
-+      - name: Build dist pkgs
-+        run: |
-+          tox -e deploy
-+
-+      - name: Upload artifacts
-+        if: matrix.python-version == 3.7 && runner.os == 'Linux'
-+        uses: actions/upload-artifact@v2
-+        with:
-+          name: wheels
-+          path: ./dist/*.whl
-+
-+  check_artifact:
-+    name: Check wheel artifact
-+    needs: [build]
-+    runs-on: ${{ matrix.os }}
-+    defaults:
-+      run:
-+        shell: bash
-+    env:
-+      PYTHONIOENCODING: utf-8
-+    strategy:
-+      fail-fast: false
-+      matrix:
-+        os: [ubuntu-18.04, macos-latest, windows-latest]
-+        python-version: [3.6, 3.8, 3.9]
-+
-+    steps:
-+      - name: Set up Python ${{ matrix.python-version }}
-+        uses: actions/setup-python@v2
-+        with:
-+          python-version: ${{ matrix.python-version }}
-+
-+      # download all artifacts to project dir
-+      - uses: actions/download-artifact@v2
-+
-+      - name: Check wheel install
-+        run: |
-+          bash -c 'export WHL=$(ls wheels/*.whl); python -m pip install $WHL'
-+          pystache-test
-diff --git a/.pep8speaks.yml b/.pep8speaks.yml
-new file mode 100644
-index 0000000..e841b66
---- /dev/null
-+++ b/.pep8speaks.yml
-@@ -0,0 +1,15 @@
-+scanner:
-+    linter: flake8  # Other option is pycodestyle
-+
-+no_blank_comment: False  # If True, no comment is made on PR without any errors.
-+descending_issues_order: True  # If True, PEP 8 issues in message will be displayed in descending order of line numbers in the file
-+
-+[flake8]
-+exclude =
-+    .git,
-+    .github,
-+    __pycache__,
-+    build,
-+    dist
-+
-+max-line-length = 110
-diff --git a/HISTORY.md b/HISTORY.md
-index e5b7638..60b6308 100644
---- a/HISTORY.md
-+++ b/HISTORY.md
-@@ -1,7 +1,42 @@
- History
- =======
- 
--**Note:** Official support for Python 2.4 will end with Pystache version 0.6.0.
-+**Note:** Official support for Python 2.7 will end with Pystache version 0.6.0.
-+
-+0.6.0 (2021-03-04)
-+------------------
-+
-+-   Bump spec versions to latest => v1.1.3
-+-   Modernize python and CI tools, update docs/doctests
-+-   Update unicode conversion test for py3-only
-+-   Add pep8speaks cfg, cleanup warnings
-+-   Remove superfluous setup test/unused imports
-+-   Add conda recipe/CI build
-+
-+0.5.6 (2021-02-28)
-+------------------
-+
-+-   Use correct wheel name in release workflow, limit wheels
-+-   Add install check/test of downloaded wheel
-+-   Update/add ci workflows and tox cfg, bump to next dev0 version
-+
-+0.5.5 (2020-12-16)
-+------------------
-+
-+-   fix document processing, update pandoc args and history
-+-   add release.yml to CI, test env settings
-+-   fix bogus commit message, update versions and tox cf
-+-   add post-test steps for building pkgs with/without doc updates
-+-   add CI build check, fix MANIFEST.in pruning
-+
-+0.5.4-2 (2020-11-09)
-+--------------------
-+
-+-   Merge pull request #1 from sarnold/rebase-up
-+-   Bugfix: test_specloader.py: fix test_find__with_directory on other OSs
-+-   Bugfix: pystache/loader.py: remove stray windows line-endings
-+-   fix crufty (and insecure) http urls
-+-   Bugfix: modernize python versions (keep py27) and fix spec_test load cmd
- 
- 0.5.4 (2014-07-11)
- ------------------
-diff --git a/MANIFEST.in b/MANIFEST.in
-index bdc64bf..1593143 100644
---- a/MANIFEST.in
-+++ b/MANIFEST.in
-@@ -1,7 +1,4 @@
--include README.md
--include HISTORY.md
--include LICENSE
--include TODO.md
-+include README.md HISTORY.md TODO.md LICENSE
- include setup_description.rst
- include tox.ini
- include test_pystache.py
-@@ -11,3 +8,6 @@ recursive-include pystache/tests *.mustache *.txt
- # We deliberately exclude the gh/ directory because it contains copies
- # of resources needed only for the web page hosted on GitHub (via the
- # gh-pages branch).
-+exclude *.ini *travis*
-+prune gh
-+prune .git*
-diff --git a/README.md b/README.md
-index 54a9608..1203b7a 100644
---- a/README.md
-+++ b/README.md
-@@ -10,11 +10,25 @@ Pystache
- <!-- -->
- <!-- We leave the leading brackets empty here.  Otherwise, unwanted -->
- <!-- caption text shows up in the reST version converted by pandoc. -->
--![](http://defunkt.github.com/pystache/images/logo_phillips.png "mustachioed, monocled snake by David Phillips")
-+[![ci](https://github.com/sarnold/pystache/actions/workflows/ci.yml/badge.svg)](https://github.com/sarnold/pystache/actions/workflows/ci.yml)
-+[![Conda](https://github.com/sarnold/pystache/actions/workflows/conda.yml/badge.svg)](https://github.com/sarnold/pystache/actions/workflows/conda.yml)
-+[![Wheels](https://github.com/sarnold/pystache/actions/workflows/wheels.yml/badge.svg)](https://github.com/sarnold/pystache/actions/workflows/wheels.yml)
-+[![Release](https://github.com/sarnold/pystache/actions/workflows/release.yml/badge.svg)](https://github.com/sarnold/pystache/actions/workflows/release.yml)
-+[![Python](https://img.shields.io/badge/python-3.6+-blue.svg)](https://www.python.org/downloads/)
- 
--![](https://secure.travis-ci.org/defunkt/pystache.png "Travis CI current build status")
-+[![Latest release](https://img.shields.io/github/v/release/sarnold/pystache?include_prereleases)](https://github.com/sarnold/pystache/releases/latest)
-+[![License](https://img.shields.io/github/license/sarnold/pystache)](https://github.com/sarnold/pystache/blob/master/LICENSE)
-+[![Maintainability](https://api.codeclimate.com/v1/badges/a8fa1bf4638bfc6581b6/maintainability)](https://codeclimate.com/github/sarnold/pystache/maintainability)
-+[![codecov](https://codecov.io/gh/sarnold/pystache/branch/master/graph/badge.svg?token=5PZNMZBI6K)](https://codecov.io/gh/sarnold/pystache)
- 
--[Pystache](http://defunkt.github.com/pystache) is a Python
-+
-+
-+This updated fork of Pystache is currently tested on Python 3.6+ and in
-+Conda, on Linux, Macos, and Windows (Python 2.7 support has been removed).
-+
-+![](gh/images/logo_phillips_small.png "mustachioed, monocled snake by David Phillips")
-+
-+[Pystache](http://sarnold.github.com/pystache) is a Python
- implementation of [Mustache](http://mustache.github.com/). Mustache is a
- framework-agnostic, logic-free templating system inspired by
- [ctemplate](http://code.google.com/p/google-ctemplate/) and
-@@ -27,10 +41,10 @@ provides a good introduction to Mustache's syntax. For a more complete
- (and more current) description of Mustache's behavior, see the official
- [Mustache spec](https://github.com/mustache/spec).
- 
--Pystache is [semantically versioned](http://semver.org) and can be found
--on [PyPI](http://pypi.python.org/pypi/pystache). This version of
--Pystache passes all tests in [version
--1.1.2](https://github.com/mustache/spec/tree/v1.1.2) of the spec.
-+Pystache is [semantically versioned](http://semver.org) and older versions
-+can still be found on [PyPI](http://pypi.python.org/pypi/pystache). This
-+version of Pystache now passes all tests in [version
-+1.1.3](https://github.com/mustache/spec/tree/v1.1.3) of the spec.
- 
- 
- Requirements
-@@ -38,41 +52,25 @@ Requirements
- 
- Pystache is tested with--
- 
---   Python 2.4 (requires simplejson [version
--    2.0.9](http://pypi.python.org/pypi/simplejson/2.0.9) or earlier)
---   Python 2.5 (requires
--    [simplejson](http://pypi.python.org/pypi/simplejson/))
---   Python 2.6
---   Python 2.7
---   Python 3.1
---   Python 3.2
---   Python 3.3
---   [PyPy](http://pypy.org/)
-+-   Python 3.6
-+-   Python 3.7
-+-   Python 3.8
-+-   Python 3.9
-+-   Conda (py36-py39)
- 
- [Distribute](http://packages.python.org/distribute/) (the setuptools fork)
--is recommended over [setuptools](http://pypi.python.org/pypi/setuptools),
--and is required in some cases (e.g. for Python 3 support).
--If you use [pip](http://www.pip-installer.org/), you probably already satisfy
--this requirement.
-+is no longer required over [setuptools](http://pypi.python.org/pypi/setuptools),
-+as the current packaging is now PEP517-compliant.
- 
- JSON support is needed only for the command-line interface and to run
--the spec tests. We require simplejson for earlier versions of Python
--since Python's [json](http://docs.python.org/library/json.html) module
--was added in Python 2.6.
--
--For Python 2.4 we require an earlier version of simplejson since
--simplejson stopped officially supporting Python 2.4 in simplejson
--version 2.1.0. Earlier versions of simplejson can be installed manually,
--as follows:
-+the spec tests; PyYAML can still be used (see the Develop section).
- 
--    pip install 'simplejson<2.1.0'
--
--Official support for Python 2.4 will end with Pystache version 0.6.0.
-+Official support for Python 2 will end with Pystache version 0.6.0.
- 
- Install It
- ----------
- 
--    pip install pystache
-+    pip install -U pystache -f https://github.com/sarnold/pystache/releases/
- 
- And test it--
- 
-@@ -85,12 +83,12 @@ Use It
- ------
- 
-     >>> import pystache
--    >>> print pystache.render('Hi {{person}}!', {'person': 'Mom'})
-+    >>> print(pystache.render('Hi {{person}}!', {'person': 'Mom'}))
-     Hi Mom!
- 
- You can also create dedicated view classes to hold your view logic.
- 
--Here's your view class (in .../examples/readme.py):
-+Here's your view class (in ../pystache/tests/examples/readme.py):
- 
-     class SayHello(object):
-         def to(self):
-@@ -109,7 +107,7 @@ directory as your class definition):
- Pull it together:
- 
-     >>> renderer = pystache.Renderer()
--    >>> print renderer.render(hello)
-+    >>> print(renderer.render(hello))
-     Hello, Pizza!
- 
- For greater control over rendering (e.g. to specify a custom template
-@@ -117,22 +115,22 @@ directory), use the `Renderer` class like above. One can pass attributes
- to the Renderer class constructor or set them on a Renderer instance. To
- customize template loading on a per-view basis, subclass `TemplateSpec`.
- See the docstrings of the
--[Renderer](https://github.com/defunkt/pystache/blob/master/pystache/renderer.py)
-+[Renderer](https://github.com/sarnold/pystache/blob/master/pystache/renderer.py)
- class and
--[TemplateSpec](https://github.com/defunkt/pystache/blob/master/pystache/template_spec.py)
-+[TemplateSpec](https://github.com/sarnold/pystache/blob/master/pystache/template_spec.py)
- class for more information.
- 
- You can also pre-parse a template:
- 
-     >>> parsed = pystache.parse(u"Hey {{#who}}{{.}}!{{/who}}")
--    >>> print parsed
--    [u'Hey ', _SectionNode(key=u'who', index_begin=12, index_end=18, parsed=[_EscapeNode(key=u'.'), u'!'])]
-+    >>> print(parsed)
-+    ['Hey ', _SectionNode(key='who', index_begin=12, index_end=18, parsed=[_EscapeNode(key='.'), '!'])]
- 
- And then:
- 
--    >>> print renderer.render(parsed, {'who': 'Pops'})
-+    >>> print(renderer.render(parsed, {'who': 'Pops'}))
-     Hey Pops!
--    >>> print renderer.render(parsed, {'who': 'you'})
-+    >>> print(renderer.render(parsed, {'who': 'you'}))
-     Hey you!
- 
- Python 3
-@@ -194,15 +192,16 @@ To test from a source distribution (without installing)--
-     python test_pystache.py
- 
- To test Pystache with multiple versions of Python (with a single
--command!), you can use [tox](http://pypi.python.org/pypi/tox):
-+command!) and different platforms, you can use [tox](http://pypi.python.org/pypi/tox):
-+
-+    pip install tox
-+    tox -e setup
- 
--    pip install 'virtualenv<1.8'  # Version 1.8 dropped support for Python 2.4.
--    pip install 'tox<1.4'  # Version 1.4 dropped support for Python 2.4.
--    tox
-+To run tests on multiple versions with coverage, run:
- 
--If you do not have all Python versions listed in `tox.ini`--
-+    tox -e py38-linux,py39-linux  # for example
- 
--    tox -e py26,py32  # for example
-+(substitute your platform above, eg, macos or windows)
- 
- The source distribution tests also include doctests and tests from the
- Mustache spec. To include tests from the Mustache spec in your test
-@@ -217,57 +216,33 @@ parses the json files. To install PyYAML--
- 
-     pip install pyyaml
- 
-+Once the submodule is available, you can run the full test set with:
-+
-+    tox -e setup . ext/spec/specs
-+
- To run a subset of the tests, you can use
- [nose](http://somethingaboutorange.com/mrl/projects/nose/0.11.1/testing.html):
- 
-     pip install nose
-     nosetests --tests pystache/tests/test_context.py:GetValueTests.test_dictionary__key_present
- 
--### Using Python 3 with Pystache from source
--
--Pystache is written in Python 2 and must be converted to Python 3 prior to
--using it with Python 3.  The installation process (and tox) do this
--automatically.
- 
--To convert the code to Python 3 manually (while using Python 3)--
-+Mailing List (old)
-+------------------
- 
--    python setup.py build
--
--This writes the converted code to a subdirectory called `build`.
--By design, Python 3 builds
--[cannot](https://bitbucket.org/tarek/distribute/issue/292/allow-use_2to3-with-python-2)
--be created from Python 2.
--
--To convert the code without using setup.py, you can use
--[2to3](http://docs.python.org/library/2to3.html) as follows (two steps)--
--
--    2to3 --write --nobackups --no-diffs --doctests_only pystache
--    2to3 --write --nobackups --no-diffs pystache
--
--This converts the code (and doctests) in place.
--
--To `import pystache` from a source distribution while using Python 3, be
--sure that you are importing from a directory containing a converted
--version of the code (e.g. from the `build` directory after converting),
--and not from the original (unconverted) source directory.  Otherwise, you will
--get a syntax error.  You can help prevent this by not running the Python
--IDE from the project directory when importing Pystache while using Python 3.
--
--
--Mailing List
--------------
--
--There is a [mailing list](http://librelist.com/browser/pystache/). Note
-+There is(was) a [mailing list](http://librelist.com/browser/pystache/). Note
- that there is a bit of a delay between posting a message and seeing it
- appear in the mailing list archive.
- 
- Credits
- -------
- 
--    >>> context = { 'author': 'Chris Wanstrath', 'maintainer': 'Chris Jerdonek' }
--    >>> print pystache.render("Author: {{author}}\nMaintainer: {{maintainer}}", context)
-+    >>> import pystache
-+    >>> context = { 'author': 'Chris Wanstrath', 'maintainer': 'Chris Jerdonek','refurbisher': 'Steve Arnold' }
-+    >>> print(pystache.render("Author: {{author}}\nMaintainer: {{maintainer}}\nRefurbisher: {{refurbisher}}", context))
-     Author: Chris Wanstrath
-     Maintainer: Chris Jerdonek
-+    Refurbisher: Steve Arnold
- 
- Pystache logo by [David Phillips](http://davidphillips.us/) is licensed
- under a [Creative Commons Attribution-ShareAlike 3.0 Unported
-diff --git a/TODO.md b/TODO.md
-index cd82417..76853a4 100644
---- a/TODO.md
-+++ b/TODO.md
-@@ -6,11 +6,10 @@ In development branch:
- * Figure out a way to suppress center alignment of images in reST output.
- * Add a unit test for the change made in 7ea8e7180c41.  This is with regard
-   to not requiring spec tests when running tests from a downloaded sdist.
--* End support for Python 2.4.
--* Add Python 3.3 to tox file (after deprecating 2.4).
-+* End support for Python 2.7 (done as of 03/03/21 - SA)
-+* Release 0.6.0 on github, make a pypi account (SA)
- * Turn the benchmarking script at pystache/tests/benchmark.py into a command
-   in pystache/commands, or make it a subcommand of one of the existing
-   commands (i.e. using a command argument).
- * Provide support for logging in at least one of the commands.
--* Make sure command parsing to pystache-test doesn't break with Python 2.4 and earlier.
- * Combine pystache-test with the main command.
-diff --git a/conda/meta.yaml b/conda/meta.yaml
-new file mode 100644
-index 0000000..e7f4fd9
---- /dev/null
-+++ b/conda/meta.yaml
-@@ -0,0 +1,50 @@
-+{% set name = "pystache" %}
-+{% set version = "0.6.0.dev0" %}
-+
-+package:
-+  name: {{ name|lower }}
-+  version: {{ version }}
-+
-+source:
-+  path: ..
-+
-+build:
-+  number: 0
-+  script: {{ PYTHON }} -m pip install . --no-deps --ignore-installed -vvv
-+  noarch: python
-+  entry_points:
-+    - pystache = pystache.commands.render:main
-+    - pystache-test = pystache.commands.test:main
-+
-+requirements:
-+  build:
-+    - python
-+    - setuptools
-+
-+  run:
-+    - python
-+
-+test:
-+  imports:
-+    - pystache
-+    - pystache.commands
-+    - pystache.tests
-+    - pystache.tests.data
-+    - pystache.tests.data.locator
-+    - pystache.tests.examples
-+
-+  commands:
-+    - pystache --help
-+    - pystache-test
-+
-+
-+about:
-+  home: https://github.com/sarnold/pystache
-+  license: MIT
-+  license_family: MIT
-+  license_file: LICENSE
-+  summary: Mustache for Python
-+
-+extra:
-+  recipe-maintainers:
-+    - sarnold
-diff --git a/pyproject.toml b/pyproject.toml
-new file mode 100644
-index 0000000..2f21011
---- /dev/null
-+++ b/pyproject.toml
-@@ -0,0 +1,3 @@
-+[build-system]
-+requires = ["setuptools>=40.8.0", "wheel"]
-+build-backend = "setuptools.build_meta"
-diff --git a/pystache/__init__.py b/pystache/__init__.py
-index 4cf2434..5edc1c5 100644
---- a/pystache/__init__.py
-+++ b/pystache/__init__.py
-@@ -10,4 +10,4 @@ from pystache.init import parse, render, Renderer, TemplateSpec
- 
- __all__ = ['parse', 'render', 'Renderer', 'TemplateSpec']
- 
--__version__ = '0.5.4'  # Also change in setup.py.
-+__version__ = '0.6.0'
-diff --git a/pystache/commands/render.py b/pystache/commands/render.py
-index 1a9c309..9c913e7 100644
---- a/pystache/commands/render.py
-+++ b/pystache/commands/render.py
-@@ -22,7 +22,7 @@ except:
-         from sys import exc_info
-         ex_type, ex_value, tb = exc_info()
-         new_ex = Exception("%s: %s" % (ex_type.__name__, ex_value))
--        raise new_ex.__class__, new_ex, tb
-+        raise new_ex.__class__(new_ex).with_traceback(tb)
- 
- # The optparse module is deprecated in Python 2.7 in favor of argparse.
- # However, argparse is not available in Python 2.6 and earlier.
-@@ -88,7 +88,7 @@ def main(sys_argv=sys.argv):
-         context = json.loads(context)
- 
-     rendered = renderer.render(template, context)
--    print rendered
-+    print(rendered)
- 
- 
- if __name__=='__main__':
-diff --git a/pystache/common.py b/pystache/common.py
-index fb266dd..0e9b091 100644
---- a/pystache/common.py
-+++ b/pystache/common.py
-@@ -5,17 +5,12 @@ Exposes functionality needed throughout the project.
- 
- """
- 
--from sys import version_info
- 
- def _get_string_types():
--    # TODO: come up with a better solution for this.  One of the issues here
--    #   is that in Python 3 there is no common base class for unicode strings
--    #   and byte strings, and 2to3 seems to convert all of "str", "unicode",
--    #   and "basestring" to Python 3's "str".
--    if version_info < (3, ):
--         return basestring
--    # The latter evaluates to "bytes" in Python 3 -- even after conversion by 2to3.
--    return (unicode, type(u"a".encode('utf-8')))
-+    """
-+    Return the Python3 string type (no more python2)
-+    """
-+    return (str, type("a".encode('utf-8')))
- 
- 
- _STRING_TYPES = _get_string_types()
-diff --git a/pystache/defaults.py b/pystache/defaults.py
-index bcfdf4c..2fab0e0 100644
---- a/pystache/defaults.py
-+++ b/pystache/defaults.py
-@@ -39,7 +39,7 @@ STRING_ENCODING = sys.getdefaultencoding()
- FILE_ENCODING = sys.getdefaultencoding()
- 
- # The delimiters to start with when parsing.
--DELIMITERS = (u'{{', u'}}')
-+DELIMITERS = ('{{', '}}')
- 
- # How to handle missing tags when rendering a template.
- MISSING_TAGS = MissingTags.ignore
-diff --git a/pystache/loader.py b/pystache/loader.py
-index d4a7e53..ea01d17 100644
---- a/pystache/loader.py
-+++ b/pystache/loader.py
-@@ -6,6 +6,7 @@ This module provides a Loader class for locating and reading templates.
- """
- 
- import os
-+import platform
- import sys
- 
- from pystache import common
-@@ -24,7 +25,7 @@ def _make_to_unicode():
-         """
-         if encoding is None:
-             encoding = defaults.STRING_ENCODING
--        return unicode(s, encoding, defaults.DECODE_ERRORS)
-+        return str(s, encoding, defaults.DECODE_ERRORS)
-     return to_unicode
- 
- 
-@@ -86,7 +87,7 @@ class Loader(object):
-     def _make_locator(self):
-         return Locator(extension=self.extension)
- 
--    def unicode(self, s, encoding=None):
-+    def str(self, s, encoding=None):
-         """
-         Convert a string to unicode using the given encoding, and return it.
- 
-@@ -104,8 +105,8 @@ class Loader(object):
-             Defaults to None.
- 
-         """
--        if isinstance(s, unicode):
--            return unicode(s)
-+        if isinstance(s, str):
-+            return str(s)
- 
-         return self.to_unicode(s, encoding)
- 
-@@ -118,8 +119,9 @@ class Loader(object):
- 
-         if encoding is None:
-             encoding = self.file_encoding
--
--        return self.unicode(b, encoding)
-+        if platform.system() == "Windows":
-+            return self.str(b, encoding).replace('\r', '')
-+        return self.str(b, encoding)
- 
-     def load_file(self, file_name):
-         """
-diff --git a/pystache/parsed.py b/pystache/parsed.py
-index 372d96c..75d417d 100644
---- a/pystache/parsed.py
-+++ b/pystache/parsed.py
-@@ -41,10 +41,10 @@ class ParsedTemplate(object):
-         """
-         # We avoid use of the ternary operator for Python 2.4 support.
-         def get_unicode(node):
--            if type(node) is unicode:
-+            if type(node) is str:
-                 return node
-             return node.render(engine, context)
--        parts = map(get_unicode, self._parse_tree)
-+        parts = list(map(get_unicode, self._parse_tree))
-         s = ''.join(parts)
- 
--        return unicode(s)
-+        return str(s)
-diff --git a/pystache/parser.py b/pystache/parser.py
-index c6a171f..1afd50a 100644
---- a/pystache/parser.py
-+++ b/pystache/parser.py
-@@ -11,8 +11,8 @@ from pystache import defaults
- from pystache.parsed import ParsedTemplate
- 
- 
--END_OF_LINE_CHARACTERS = [u'\r', u'\n']
--NON_BLANK_RE = re.compile(ur'^(.)', re.M)
-+END_OF_LINE_CHARACTERS = ['\r', '\n']
-+NON_BLANK_RE = re.compile(r'^(.)', re.M)
- 
- 
- # TODO: add some unit tests for this.
-@@ -30,12 +30,12 @@ def parse(template, delimiters=None):
- 
-     Examples:
- 
--    >>> parsed = parse(u"Hey {{#who}}{{name}}!{{/who}}")
--    >>> print str(parsed).replace('u', '')  # This is a hack to get the test to pass both in Python 2 and 3.
-+    >>> parsed = parse("Hey {{#who}}{{name}}!{{/who}}")
-+    >>> print(str(parsed).replace('u', ''))  # This is an old hack.
-     ['Hey ', _SectionNode(key='who', index_begin=12, index_end=21, parsed=[_EscapeNode(key='name'), '!'])]
- 
-     """
--    if type(template) is not unicode:
-+    if type(template) is not str:
-         raise Exception("Template is not unicode: %s" % type(template))
-     parser = _Parser(delimiters)
-     return parser.parse(template)
-@@ -94,7 +94,7 @@ class _CommentNode(object):
-         return _format(self)
- 
-     def render(self, engine, context):
--        return u''
-+        return ''
- 
- 
- class _ChangeNode(object):
-@@ -106,7 +106,7 @@ class _ChangeNode(object):
-         return _format(self)
- 
-     def render(self, engine, context):
--        return u''
-+        return ''
- 
- 
- class _EscapeNode(object):
-@@ -147,7 +147,7 @@ class _PartialNode(object):
-     def render(self, engine, context):
-         template = engine.resolve_partial(self.key)
-         # Indent before rendering.
--        template = re.sub(NON_BLANK_RE, self.indent + ur'\1', template)
-+        template = re.sub(NON_BLANK_RE, self.indent + r'\1', template)
- 
-         return engine.render(template, context)
- 
-@@ -168,7 +168,7 @@ class _InvertedNode(object):
-         # Note that lambdas are considered truthy for inverted sections
-         # per the spec.
-         if data:
--            return u''
-+            return ''
-         return self.parsed_section.render(engine, context)
- 
- 
-@@ -218,7 +218,7 @@ class _SectionNode(object):
-             parts.append(self.parsed.render(engine, context))
-             context.pop()
- 
--        return unicode(''.join(parts))
-+        return str(''.join(parts))
- 
- 
- class _Parser(object):
-diff --git a/pystache/renderengine.py b/pystache/renderengine.py
-index c797b17..2f1e341 100644
---- a/pystache/renderengine.py
-+++ b/pystache/renderengine.py
-@@ -160,7 +160,7 @@ class RenderEngine(object):
-         if not is_string(val):
-             # In case the template is an integer, for example.
-             val = self.to_str(val)
--        if type(val) is not unicode:
-+        if type(val) is not str:
-             val = self.literal(val)
-         return self.render(val, context, delimiters)
- 
-diff --git a/pystache/renderer.py b/pystache/renderer.py
-index ff6a90c..064f040 100644
---- a/pystache/renderer.py
-+++ b/pystache/renderer.py
-@@ -32,7 +32,7 @@ class Renderer(object):
-     >>> partials = {'partial': 'Hello, {{thing}}!'}
-     >>> renderer = Renderer(partials=partials)
-     >>> # We apply print to make the test work in Python 3 after 2to3.
--    >>> print renderer.render('{{>partial}}', {'thing': 'world'})
-+    >>> print(renderer.render('{{>partial}}', {'thing': 'world'}))
-     Hello, world!
- 
-     To customize string coercion (e.g. to render False values as ''), one can
-@@ -130,7 +130,7 @@ class Renderer(object):
-         if string_encoding is None:
-             string_encoding = defaults.STRING_ENCODING
- 
--        if isinstance(search_dirs, basestring):
-+        if isinstance(search_dirs, str):
-             search_dirs = [search_dirs]
- 
-         self._context = None
-@@ -177,16 +177,16 @@ class Renderer(object):
-         """
-         # We type-check to avoid "TypeError: decoding Unicode is not supported".
-         # We avoid the Python ternary operator for Python 2.4 support.
--        if isinstance(s, unicode):
-+        if isinstance(s, str):
-             return s
--        return self.unicode(s)
-+        return self.str(s)
- 
-     def _to_unicode_hard(self, s):
-         """
-         Convert a basestring to a string with type unicode (not subclass).
- 
-         """
--        return unicode(self._to_unicode_soft(s))
-+        return str(self._to_unicode_soft(s))
- 
-     def _escape_to_unicode(self, s):
-         """
-@@ -195,9 +195,9 @@ class Renderer(object):
-         Returns a unicode string (not subclass).
- 
-         """
--        return unicode(self.escape(self._to_unicode_soft(s)))
-+        return str(self.escape(self._to_unicode_soft(s)))
- 
--    def unicode(self, b, encoding=None):
-+    def str(self, b, encoding=None):
-         """
-         Convert a byte string to unicode, using string_encoding and decode_errors.
- 
-@@ -222,7 +222,7 @@ class Renderer(object):
- 
-         # TODO: Wrap UnicodeDecodeErrors with a message about setting
-         # the string_encoding and decode_errors attributes.
--        return unicode(b, encoding, self.decode_errors)
-+        return str(b, encoding, self.decode_errors)
- 
-     def _make_loader(self):
-         """
-@@ -230,7 +230,7 @@ class Renderer(object):
- 
-         """
-         return Loader(file_encoding=self.file_encoding, extension=self.file_extension,
--                      to_unicode=self.unicode, search_dirs=self.search_dirs)
-+                      to_unicode=self.str, search_dirs=self.search_dirs)
- 
-     def _make_load_template(self):
-         """
-@@ -299,7 +299,7 @@ class Renderer(object):
-             try:
-                 return load_partial(name)
-             except TemplateNotFoundError:
--                return u''
-+                return ''
- 
-         return resolve_partial
- 
-@@ -316,7 +316,7 @@ class Renderer(object):
-             try:
-                 return context_get(stack, name)
-             except KeyNotFoundError:
--                return u''
-+                return ''
- 
-         return resolve_context
- 
-diff --git a/pystache/specloader.py b/pystache/specloader.py
-index 3a77d4c..a82d52a 100644
---- a/pystache/specloader.py
-+++ b/pystache/specloader.py
-@@ -83,7 +83,7 @@ class SpecLoader(object):
- 
-         """
-         if spec.template is not None:
--            return self.loader.unicode(spec.template, spec.template_encoding)
-+            return self.loader.str(spec.template, spec.template_encoding)
- 
-         path = self._find(spec)
- 
-diff --git a/pystache/tests/benchmark.py b/pystache/tests/benchmark.py
-index d46e973..6cb54f8 100755
---- a/pystache/tests/benchmark.py
-+++ b/pystache/tests/benchmark.py
-@@ -13,6 +13,13 @@ tests/benchmark.py 10000
- import sys
- from timeit import Timer
- 
-+try:
-+    import chevron as pystache
-+    print('Using module: chevron')
-+except (ImportError):
-+    import pystache
-+    print('Using module: pystache')
-+
- import pystache
- 
- # TODO: make the example realistic.
-@@ -76,17 +83,17 @@ def main(sys_argv):
-     args = sys_argv[1:]
-     count = int(args[0])
- 
--    print "Benchmarking: %sx" % count
--    print
-+    print("Benchmarking: %sx" % count)
-+    print()
- 
-     for example in examples:
- 
-         test = make_test_function(example)
- 
-         t = Timer(test,)
--        print min(t.repeat(repeat=3, number=count))
-+        print(min(t.repeat(repeat=3, number=count)))
- 
--    print "Done"
-+    print("Done")
- 
- 
- if __name__ == '__main__':
-diff --git a/pystache/tests/common.py b/pystache/tests/common.py
-index 222e14f..12b76b5 100644
---- a/pystache/tests/common.py
-+++ b/pystache/tests/common.py
-@@ -72,8 +72,8 @@ def _find_files(root_dir, should_include):
-     #   http://docs.python.org/library/os.html#os.walk
-     for dir_path, dir_names, file_names in os.walk(root_dir):
-         new_paths = [os.path.join(dir_path, file_name) for file_name in file_names]
--        new_paths = filter(is_module, new_paths)
--        new_paths = filter(should_include, new_paths)
-+        new_paths = list(filter(is_module, new_paths))
-+        new_paths = list(filter(should_include, new_paths))
-         paths.extend(new_paths)
- 
-     return paths
-@@ -183,7 +183,7 @@ class AssertExceptionMixin:
-         try:
-             callable(*args, **kwds)
-             raise Exception("Expected exception: %s: %s" % (exception_type, repr(msg)))
--        except exception_type, err:
-+        except exception_type as err:
-             self.assertEqual(str(err), msg)
- 
- 
-@@ -228,10 +228,10 @@ class Attachable(object):
-     """
-     def __init__(self, **kwargs):
-         self.__args__ = kwargs
--        for arg, value in kwargs.iteritems():
-+        for arg, value in kwargs.items():
-             setattr(self, arg, value)
- 
-     def __repr__(self):
-         return "%s(%s)" % (self.__class__.__name__,
-                            ", ".join("%s=%s" % (k, repr(v))
--                                     for k, v in self.__args__.iteritems()))
-+                                     for k, v in self.__args__.items()))
-diff --git a/pystache/tests/examples/unicode_output.py b/pystache/tests/examples/unicode_output.py
-index da0e1d2..7bdea36 100644
---- a/pystache/tests/examples/unicode_output.py
-+++ b/pystache/tests/examples/unicode_output.py
-@@ -8,4 +8,4 @@ TODO: add a docstring.
- class UnicodeOutput(object):
- 
-     def name(self):
--        return u'Henri Poincaré'
-+        return 'Henri Poincaré'
-diff --git a/pystache/tests/main.py b/pystache/tests/main.py
-index 8af6b2e..17f2fb2 100644
---- a/pystache/tests/main.py
-+++ b/pystache/tests/main.py
-@@ -88,7 +88,7 @@ def main(sys_argv):
- 
-     """
-     # TODO: use logging module
--    print "pystache: running tests: argv: %s" % repr(sys_argv)
-+    print("pystache: running tests: argv: %s" % repr(sys_argv))
- 
-     should_source_exist = False
-     spec_test_dir = None
-@@ -131,11 +131,9 @@ def main(sys_argv):
-         module_names = _discover_test_modules(PACKAGE_DIR)
-         sys_argv.extend(module_names)
-         if project_dir is not None:
--            # Add the current module for unit tests contained here (e.g.
--            # to include SetupTests).
-+            # Add the current module for unit tests contained here
-             sys_argv.append(__name__)
- 
--    SetupTests.project_dir = project_dir
- 
-     extra_tests = make_extra_tests(project_dir, spec_test_dir)
-     test_program_class = make_test_program_class(extra_tests)
-@@ -166,25 +164,3 @@ def _discover_test_modules(package_dir):
-         raise Exception("No unit-test modules found--\n  in %s" % package_dir)
- 
-     return names
--
--
--class SetupTests(TestCase):
--
--    """Tests about setup.py."""
--
--    project_dir = None
--
--    def test_version(self):
--        """
--        Test that setup.py's version matches the package's version.
--
--        """
--        original_path = list(sys.path)
--
--        sys.path.insert(0, self.project_dir)
--
--        try:
--            from setup import VERSION
--            self.assertEqual(VERSION, pystache.__version__)
--        finally:
--            sys.path = original_path
-diff --git a/pystache/tests/spectesting.py b/pystache/tests/spectesting.py
-index ec8a08d..2dd57e8 100644
---- a/pystache/tests/spectesting.py
-+++ b/pystache/tests/spectesting.py
-@@ -37,7 +37,7 @@ except ImportError:
-             from sys import exc_info
-             ex_type, ex_value, tb = exc_info()
-             new_ex = Exception("%s: %s" % (ex_type.__name__, ex_value))
--            raise new_ex.__class__, new_ex, tb
-+            raise new_ex.__class__(new_ex).with_traceback(tb)
-     file_extension = 'json'
-     parser = json
- else:
-@@ -62,7 +62,7 @@ def get_spec_tests(spec_test_dir):
- 
-     """
-     # TODO: use logging module instead.
--    print "pystache: spec tests: using %s" % _get_parser_info()
-+    print("pystache: spec tests: using %s" % _get_parser_info())
- 
-     cases = []
- 
-@@ -103,7 +103,7 @@ def _read_spec_tests(path):
- 
-     """
-     b = common.read(path)
--    u = unicode(b, encoding=FILE_ENCODING)
-+    u = str(b, encoding=FILE_ENCODING)
-     spec_data = parse(u)
-     tests = spec_data['tests']
- 
-@@ -133,7 +133,7 @@ def _convert_children(node):
-         return
-     # Otherwise, node is a dict, so attempt the conversion.
- 
--    for key in node.keys():
-+    for key in list(node.keys()):
-         val = node[key]
- 
-         if not isinstance(val, dict) or val.get('__tag__') != 'code':
-@@ -158,9 +158,9 @@ def _deserialize_spec_test(data, file_path):
-     context = data['data']
-     description = data['desc']
-     # PyYAML seems to leave ASCII strings as byte strings.
--    expected = unicode(data['expected'])
-+    expected = str(data['expected'])
-     # TODO: switch to using dict.get().
--    partials = data.has_key('partials') and data['partials'] or {}
-+    partials = 'partials' in data and data['partials'] or {}
-     template = data['template']
-     test_name = data['name']
- 
-@@ -237,8 +237,8 @@ def parse(u):
-         value = loader.construct_mapping(node)
-         return eval(value['python'], {})
- 
--    yaml.add_constructor(u'!code', code_constructor)
--    return yaml.load(u)
-+    yaml.add_constructor('!code', code_constructor)
-+    return yaml.full_load(u)
- 
- 
- class SpecTestBase(unittest.TestCase, AssertStringMixin):
-diff --git a/pystache/tests/test___init__.py b/pystache/tests/test___init__.py
-index eae42c1..63d2c3b 100644
---- a/pystache/tests/test___init__.py
-+++ b/pystache/tests/test___init__.py
-@@ -6,9 +6,9 @@ Tests of __init__.py.
- """
- 
- # Calling "import *" is allowed only at the module level.
--GLOBALS_INITIAL = globals().keys()
-+GLOBALS_INITIAL = list(globals().keys())
- from pystache import *
--GLOBALS_PYSTACHE_IMPORTED = globals().keys()
-+GLOBALS_PYSTACHE_IMPORTED = list(globals().keys())
- 
- import unittest
- 
-diff --git a/pystache/tests/test_commands.py b/pystache/tests/test_commands.py
-index 2529d25..34fe8ba 100644
---- a/pystache/tests/test_commands.py
-+++ b/pystache/tests/test_commands.py
-@@ -39,7 +39,7 @@ class CommandsTestCase(unittest.TestCase):
- 
-         """
-         actual = self.callScript("Hi {{thing}}", '{"thing": "world"}')
--        self.assertEqual(actual, u"Hi world\n")
-+        self.assertEqual(actual, "Hi world\n")
- 
-     def tearDown(self):
-         sys.stdout = ORIGINAL_STDOUT
-diff --git a/pystache/tests/test_defaults.py b/pystache/tests/test_defaults.py
-index c78ea7c..5399bb0 100644
---- a/pystache/tests/test_defaults.py
-+++ b/pystache/tests/test_defaults.py
-@@ -31,37 +31,37 @@ class DefaultsConfigurableTestCase(unittest.TestCase, AssertStringMixin):
-             self.saved[e] = getattr(pystache.defaults, e)
- 
-     def tearDown(self):
--        for key, value in self.saved.items():
-+        for key, value in list(self.saved.items()):
-             setattr(pystache.defaults, key, value)
- 
-     def test_tag_escape(self):
-         """Test that changes to defaults.TAG_ESCAPE take effect."""
--        template = u"{{foo}}"
-+        template = "{{foo}}"
-         context = {'foo': '<'}
-         actual = pystache.render(template, context)
--        self.assertString(actual, u"&lt;")
-+        self.assertString(actual, "&lt;")
- 
-         pystache.defaults.TAG_ESCAPE = lambda u: u
-         actual = pystache.render(template, context)
--        self.assertString(actual, u"<")
-+        self.assertString(actual, "<")
- 
-     def test_delimiters(self):
-         """Test that changes to defaults.DELIMITERS take effect."""
--        template = u"[[foo]]{{foo}}"
-+        template = "[[foo]]{{foo}}"
-         context = {'foo': 'FOO'}
-         actual = pystache.render(template, context)
--        self.assertString(actual, u"[[foo]]FOO")
-+        self.assertString(actual, "[[foo]]FOO")
- 
-         pystache.defaults.DELIMITERS = ('[[', ']]')
-         actual = pystache.render(template, context)
--        self.assertString(actual, u"FOO{{foo}}")
-+        self.assertString(actual, "FOO{{foo}}")
- 
-     def test_missing_tags(self):
-         """Test that changes to defaults.MISSING_TAGS take effect."""
--        template = u"{{foo}}"
-+        template = "{{foo}}"
-         context = {}
-         actual = pystache.render(template, context)
--        self.assertString(actual, u"")
-+        self.assertString(actual, "")
- 
-         pystache.defaults.MISSING_TAGS = 'strict'
-         self.assertRaises(pystache.context.KeyNotFoundError,
-diff --git a/pystache/tests/test_examples.py b/pystache/tests/test_examples.py
-index 5c9f74d..9f93de3 100644
---- a/pystache/tests/test_examples.py
-+++ b/pystache/tests/test_examples.py
-@@ -7,15 +7,15 @@ TODO: add a docstring.
- 
- import unittest
- 
--from examples.comments import Comments
--from examples.double_section import DoubleSection
--from examples.escaped import Escaped
--from examples.unescaped import Unescaped
--from examples.template_partial import TemplatePartial
--from examples.delimiters import Delimiters
--from examples.unicode_output import UnicodeOutput
--from examples.unicode_input import UnicodeInput
--from examples.nested_context import NestedContext
-+from .examples.comments import Comments
-+from .examples.double_section import DoubleSection
-+from .examples.escaped import Escaped
-+from .examples.unescaped import Unescaped
-+from .examples.template_partial import TemplatePartial
-+from .examples.delimiters import Delimiters
-+from .examples.unicode_output import UnicodeOutput
-+from .examples.unicode_input import UnicodeInput
-+from .examples.nested_context import NestedContext
- from pystache import Renderer
- from pystache.tests.common import EXAMPLES_DIR
- from pystache.tests.common import AssertStringMixin
-@@ -29,34 +29,34 @@ class TestView(unittest.TestCase, AssertStringMixin):
-         self.assertString(actual, expected)
- 
-     def test_comments(self):
--        self._assert(Comments(), u"<h1>A Comedy of Errors</h1>")
-+        self._assert(Comments(), "<h1>A Comedy of Errors</h1>")
- 
-     def test_double_section(self):
--        self._assert(DoubleSection(), u"* first\n* second\n* third")
-+        self._assert(DoubleSection(), "* first\n* second\n* third")
- 
-     def test_unicode_output(self):
-         renderer = Renderer()
-         actual = renderer.render(UnicodeOutput())
--        self.assertString(actual, u'<p>Name: Henri Poincaré</p>')
-+        self.assertString(actual, '<p>Name: Henri Poincaré</p>')
- 
-     def test_unicode_input(self):
-         renderer = Renderer()
-         actual = renderer.render(UnicodeInput())
--        self.assertString(actual, u'abcdé')
-+        self.assertString(actual, 'abcdé')
- 
-     def test_escaping(self):
--        self._assert(Escaped(), u"<h1>Bear &gt; Shark</h1>")
-+        self._assert(Escaped(), "<h1>Bear &gt; Shark</h1>")
- 
-     def test_literal(self):
-         renderer = Renderer()
-         actual = renderer.render(Unescaped())
--        self.assertString(actual, u"<h1>Bear > Shark</h1>")
-+        self.assertString(actual, "<h1>Bear > Shark</h1>")
- 
-     def test_template_partial(self):
-         renderer = Renderer(search_dirs=EXAMPLES_DIR)
-         actual = renderer.render(TemplatePartial(renderer=renderer))
- 
--        self.assertString(actual, u"""<h1>Welcome</h1>
-+        self.assertString(actual, """<h1>Welcome</h1>
- Again, Welcome!""")
- 
-     def test_template_partial_extension(self):
-@@ -65,7 +65,7 @@ Again, Welcome!""")
-         view = TemplatePartial(renderer=renderer)
- 
-         actual = renderer.render(view)
--        self.assertString(actual, u"""Welcome
-+        self.assertString(actual, """Welcome
- -------
- 
- ## Again, Welcome! ##""")
-@@ -73,7 +73,7 @@ Again, Welcome!""")
-     def test_delimiters(self):
-         renderer = Renderer()
-         actual = renderer.render(Delimiters())
--        self.assertString(actual, u"""\
-+        self.assertString(actual, """\
- * It worked the first time.
- * And it worked the second time.
- * Then, surprisingly, it worked the third time.
-@@ -82,7 +82,7 @@ Again, Welcome!""")
-     def test_nested_context(self):
-         renderer = Renderer()
-         actual = renderer.render(NestedContext(renderer))
--        self.assertString(actual, u"one and foo and two")
-+        self.assertString(actual, "one and foo and two")
- 
-     def test_nested_context_is_available_in_view(self):
-         renderer = Renderer()
-@@ -91,7 +91,7 @@ Again, Welcome!""")
-         view.template = '{{#herp}}{{#derp}}{{nested_context_in_view}}{{/derp}}{{/herp}}'
- 
-         actual = renderer.render(view)
--        self.assertString(actual, u'it works!')
-+        self.assertString(actual, 'it works!')
- 
-     def test_partial_in_partial_has_access_to_grand_parent_context(self):
-         renderer = Renderer(search_dirs=EXAMPLES_DIR)
-diff --git a/pystache/tests/test_loader.py b/pystache/tests/test_loader.py
-index f2c2187..315daff 100644
---- a/pystache/tests/test_loader.py
-+++ b/pystache/tests/test_loader.py
-@@ -55,23 +55,23 @@ class LoaderTests(unittest.TestCase, AssertStringMixin, SetupDefaults):
- 
-     def test_init__to_unicode__default(self):
-         loader = Loader()
--        self.assertRaises(TypeError, loader.to_unicode, u"abc")
-+        self.assertRaises(TypeError, loader.to_unicode, "abc")
- 
-         decode_errors = defaults.DECODE_ERRORS
-         string_encoding = defaults.STRING_ENCODING
- 
--        nonascii = u'abcdé'.encode('utf-8')
-+        nonascii = 'abcdé'.encode('utf-8')
- 
-         loader = Loader()
-         self.assertRaises(UnicodeDecodeError, loader.to_unicode, nonascii)
- 
-         defaults.DECODE_ERRORS = 'ignore'
-         loader = Loader()
--        self.assertString(loader.to_unicode(nonascii), u'abcd')
-+        self.assertString(loader.to_unicode(nonascii), 'abcd')
- 
-         defaults.STRING_ENCODING = 'utf-8'
-         loader = Loader()
--        self.assertString(loader.to_unicode(nonascii), u'abcdé')
-+        self.assertString(loader.to_unicode(nonascii), 'abcdé')
- 
- 
-     def _get_path(self, filename):
-@@ -83,9 +83,9 @@ class LoaderTests(unittest.TestCase, AssertStringMixin, SetupDefaults):
- 
-         """
-         loader = Loader()
--        actual = loader.unicode("foo")
-+        actual = loader.str("foo")
- 
--        self.assertString(actual, u"foo")
-+        self.assertString(actual, "foo")
- 
-     def test_unicode__basic__input_unicode(self):
-         """
-@@ -93,24 +93,24 @@ class LoaderTests(unittest.TestCase, AssertStringMixin, SetupDefaults):
- 
-         """
-         loader = Loader()
--        actual = loader.unicode(u"foo")
-+        actual = loader.str("foo")
- 
--        self.assertString(actual, u"foo")
-+        self.assertString(actual, "foo")
- 
-     def test_unicode__basic__input_unicode_subclass(self):
-         """
-         Test unicode(): default arguments with unicode-subclass input.
- 
-         """
--        class UnicodeSubclass(unicode):
-+        class UnicodeSubclass(str):
-             pass
- 
--        s = UnicodeSubclass(u"foo")
-+        s = UnicodeSubclass("foo")
- 
-         loader = Loader()
--        actual = loader.unicode(s)
-+        actual = loader.str(s)
- 
--        self.assertString(actual, u"foo")
-+        self.assertString(actual, "foo")
- 
-     def test_unicode__to_unicode__attribute(self):
-         """
-@@ -119,16 +119,16 @@ class LoaderTests(unittest.TestCase, AssertStringMixin, SetupDefaults):
-         """
-         loader = Loader()
- 
--        non_ascii = u'abcdé'.encode('utf-8')
--        self.assertRaises(UnicodeDecodeError, loader.unicode, non_ascii)
-+        non_ascii = 'abcdé'.encode('utf-8')
-+        self.assertRaises(UnicodeDecodeError, loader.str, non_ascii)
- 
-         def to_unicode(s, encoding=None):
-             if encoding is None:
-                 encoding = 'utf-8'
--            return unicode(s, encoding)
-+            return str(s, encoding)
- 
-         loader.to_unicode = to_unicode
--        self.assertString(loader.unicode(non_ascii), u"abcdé")
-+        self.assertString(loader.str(non_ascii), "abcdé")
- 
-     def test_unicode__encoding_argument(self):
-         """
-@@ -137,12 +137,12 @@ class LoaderTests(unittest.TestCase, AssertStringMixin, SetupDefaults):
-         """
-         loader = Loader()
- 
--        non_ascii = u'abcdé'.encode('utf-8')
-+        non_ascii = 'abcdé'.encode('utf-8')
- 
--        self.assertRaises(UnicodeDecodeError, loader.unicode, non_ascii)
-+        self.assertRaises(UnicodeDecodeError, loader.str, non_ascii)
- 
--        actual = loader.unicode(non_ascii, encoding='utf-8')
--        self.assertString(actual, u'abcdé')
-+        actual = loader.str(non_ascii, encoding='utf-8')
-+        self.assertString(actual, 'abcdé')
- 
-     # TODO: check the read() unit tests.
-     def test_read(self):
-@@ -153,7 +153,7 @@ class LoaderTests(unittest.TestCase, AssertStringMixin, SetupDefaults):
-         loader = Loader()
-         path = self._get_path('ascii.mustache')
-         actual = loader.read(path)
--        self.assertString(actual, u'ascii: abc')
-+        self.assertString(actual, 'ascii: abc')
- 
-     def test_read__file_encoding__attribute(self):
-         """
-@@ -167,7 +167,7 @@ class LoaderTests(unittest.TestCase, AssertStringMixin, SetupDefaults):
- 
-         loader.file_encoding = 'utf-8'
-         actual = loader.read(path)
--        self.assertString(actual, u'non-ascii: é')
-+        self.assertString(actual, 'non-ascii: é')
- 
-     def test_read__encoding__argument(self):
-         """
-@@ -180,7 +180,7 @@ class LoaderTests(unittest.TestCase, AssertStringMixin, SetupDefaults):
-         self.assertRaises(UnicodeDecodeError, loader.read, path)
- 
-         actual = loader.read(path, encoding='utf-8')
--        self.assertString(actual, u'non-ascii: é')
-+        self.assertString(actual, 'non-ascii: é')
- 
-     def test_read__to_unicode__attribute(self):
-         """
-diff --git a/pystache/tests/test_pystache.py b/pystache/tests/test_pystache.py
-index 5447f8d..cf5d6af 100644
---- a/pystache/tests/test_pystache.py
-+++ b/pystache/tests/test_pystache.py
-@@ -71,14 +71,14 @@ class PystacheTests(unittest.TestCase):
-         template = "{{#stats}}({{key}} & {{value}}){{/stats}}"
-         stats = []
-         stats.append({'key': 123, 'value': ['something']})
--        stats.append({'key': u"chris", 'value': 0.900})
-+        stats.append({'key': "chris", 'value': 0.900})
-         context = { 'stats': stats }
-         self._assert_rendered(self.non_strings_expected, template, context)
- 
-     def test_unicode(self):
-         template = 'Name: {{name}}; Age: {{age}}'
--        context = {'name': u'Henri Poincaré', 'age': 156 }
--        self._assert_rendered(u'Name: Henri Poincaré; Age: 156', template, context)
-+        context = {'name': 'Henri Poincaré', 'age': 156}
-+        self._assert_rendered('Name: Henri Poincaré; Age: 156', template, context)
- 
-     def test_sections(self):
-         template = """<ul>{{#users}}<li>{{name}}</li>{{/users}}</ul>"""
-diff --git a/pystache/tests/test_renderengine.py b/pystache/tests/test_renderengine.py
-index db916f7..ed604c5 100644
---- a/pystache/tests/test_renderengine.py
-+++ b/pystache/tests/test_renderengine.py
-@@ -33,11 +33,11 @@ def mock_literal(s):
-       s: a byte string or unicode string.
- 
-     """
--    if isinstance(s, unicode):
-+    if isinstance(s, str):
-         # Strip off unicode super classes, if present.
--        u = unicode(s)
-+        u = str(s)
-     else:
--        u = unicode(s, encoding='ascii')
-+        u = str(s, encoding='ascii')
- 
-     # We apply upper() to make sure we are actually using our custom
-     # function in the tests
-@@ -94,17 +94,17 @@ class RenderTests(unittest.TestCase, AssertStringMixin, AssertExceptionMixin):
-         engine = kwargs.get('engine', self._engine())
- 
-         if partials is not None:
--            engine.resolve_partial = lambda key: unicode(partials[key])
-+            engine.resolve_partial = lambda key: str(partials[key])
- 
-         context = ContextStack(*context)
- 
-         # RenderEngine.render() only accepts unicode template strings.
--        actual = engine.render(unicode(template), context)
-+        actual = engine.render(str(template), context)
- 
-         self.assertString(actual=actual, expected=expected)
- 
-     def test_render(self):
--        self._assert_render(u'Hi Mom', 'Hi {{person}}', {'person': 'Mom'})
-+        self._assert_render('Hi Mom', 'Hi {{person}}', {'person': 'Mom'})
- 
-     def test__resolve_partial(self):
-         """
-@@ -112,10 +112,10 @@ class RenderTests(unittest.TestCase, AssertStringMixin, AssertExceptionMixin):
- 
-         """
-         engine = self._engine()
--        partials = {'partial': u"{{person}}"}
-+        partials = {'partial': "{{person}}"}
-         engine.resolve_partial = lambda key: partials[key]
- 
--        self._assert_render(u'Hi Mom', 'Hi {{>partial}}', {'person': 'Mom'}, engine=engine)
-+        self._assert_render('Hi Mom', 'Hi {{>partial}}', {'person': 'Mom'}, engine=engine)
- 
-     def test__literal(self):
-         """
-@@ -125,13 +125,13 @@ class RenderTests(unittest.TestCase, AssertStringMixin, AssertExceptionMixin):
-         engine = self._engine()
-         engine.literal = lambda s: s.upper()
- 
--        self._assert_render(u'BAR', '{{{foo}}}', {'foo': 'bar'}, engine=engine)
-+        self._assert_render('BAR', '{{{foo}}}', {'foo': 'bar'}, engine=engine)
- 
-     def test_literal__sigil(self):
-         template = "<h1>{{& thing}}</h1>"
-         context = {'thing': 'Bear > Giraffe'}
- 
--        expected = u"<h1>Bear > Giraffe</h1>"
-+        expected = "<h1>Bear > Giraffe</h1>"
- 
-         self._assert_render(expected, template, context)
- 
-@@ -143,7 +143,7 @@ class RenderTests(unittest.TestCase, AssertStringMixin, AssertExceptionMixin):
-         engine = self._engine()
-         engine.escape = lambda s: "**" + s
- 
--        self._assert_render(u'**bar', '{{foo}}', {'foo': 'bar'}, engine=engine)
-+        self._assert_render('**bar', '{{foo}}', {'foo': 'bar'}, engine=engine)
- 
-     def test__escape_does_not_call_literal(self):
-         """
-@@ -157,7 +157,7 @@ class RenderTests(unittest.TestCase, AssertStringMixin, AssertExceptionMixin):
-         template = 'literal: {{{foo}}} escaped: {{foo}}'
-         context = {'foo': 'bar'}
- 
--        self._assert_render(u'literal: BAR escaped: **bar', template, context, engine=engine)
-+        self._assert_render('literal: BAR escaped: **bar', template, context, engine=engine)
- 
-     def test__escape_preserves_unicode_subclasses(self):
-         """
-@@ -167,7 +167,7 @@ class RenderTests(unittest.TestCase, AssertStringMixin, AssertExceptionMixin):
-         variable value is markupsafe.Markup when escaping.
- 
-         """
--        class MyUnicode(unicode):
-+        class MyUnicode(str):
-             pass
- 
-         def escape(s):
-@@ -182,7 +182,7 @@ class RenderTests(unittest.TestCase, AssertStringMixin, AssertExceptionMixin):
-         template = '{{foo1}} {{foo2}}'
-         context = {'foo1': MyUnicode('bar'), 'foo2': 'bar'}
- 
--        self._assert_render(u'**bar bar**', template, context, engine=engine)
-+        self._assert_render('**bar bar**', template, context, engine=engine)
- 
-     # Custom to_str for testing purposes.
-     def _to_str(self, val):
-@@ -197,9 +197,9 @@ class RenderTests(unittest.TestCase, AssertStringMixin, AssertExceptionMixin):
-         template = '{{value}}'
-         context = {'value': None}
- 
--        self._assert_render(u'None', template, context, engine=engine)
-+        self._assert_render('None', template, context, engine=engine)
-         engine.to_str = self._to_str
--        self._assert_render(u'', template, context, engine=engine)
-+        self._assert_render('', template, context, engine=engine)
- 
-     def test_to_str__lambda(self):
-         """Test the to_str attribute for a lambda."""
-@@ -207,9 +207,9 @@ class RenderTests(unittest.TestCase, AssertStringMixin, AssertExceptionMixin):
-         template = '{{value}}'
-         context = {'value': lambda: None}
- 
--        self._assert_render(u'None', template, context, engine=engine)
-+        self._assert_render('None', template, context, engine=engine)
-         engine.to_str = self._to_str
--        self._assert_render(u'', template, context, engine=engine)
-+        self._assert_render('', template, context, engine=engine)
- 
-     def test_to_str__section_list(self):
-         """Test the to_str attribute for a section list."""
-@@ -217,9 +217,9 @@ class RenderTests(unittest.TestCase, AssertStringMixin, AssertExceptionMixin):
-         template = '{{#list}}{{.}}{{/list}}'
-         context = {'list': [None, None]}
- 
--        self._assert_render(u'NoneNone', template, context, engine=engine)
-+        self._assert_render('NoneNone', template, context, engine=engine)
-         engine.to_str = self._to_str
--        self._assert_render(u'', template, context, engine=engine)
-+        self._assert_render('', template, context, engine=engine)
- 
-     def test_to_str__section_lambda(self):
-         # TODO: add a test for a "method with an arity of 1".
-@@ -239,7 +239,7 @@ class RenderTests(unittest.TestCase, AssertStringMixin, AssertExceptionMixin):
-         template = '{{text}} {{int}} {{{int}}}'
-         context = {'int': 100, 'text': 'foo'}
- 
--        self._assert_render(u'FOO 100 100', template, context, engine=engine)
-+        self._assert_render('FOO 100 100', template, context, engine=engine)
- 
-     def test_tag__output_not_interpolated(self):
-         """
-@@ -248,7 +248,7 @@ class RenderTests(unittest.TestCase, AssertStringMixin, AssertExceptionMixin):
-         """
-         template = '{{template}}: {{planet}}'
-         context = {'template': '{{planet}}', 'planet': 'Earth'}
--        self._assert_render(u'{{planet}}: Earth', template, context)
-+        self._assert_render('{{planet}}: Earth', template, context)
- 
-     def test_tag__output_not_interpolated__section(self):
-         """
-@@ -257,7 +257,7 @@ class RenderTests(unittest.TestCase, AssertStringMixin, AssertExceptionMixin):
-         """
-         template = '{{test}}'
-         context = {'test': '{{#hello}}'}
--        self._assert_render(u'{{#hello}}', template, context)
-+        self._assert_render('{{#hello}}', template, context)
- 
-     ## Test interpolation with "falsey" values
-     #
-@@ -268,17 +268,17 @@ class RenderTests(unittest.TestCase, AssertStringMixin, AssertExceptionMixin):
-     def test_interpolation__falsey__zero(self):
-         template = '{{.}}'
-         context = 0
--        self._assert_render(u'0', template, context)
-+        self._assert_render('0', template, context)
- 
-     def test_interpolation__falsey__none(self):
-         template = '{{.}}'
-         context = None
--        self._assert_render(u'None', template, context)
-+        self._assert_render('None', template, context)
- 
-     def test_interpolation__falsey__zero(self):
-         template = '{{.}}'
-         context = False
--        self._assert_render(u'False', template, context)
-+        self._assert_render('False', template, context)
- 
-     # Built-in types:
-     #
-@@ -310,7 +310,7 @@ class RenderTests(unittest.TestCase, AssertStringMixin, AssertExceptionMixin):
-         Check tag interpolation with a built-in type: string.
- 
-         """
--        self._assert_builtin_type('abc', 'upper', 'ABC', u'xyz')
-+        self._assert_builtin_type('abc', 'upper', 'ABC', 'xyz')
- 
-     def test_interpolation__built_in_type__integer(self):
-         """
-@@ -324,7 +324,7 @@ class RenderTests(unittest.TestCase, AssertStringMixin, AssertExceptionMixin):
-         #
-         # we need to resort to built-in attributes (double-underscored) on
-         # the integer type.
--        self._assert_builtin_type(15, '__neg__', -15, u'999')
-+        self._assert_builtin_type(15, '__neg__', -15, '999')
- 
-     def test_interpolation__built_in_type__list(self):
-         """
-@@ -338,7 +338,7 @@ class RenderTests(unittest.TestCase, AssertStringMixin, AssertExceptionMixin):
- 
-         template = '{{#section}}{{%s}}{{/section}}' % attr_name
-         context = {'section': item, attr_name: 7}
--        self._assert_render(u'7', template, context)
-+        self._assert_render('7', template, context)
- 
-     # This test is also important for testing 2to3.
-     def test_interpolation__nonascii_nonunicode(self):
-@@ -347,8 +347,8 @@ class RenderTests(unittest.TestCase, AssertStringMixin, AssertExceptionMixin):
- 
-         """
-         template = '{{nonascii}}'
--        context = {'nonascii': u'abcdé'.encode('utf-8')}
--        self._assert_render(u'abcdé', template, context)
-+        context = {'nonascii': 'abcdé'.encode('utf-8')}
-+        self._assert_render('abcdé', template, context)
- 
-     def test_implicit_iterator__literal(self):
-         """
-@@ -358,7 +358,7 @@ class RenderTests(unittest.TestCase, AssertStringMixin, AssertExceptionMixin):
-         template = """{{#test}}{{{.}}}{{/test}}"""
-         context = {'test': ['<', '>']}
- 
--        self._assert_render(u'<>', template, context)
-+        self._assert_render('<>', template, context)
- 
-     def test_implicit_iterator__escaped(self):
-         """
-@@ -368,7 +368,7 @@ class RenderTests(unittest.TestCase, AssertStringMixin, AssertExceptionMixin):
-         template = """{{#test}}{{.}}{{/test}}"""
-         context = {'test': ['<', '>']}
- 
--        self._assert_render(u'&lt;&gt;', template, context)
-+        self._assert_render('&lt;&gt;', template, context)
- 
-     def test_literal__in_section(self):
-         """
-@@ -378,7 +378,7 @@ class RenderTests(unittest.TestCase, AssertStringMixin, AssertExceptionMixin):
-         template = '{{#test}}1 {{{less_than}}} 2{{/test}}'
-         context = {'test': {'less_than': '<'}}
- 
--        self._assert_render(u'1 < 2', template, context)
-+        self._assert_render('1 < 2', template, context)
- 
-     def test_literal__in_partial(self):
-         """
-@@ -389,11 +389,11 @@ class RenderTests(unittest.TestCase, AssertStringMixin, AssertExceptionMixin):
-         partials = {'partial': '1 {{{less_than}}} 2'}
-         context = {'less_than': '<'}
- 
--        self._assert_render(u'1 < 2', template, context, partials=partials)
-+        self._assert_render('1 < 2', template, context, partials=partials)
- 
-     def test_partial(self):
-         partials = {'partial': "{{person}}"}
--        self._assert_render(u'Hi Mom', 'Hi {{>partial}}', {'person': 'Mom'}, partials=partials)
-+        self._assert_render('Hi Mom', 'Hi {{>partial}}', {'person': 'Mom'}, partials=partials)
- 
-     def test_partial__context_values(self):
-         """
-@@ -406,7 +406,9 @@ class RenderTests(unittest.TestCase, AssertStringMixin, AssertExceptionMixin):
-         partials = {'partial': 'unescaped: {{{foo}}} escaped: {{foo}}'}
-         context = {'foo': '<'}
- 
--        self._assert_render(u'unescaped: < escaped: &lt;', template, context, engine=engine, partials=partials)
-+        self._assert_render(
-+            'unescaped: < escaped: &lt;',
-+            template, context, engine=engine, partials=partials)
- 
-     ## Test cases related specifically to lambdas.
- 
-@@ -417,8 +419,8 @@ class RenderTests(unittest.TestCase, AssertStringMixin, AssertExceptionMixin):
- 
-         """
-         template = '{{#nonascii}}{{.}}{{/nonascii}}'
--        context = {'nonascii': u'abcdé'.encode('utf-8')}
--        self._assert_render(u'abcdé', template, context)
-+        context = {'nonascii': 'abcdé'.encode('utf-8')}
-+        self._assert_render('abcdé', template, context)
- 
-     # This test is also important for testing 2to3.
-     def test_lambda__returning_nonascii_nonunicode(self):
-@@ -427,8 +429,8 @@ class RenderTests(unittest.TestCase, AssertStringMixin, AssertExceptionMixin):
- 
-         """
-         template = '{{lambda}}'
--        context = {'lambda': lambda: u'abcdé'.encode('utf-8')}
--        self._assert_render(u'abcdé', template, context)
-+        context = {'lambda': lambda: 'abcdé'.encode('utf-8')}
-+        self._assert_render('abcdé', template, context)
- 
-     ## Test cases related specifically to sections.
- 
-@@ -440,7 +442,7 @@ class RenderTests(unittest.TestCase, AssertStringMixin, AssertExceptionMixin):
-         template = '{{/section}}'
-         try:
-             self._assert_render(None, template)
--        except ParsingError, err:
-+        except ParsingError as err:
-             self.assertEqual(str(err), "Section end tag mismatch: section != None")
- 
-     def test_section__end_tag_mismatch(self):
-@@ -451,7 +453,7 @@ class RenderTests(unittest.TestCase, AssertStringMixin, AssertExceptionMixin):
-         template = '{{#section_start}}{{/section_end}}'
-         try:
-             self._assert_render(None, template)
--        except ParsingError, err:
-+        except ParsingError as err:
-             self.assertEqual(str(err), "Section end tag mismatch: section_end != section_start")
- 
-     def test_section__context_values(self):
-@@ -464,7 +466,7 @@ class RenderTests(unittest.TestCase, AssertStringMixin, AssertExceptionMixin):
-         template = '{{#test}}unescaped: {{{foo}}} escaped: {{foo}}{{/test}}'
-         context = {'test': {'foo': '<'}}
- 
--        self._assert_render(u'unescaped: < escaped: &lt;', template, context, engine=engine)
-+        self._assert_render('unescaped: < escaped: &lt;', template, context, engine=engine)
- 
-     def test_section__context_precedence(self):
-         """
-@@ -473,7 +475,7 @@ class RenderTests(unittest.TestCase, AssertStringMixin, AssertExceptionMixin):
-         """
-         template = '{{entree}} : {{#vegetarian}}{{entree}}{{/vegetarian}}'
-         context = {'entree': 'chicken', 'vegetarian': {'entree': 'beans and rice'}}
--        self._assert_render(u'chicken : beans and rice', template, context)
-+        self._assert_render('chicken : beans and rice', template, context)
- 
-     def test_section__list_referencing_outer_context(self):
-         """
-@@ -491,7 +493,7 @@ class RenderTests(unittest.TestCase, AssertStringMixin, AssertExceptionMixin):
- 
-         template = "{{#list}}{{greeting}} {{name}}, {{/list}}"
- 
--        self._assert_render(u"Hi Al, Hi Bob, ", template, context)
-+        self._assert_render("Hi Al, Hi Bob, ", template, context)
- 
-     def test_section__output_not_interpolated(self):
-         """
-@@ -500,7 +502,7 @@ class RenderTests(unittest.TestCase, AssertStringMixin, AssertExceptionMixin):
-         """
-         template = '{{#section}}{{template}}{{/section}}: {{planet}}'
-         context = {'section': True, 'template': '{{planet}}', 'planet': 'Earth'}
--        self._assert_render(u'{{planet}}: Earth', template, context)
-+        self._assert_render('{{planet}}: Earth', template, context)
- 
-     # TODO: have this test case added to the spec.
-     def test_section__string_values_not_lists(self):
-@@ -511,7 +513,7 @@ class RenderTests(unittest.TestCase, AssertStringMixin, AssertExceptionMixin):
-         template = '{{#section}}foo{{/section}}'
-         context = {'section': '123'}
-         # If strings were interpreted as lists, this would give "foofoofoo".
--        self._assert_render(u'foo', template, context)
-+        self._assert_render('foo', template, context)
- 
-     def test_section__nested_truthy(self):
-         """
-@@ -525,7 +527,7 @@ class RenderTests(unittest.TestCase, AssertStringMixin, AssertExceptionMixin):
-         """
-         template = '| A {{#bool}}B {{#bool}}C{{/bool}} D{{/bool}} E |'
-         context = {'bool': True}
--        self._assert_render(u'| A B C D E |', template, context)
-+        self._assert_render('| A B C D E |', template, context)
- 
-     def test_section__nested_with_same_keys(self):
-         """
-@@ -537,16 +539,16 @@ class RenderTests(unittest.TestCase, AssertStringMixin, AssertExceptionMixin):
-         # Start with an easier, working case.
-         template = '{{#x}}{{#z}}{{y}}{{/z}}{{/x}}'
-         context = {'x': {'z': {'y': 1}}}
--        self._assert_render(u'1', template, context)
-+        self._assert_render('1', template, context)
- 
-         template = '{{#x}}{{#x}}{{y}}{{/x}}{{/x}}'
-         context = {'x': {'x': {'y': 1}}}
--        self._assert_render(u'1', template, context)
-+        self._assert_render('1', template, context)
- 
-     def test_section__lambda(self):
-         template = '{{#test}}Mom{{/test}}'
-         context = {'test': (lambda text: 'Hi %s' % text)}
--        self._assert_render(u'Hi Mom', template, context)
-+        self._assert_render('Hi Mom', template, context)
- 
-     # This test is also important for testing 2to3.
-     def test_section__lambda__returning_nonascii_nonunicode(self):
-@@ -555,8 +557,8 @@ class RenderTests(unittest.TestCase, AssertStringMixin, AssertExceptionMixin):
- 
-         """
-         template = '{{#lambda}}{{/lambda}}'
--        context = {'lambda': lambda text: u'abcdé'.encode('utf-8')}
--        self._assert_render(u'abcdé', template, context)
-+        context = {'lambda': lambda text: 'abcdé'.encode('utf-8')}
-+        self._assert_render('abcdé', template, context)
- 
-     def test_section__lambda__returning_nonstring(self):
-         """
-@@ -565,7 +567,7 @@ class RenderTests(unittest.TestCase, AssertStringMixin, AssertExceptionMixin):
-         """
-         template = '{{#lambda}}foo{{/lambda}}'
-         context = {'lambda': lambda text: len(text)}
--        self._assert_render(u'3', template, context)
-+        self._assert_render('3', template, context)
- 
-     def test_section__iterable(self):
-         """
-@@ -575,10 +577,10 @@ class RenderTests(unittest.TestCase, AssertStringMixin, AssertExceptionMixin):
-         template = '{{#iterable}}{{.}}{{/iterable}}'
- 
-         context = {'iterable': (i for i in range(3))}  # type 'generator'
--        self._assert_render(u'012', template, context)
-+        self._assert_render('012', template, context)
- 
--        context = {'iterable': xrange(4)}  # type 'xrange'
--        self._assert_render(u'0123', template, context)
-+        context = {'iterable': range(4)}  # type 'xrange'
-+        self._assert_render('0123', template, context)
- 
-         d = {'foo': 0, 'bar': 0}
-         # We don't know what order of keys we'll be given, but from the
-@@ -586,8 +588,8 @@ class RenderTests(unittest.TestCase, AssertStringMixin, AssertExceptionMixin):
-         #  "If items(), keys(), values(), iteritems(), iterkeys(), and
-         #   itervalues() are called with no intervening modifications to
-         #   the dictionary, the lists will directly correspond."
--        expected = u''.join(d.keys())
--        context = {'iterable': d.iterkeys()}  # type 'dictionary-keyiterator'
-+        expected = ''.join(list(d.keys()))
-+        context = {'iterable': iter(d.keys())}  # type 'dictionary-keyiterator'
-         self._assert_render(expected, template, context)
- 
-     def test_section__lambda__tag_in_output(self):
-@@ -605,7 +607,7 @@ class RenderTests(unittest.TestCase, AssertStringMixin, AssertExceptionMixin):
-         """
-         template = '{{#test}}Hi {{person}}{{/test}}'
-         context = {'person': 'Mom', 'test': (lambda text: text + " :)")}
--        self._assert_render(u'Hi Mom :)', template, context)
-+        self._assert_render('Hi Mom :)', template, context)
- 
-     def test_section__lambda__list(self):
-         """
-@@ -621,7 +623,7 @@ class RenderTests(unittest.TestCase, AssertStringMixin, AssertExceptionMixin):
-                    'lambdas': [lambda text: "~{{%s}}~" % text,
-                                lambda text: "#{{%s}}#" % text]}
- 
--        self._assert_render(u'<~bar~#bar#>', template, context)
-+        self._assert_render('<~bar~#bar#>', template, context)
- 
-     def test_section__lambda__mixed_list(self):
-         """
-@@ -636,7 +638,7 @@ class RenderTests(unittest.TestCase, AssertStringMixin, AssertExceptionMixin):
-         context = {'foo': 'bar',
-                    'lambdas': [lambda text: "~{{%s}}~" % text, 1]}
- 
--        self._assert_render(u'<~bar~foo>', template, context)
-+        self._assert_render('<~bar~foo>', template, context)
- 
-     def test_section__lambda__not_on_context_stack(self):
-         """
-@@ -653,7 +655,7 @@ class RenderTests(unittest.TestCase, AssertStringMixin, AssertExceptionMixin):
-         """
-         context = {'foo': 'bar', 'lambda': (lambda text: "{{.}}")}
-         template = '{{#foo}}{{#lambda}}blah{{/lambda}}{{/foo}}'
--        self._assert_render(u'bar', template, context)
-+        self._assert_render('bar', template, context)
- 
-     def test_section__lambda__no_reinterpolation(self):
-         """
-@@ -670,15 +672,15 @@ class RenderTests(unittest.TestCase, AssertStringMixin, AssertExceptionMixin):
-         """
-         template = '{{#planet}}{{#lambda}}dot{{/lambda}}{{/planet}}'
-         context = {'planet': 'Earth', 'dot': '~{{.}}~', 'lambda': (lambda text: "#{{%s}}#" % text)}
--        self._assert_render(u'#~{{.}}~#', template, context)
-+        self._assert_render('#~{{.}}~#', template, context)
- 
-     def test_comment__multiline(self):
-         """
-         Check that multiline comments are permitted.
- 
-         """
--        self._assert_render(u'foobar', 'foo{{! baz }}bar')
--        self._assert_render(u'foobar', 'foo{{! \nbaz }}bar')
-+        self._assert_render('foobar', 'foo{{! baz }}bar')
-+        self._assert_render('foobar', 'foo{{! \nbaz }}bar')
- 
-     def test_custom_delimiters__sections(self):
-         """
-@@ -689,7 +691,7 @@ class RenderTests(unittest.TestCase, AssertStringMixin, AssertExceptionMixin):
-         """
-         template = '{{=[[ ]]=}}[[#foo]]bar[[/foo]]'
-         context = {'foo': True}
--        self._assert_render(u'bar', template, context)
-+        self._assert_render('bar', template, context)
- 
-     def test_custom_delimiters__not_retroactive(self):
-         """
-@@ -698,7 +700,7 @@ class RenderTests(unittest.TestCase, AssertStringMixin, AssertExceptionMixin):
-         Test case for issue #35: https://github.com/defunkt/pystache/issues/35
- 
-         """
--        expected = u' {{foo}} '
-+        expected = ' {{foo}} '
-         self._assert_render(expected, '{{=$ $=}} {{foo}} ')
-         self._assert_render(expected, '{{=$ $=}} {{foo}} $={{ }}=$')  # was yielding u'  '.
- 
-@@ -713,7 +715,7 @@ class RenderTests(unittest.TestCase, AssertStringMixin, AssertExceptionMixin):
-         template = 'Hello, {{person.name}}. I see you are {{person.details.age}}.'
-         person = Attachable(name='Biggles', details={'age': 42})
-         context = {'person': person}
--        self._assert_render(u'Hello, Biggles. I see you are 42.', template, context)
-+        self._assert_render('Hello, Biggles. I see you are 42.', template, context)
- 
-     def test_dot_notation__multiple_levels(self):
-         """
-@@ -722,7 +724,7 @@ class RenderTests(unittest.TestCase, AssertStringMixin, AssertExceptionMixin):
-         """
-         template = """Hello, Mr. {{person.name.lastname}}.
-         I see you're back from {{person.travels.last.country.city}}."""
--        expected = u"""Hello, Mr. Pither.
-+        expected = """Hello, Mr. Pither.
-         I see you're back from Cornwall."""
-         context = {'person': {'name': {'firstname': 'unknown', 'lastname': 'Pither'},
-                             'travels': {'last': {'country': {'city': 'Cornwall'}}},
-@@ -758,10 +760,10 @@ class RenderTests(unittest.TestCase, AssertStringMixin, AssertExceptionMixin):
-         context = {'a': {'b': 'A.B'}, 'c': {'a': 'A'} }
- 
-         template = '{{a.b}}'
--        self._assert_render(u'A.B', template, context)
-+        self._assert_render('A.B', template, context)
- 
-         template = '{{#c}}{{a}}{{/c}}'
--        self._assert_render(u'A', template, context)
-+        self._assert_render('A', template, context)
- 
-         template = '{{#c}}{{a.b}}{{/c}}'
-         self.assertException(KeyNotFoundError, "Key %(unicode)s'a.b' not found: missing %(unicode)s'b'" %
-diff --git a/pystache/tests/test_renderer.py b/pystache/tests/test_renderer.py
-index 0dbe0d9..e0d2448 100644
---- a/pystache/tests/test_renderer.py
-+++ b/pystache/tests/test_renderer.py
-@@ -10,7 +10,7 @@ import os
- import sys
- import unittest
- 
--from examples.simple import Simple
-+from .examples.simple import Simple
- from pystache import Renderer
- from pystache import TemplateSpec
- from pystache.common import TemplateNotFoundError
-@@ -33,7 +33,7 @@ def _make_renderer():
- def mock_unicode(b, encoding=None):
-     if encoding is None:
-         encoding = 'ascii'
--    u = unicode(b, encoding=encoding)
-+    u = str(b, encoding=encoding)
-     return u.upper()
- 
- 
-@@ -197,13 +197,13 @@ class RendererTests(unittest.TestCase, AssertStringMixin):
- 
-         """
-         renderer = self._renderer()
--        b = u"é".encode('utf-8')
-+        b = "é".encode('utf-8')
- 
-         renderer.string_encoding = "ascii"
--        self.assertRaises(UnicodeDecodeError, renderer.unicode, b)
-+        self.assertRaises(UnicodeDecodeError, renderer.str, b)
- 
-         renderer.string_encoding = "utf-8"
--        self.assertEqual(renderer.unicode(b), u"é")
-+        self.assertEqual(renderer.str(b), "é")
- 
-     def test_unicode__decode_errors(self):
-         """
-@@ -212,14 +212,14 @@ class RendererTests(unittest.TestCase, AssertStringMixin):
-         """
-         renderer = self._renderer()
-         renderer.string_encoding = "ascii"
--        b = u"déf".encode('utf-8')
-+        b = "déf".encode('utf-8')
- 
-         renderer.decode_errors = "ignore"
--        self.assertEqual(renderer.unicode(b), "df")
-+        self.assertEqual(renderer.str(b), "df")
- 
-         renderer.decode_errors = "replace"
-         # U+FFFD is the official Unicode replacement character.
--        self.assertEqual(renderer.unicode(b), u'd\ufffd\ufffdf')
-+        self.assertEqual(renderer.str(b), u'd\ufffd\ufffdf')
- 
-     ## Test the _make_loader() method.
- 
-@@ -243,7 +243,7 @@ class RendererTests(unittest.TestCase, AssertStringMixin):
-         renderer = self._renderer()
-         renderer.file_encoding = 'enc'
-         renderer.file_extension = 'ext'
--        renderer.unicode = unicode_
-+        renderer.str = unicode_
- 
-         loader = renderer._make_loader()
- 
-@@ -260,12 +260,12 @@ class RendererTests(unittest.TestCase, AssertStringMixin):
-         """
-         renderer = self._renderer()
-         rendered = renderer.render('foo')
--        self.assertEqual(type(rendered), unicode)
-+        self.assertEqual(type(rendered), str)
- 
-     def test_render__unicode(self):
-         renderer = self._renderer()
--        actual = renderer.render(u'foo')
--        self.assertEqual(actual, u'foo')
-+        actual = renderer.render('foo')
-+        self.assertEqual(actual, 'foo')
- 
-     def test_render__str(self):
-         renderer = self._renderer()
-@@ -274,8 +274,8 @@ class RendererTests(unittest.TestCase, AssertStringMixin):
- 
-     def test_render__non_ascii_character(self):
-         renderer = self._renderer()
--        actual = renderer.render(u'Poincaré')
--        self.assertEqual(actual, u'Poincaré')
-+        actual = renderer.render('Poincaré')
-+        self.assertEqual(actual, 'Poincaré')
- 
-     def test_render__context(self):
-         """
-@@ -326,7 +326,7 @@ class RendererTests(unittest.TestCase, AssertStringMixin):
- 
-         """
-         renderer = _make_renderer()
--        template = u"déf".encode("utf-8")
-+        template = "déf".encode("utf-8")
- 
-         # Check that decode_errors and string_encoding are both respected.
-         renderer.decode_errors = 'ignore'
-@@ -334,7 +334,7 @@ class RendererTests(unittest.TestCase, AssertStringMixin):
-         self.assertEqual(renderer.render(template), "df")
- 
-         renderer.string_encoding = 'utf_8'
--        self.assertEqual(renderer.render(template), u"déf")
-+        self.assertEqual(renderer.render(template), "déf")
- 
-     def test_make_resolve_partial(self):
-         """
-@@ -347,7 +347,7 @@ class RendererTests(unittest.TestCase, AssertStringMixin):
- 
-         actual = resolve_partial('foo')
-         self.assertEqual(actual, 'bar')
--        self.assertEqual(type(actual), unicode, "RenderEngine requires that "
-+        self.assertEqual(type(actual), str, "RenderEngine requires that "
-             "resolve_partial return unicode strings.")
- 
-     def test_make_resolve_partial__unicode(self):
-@@ -362,7 +362,7 @@ class RendererTests(unittest.TestCase, AssertStringMixin):
-         self.assertEqual(resolve_partial("partial"), "foo")
- 
-         # Now with a value that is already unicode.
--        renderer.partials = {'partial': u'foo'}
-+        renderer.partials = {'partial': 'foo'}
-         resolve_partial = renderer._make_resolve_partial()
-         # If the next line failed, we would get the following error:
-         #   TypeError: decoding Unicode is not supported
-@@ -373,7 +373,7 @@ class RendererTests(unittest.TestCase, AssertStringMixin):
-         data_dir = get_data_path()
-         renderer = Renderer(search_dirs=data_dir)
-         actual = renderer.render_name("say_hello", to='foo')
--        self.assertString(actual, u"Hello, foo")
-+        self.assertString(actual, "Hello, foo")
- 
-     def test_render_path(self):
-         """
-@@ -412,7 +412,7 @@ class RendererTests(unittest.TestCase, AssertStringMixin):
- 
-         spec = Spec()
-         actual = renderer.render(spec)
--        self.assertString(actual, u'hello, world')
-+        self.assertString(actual, 'hello, world')
- 
-     def test_render__view(self):
-         """
-@@ -484,7 +484,7 @@ class Renderer_MakeRenderEngineTests(unittest.TestCase, AssertStringMixin, Asser
-         Check that resolve_partial returns unicode (and not a subclass).
- 
-         """
--        class MyUnicode(unicode):
-+        class MyUnicode(str):
-             pass
- 
-         renderer = Renderer()
-@@ -495,12 +495,12 @@ class Renderer_MakeRenderEngineTests(unittest.TestCase, AssertStringMixin, Asser
- 
-         actual = engine.resolve_partial('str')
-         self.assertEqual(actual, "foo")
--        self.assertEqual(type(actual), unicode)
-+        self.assertEqual(type(actual), str)
- 
-         # Check that unicode subclasses are not preserved.
-         actual = engine.resolve_partial('subclass')
-         self.assertEqual(actual, "abc")
--        self.assertEqual(type(actual), unicode)
-+        self.assertEqual(type(actual), str)
- 
-     def test__resolve_partial__not_found(self):
-         """
-@@ -512,7 +512,7 @@ class Renderer_MakeRenderEngineTests(unittest.TestCase, AssertStringMixin, Asser
-         engine = renderer._make_render_engine()
-         resolve_partial = engine.resolve_partial
- 
--        self.assertString(resolve_partial('foo'), u'')
-+        self.assertString(resolve_partial('foo'), '')
- 
-     def test__resolve_partial__not_found__missing_tags_strict(self):
-         """
-@@ -539,7 +539,7 @@ class Renderer_MakeRenderEngineTests(unittest.TestCase, AssertStringMixin, Asser
-         engine = renderer._make_render_engine()
-         resolve_partial = engine.resolve_partial
- 
--        self.assertString(resolve_partial('foo'), u'')
-+        self.assertString(resolve_partial('foo'), '')
- 
-     def test__resolve_partial__not_found__partials_dict__missing_tags_strict(self):
-         """
-@@ -566,12 +566,12 @@ class Renderer_MakeRenderEngineTests(unittest.TestCase, AssertStringMixin, Asser
- 
-         """
-         renderer = self._make_renderer()
--        renderer.unicode = mock_unicode
-+        renderer.str = mock_unicode
- 
-         engine = renderer._make_render_engine()
-         literal = engine.literal
- 
--        b = u"foo".encode("ascii")
-+        b = "foo".encode("ascii")
-         self.assertEqual(literal(b), "FOO")
- 
-     def test__literal__handles_unicode(self):
-@@ -585,7 +585,7 @@ class Renderer_MakeRenderEngineTests(unittest.TestCase, AssertStringMixin, Asser
-         engine = renderer._make_render_engine()
-         literal = engine.literal
- 
--        self.assertEqual(literal(u"foo"), "foo")
-+        self.assertEqual(literal("foo"), "foo")
- 
-     def test__literal__returns_unicode(self):
-         """
-@@ -598,16 +598,16 @@ class Renderer_MakeRenderEngineTests(unittest.TestCase, AssertStringMixin, Asser
-         engine = renderer._make_render_engine()
-         literal = engine.literal
- 
--        self.assertEqual(type(literal("foo")), unicode)
-+        self.assertEqual(type(literal("foo")), str)
- 
--        class MyUnicode(unicode):
-+        class MyUnicode(str):
-             pass
- 
-         s = MyUnicode("abc")
- 
-         self.assertEqual(type(s), MyUnicode)
--        self.assertTrue(isinstance(s, unicode))
--        self.assertEqual(type(literal(s)), unicode)
-+        self.assertTrue(isinstance(s, str))
-+        self.assertEqual(type(literal(s)), str)
- 
-     ## Test the engine's escape attribute.
- 
-@@ -630,12 +630,12 @@ class Renderer_MakeRenderEngineTests(unittest.TestCase, AssertStringMixin, Asser
- 
-         """
-         renderer = Renderer()
--        renderer.unicode = mock_unicode
-+        renderer.str = mock_unicode
- 
-         engine = renderer._make_render_engine()
-         escape = engine.escape
- 
--        b = u"foo".encode('ascii')
-+        b = "foo".encode('ascii')
-         self.assertEqual(escape(b), "FOO")
- 
-     def test__escape__has_access_to_original_unicode_subclass(self):
-@@ -644,16 +644,16 @@ class Renderer_MakeRenderEngineTests(unittest.TestCase, AssertStringMixin, Asser
- 
-         """
-         renderer = Renderer()
--        renderer.escape = lambda s: unicode(type(s).__name__)
-+        renderer.escape = lambda s: str(type(s).__name__)
- 
-         engine = renderer._make_render_engine()
-         escape = engine.escape
- 
--        class MyUnicode(unicode):
-+        class MyUnicode(str):
-             pass
- 
--        self.assertEqual(escape(u"foo".encode('ascii')), unicode.__name__)
--        self.assertEqual(escape(u"foo"), unicode.__name__)
-+        self.assertEqual(escape("foo".encode('ascii')), str.__name__)
-+        self.assertEqual(escape("foo"), str.__name__)
-         self.assertEqual(escape(MyUnicode("foo")), MyUnicode.__name__)
- 
-     def test__escape__returns_unicode(self):
-@@ -667,17 +667,17 @@ class Renderer_MakeRenderEngineTests(unittest.TestCase, AssertStringMixin, Asser
-         engine = renderer._make_render_engine()
-         escape = engine.escape
- 
--        self.assertEqual(type(escape("foo")), unicode)
-+        self.assertEqual(type(escape("foo")), str)
- 
-         # Check that literal doesn't preserve unicode subclasses.
--        class MyUnicode(unicode):
-+        class MyUnicode(str):
-             pass
- 
-         s = MyUnicode("abc")
- 
-         self.assertEqual(type(s), MyUnicode)
--        self.assertTrue(isinstance(s, unicode))
--        self.assertEqual(type(escape(s)), unicode)
-+        self.assertTrue(isinstance(s, str))
-+        self.assertEqual(type(escape(s)), str)
- 
-     ## Test the missing_tags attribute.
- 
-@@ -706,7 +706,7 @@ class Renderer_MakeRenderEngineTests(unittest.TestCase, AssertStringMixin, Asser
-         stack = ContextStack({'foo': 'bar'})
- 
-         self.assertEqual('bar', engine.resolve_context(stack, 'foo'))
--        self.assertString(u'', engine.resolve_context(stack, 'missing'))
-+        self.assertString('', engine.resolve_context(stack, 'missing'))
- 
-     def test__resolve_context__missing_tags_strict(self):
-         """
-diff --git a/pystache/tests/test_simple.py b/pystache/tests/test_simple.py
-index 07b059f..b88bf35 100644
---- a/pystache/tests/test_simple.py
-+++ b/pystache/tests/test_simple.py
-@@ -2,11 +2,11 @@ import unittest
- 
- import pystache
- from pystache import Renderer
--from examples.nested_context import NestedContext
--from examples.complex import Complex
--from examples.lambdas import Lambdas
--from examples.template_partial import TemplatePartial
--from examples.simple import Simple
-+from .examples.nested_context import NestedContext
-+from .examples.complex import Complex
-+from .examples.lambdas import Lambdas
-+from .examples.template_partial import TemplatePartial
-+from .examples.simple import Simple
- 
- from pystache.tests.common import EXAMPLES_DIR
- from pystache.tests.common import AssertStringMixin
-@@ -20,7 +20,7 @@ class TestSimple(unittest.TestCase, AssertStringMixin):
-         view.template = '{{#foo}}{{thing1}} and {{thing2}} and {{outer_thing}}{{/foo}}{{^foo}}Not foo!{{/foo}}'
- 
-         actual = renderer.render(view)
--        self.assertString(actual, u"one and foo and two")
-+        self.assertString(actual, "one and foo and two")
- 
-     def test_looping_and_negation_context(self):
-         template = '{{#item}}{{header}}: {{name}} {{/item}}{{^item}} Shouldnt see me{{/item}}'
-@@ -40,7 +40,7 @@ class TestSimple(unittest.TestCase, AssertStringMixin):
- 
-         renderer = Renderer()
-         actual = renderer.render(view)
--        self.assertString(actual, u'bar != bar. oh, it does!')
-+        self.assertString(actual, 'bar != bar. oh, it does!')
- 
-     def test_rendering_partial(self):
-         renderer = Renderer(search_dirs=EXAMPLES_DIR)
-@@ -49,11 +49,11 @@ class TestSimple(unittest.TestCase, AssertStringMixin):
-         view.template = '{{>inner_partial}}'
- 
-         actual = renderer.render(view)
--        self.assertString(actual, u'Again, Welcome!')
-+        self.assertString(actual, 'Again, Welcome!')
- 
-         view.template = '{{#looping}}{{>inner_partial}} {{/looping}}'
-         actual = renderer.render(view)
--        self.assertString(actual, u"Again, Welcome! Again, Welcome! Again, Welcome! ")
-+        self.assertString(actual, "Again, Welcome! Again, Welcome! Again, Welcome! ")
- 
-     def test_non_existent_value_renders_blank(self):
-         view = Simple()
-@@ -77,7 +77,7 @@ class TestSimple(unittest.TestCase, AssertStringMixin):
-         view = TemplatePartial(renderer=renderer)
- 
-         actual = renderer.render(view)
--        self.assertString(actual, u"""Welcome
-+        self.assertString(actual, """Welcome
- -------
- 
- ## Again, Welcome! ##""")
-diff --git a/pystache/tests/test_specloader.py b/pystache/tests/test_specloader.py
-index cacc0fc..dcdc55f 100644
---- a/pystache/tests/test_specloader.py
-+++ b/pystache/tests/test_specloader.py
-@@ -9,11 +9,11 @@ import os.path
- import sys
- import unittest
- 
--import examples
--from examples.simple import Simple
--from examples.complex import Complex
--from examples.lambdas import Lambdas
--from examples.inverted import Inverted, InvertedLists
-+from . import examples
-+from .examples.simple import Simple
-+from .examples.complex import Complex
-+from .examples.lambdas import Lambdas
-+from .examples.inverted import Inverted, InvertedLists
- from pystache import Renderer
- from pystache import TemplateSpec
- from pystache.common import TemplateNotFoundError
-@@ -70,7 +70,7 @@ class ViewTestCase(unittest.TestCase, AssertStringMixin):
-         renderer2 = Renderer(search_dirs=EXAMPLES_DIR)
- 
-         actual = renderer1.render(spec)
--        self.assertString(actual, u"Partial: ")
-+        self.assertString(actual, "Partial: ")
- 
-         actual = renderer2.render(spec)
-         self.assertEqual(actual, "Partial: No tags...")
-@@ -79,7 +79,7 @@ class ViewTestCase(unittest.TestCase, AssertStringMixin):
-         renderer = Renderer()
-         actual = renderer.render(Simple())
- 
--        self.assertString(actual, u"Hi pizza!")
-+        self.assertString(actual, "Hi pizza!")
- 
-     def test_non_callable_attributes(self):
-         view = Simple()
-@@ -92,7 +92,7 @@ class ViewTestCase(unittest.TestCase, AssertStringMixin):
-     def test_complex(self):
-         renderer = Renderer()
-         actual = renderer.render(Complex())
--        self.assertString(actual, u"""\
-+        self.assertString(actual, """\
- <h1>Colors</h1>
- <ul>
- <li><strong>red</strong></li>
-@@ -111,7 +111,7 @@ class ViewTestCase(unittest.TestCase, AssertStringMixin):
- 
-         renderer = Renderer()
-         actual = renderer.render(view)
--        self.assertString(actual, u'nopqrstuvwxyz')
-+        self.assertString(actual, 'nopqrstuvwxyz')
- 
-     def test_higher_order_lambda(self):
-         view = Lambdas()
-@@ -119,7 +119,7 @@ class ViewTestCase(unittest.TestCase, AssertStringMixin):
- 
-         renderer = Renderer()
-         actual = renderer.render(view)
--        self.assertString(actual, u'abcdefghijklmnopqrstuvwxyz')
-+        self.assertString(actual, 'abcdefghijklmnopqrstuvwxyz')
- 
-     def test_partials_with_lambda(self):
-         view = Lambdas()
-@@ -127,7 +127,7 @@ class ViewTestCase(unittest.TestCase, AssertStringMixin):
- 
-         renderer = Renderer(search_dirs=EXAMPLES_DIR)
-         actual = renderer.render(view)
--        self.assertEqual(actual, u'nopqrstuvwxyz')
-+        self.assertEqual(actual, 'nopqrstuvwxyz')
- 
-     def test_hierarchical_partials_with_lambdas(self):
-         view = Lambdas()
-@@ -135,12 +135,12 @@ class ViewTestCase(unittest.TestCase, AssertStringMixin):
- 
-         renderer = Renderer(search_dirs=EXAMPLES_DIR)
-         actual = renderer.render(view)
--        self.assertString(actual, u'nopqrstuvwxyznopqrstuvwxyz')
-+        self.assertString(actual, 'nopqrstuvwxyznopqrstuvwxyz')
- 
-     def test_inverted(self):
-         renderer = Renderer()
-         actual = renderer.render(Inverted())
--        self.assertString(actual, u"""one, two, three, empty list""")
-+        self.assertString(actual, """one, two, three, empty list""")
- 
-     def test_accessing_properties_on_parent_object_from_child_objects(self):
-         parent = Thing()
-@@ -152,12 +152,12 @@ class ViewTestCase(unittest.TestCase, AssertStringMixin):
-         renderer = Renderer()
-         actual = renderer.render(view, {'parent': parent})
- 
--        self.assertString(actual, u'derp')
-+        self.assertString(actual, 'derp')
- 
-     def test_inverted_lists(self):
-         renderer = Renderer()
-         actual = renderer.render(InvertedLists())
--        self.assertString(actual, u"""one, two, three, empty list""")
-+        self.assertString(actual, """one, two, three, empty list""")
- 
- 
- def _make_specloader():
-@@ -176,7 +176,7 @@ def _make_specloader():
-         """
-         if encoding is None:
-             encoding = 'ascii'
--        return unicode(s, encoding, 'strict')
-+        return str(s, encoding, 'strict')
- 
-     loader = Loader(file_encoding='ascii', to_unicode=to_unicode)
-     return SpecLoader(loader=loader)
-@@ -222,7 +222,7 @@ class SpecLoaderTests(unittest.TestCase, AssertIsMixin, AssertStringMixin,
-         custom.template = "abc"
- 
-         spec_loader = self._make_specloader()
--        self._assert_template(spec_loader, custom, u"abc")
-+        self._assert_template(spec_loader, custom, "abc")
- 
-     def test_load__template__type_unicode(self):
-         """
-@@ -230,10 +230,10 @@ class SpecLoaderTests(unittest.TestCase, AssertIsMixin, AssertStringMixin,
- 
-         """
-         custom = TemplateSpec()
--        custom.template = u"abc"
-+        custom.template = "abc"
- 
-         spec_loader = self._make_specloader()
--        self._assert_template(spec_loader, custom, u"abc")
-+        self._assert_template(spec_loader, custom, "abc")
- 
-     def test_load__template__unicode_non_ascii(self):
-         """
-@@ -241,10 +241,10 @@ class SpecLoaderTests(unittest.TestCase, AssertIsMixin, AssertStringMixin,
- 
-         """
-         custom = TemplateSpec()
--        custom.template = u"é"
-+        custom.template = "é"
- 
-         spec_loader = self._make_specloader()
--        self._assert_template(spec_loader, custom, u"é")
-+        self._assert_template(spec_loader, custom, "é")
- 
-     def test_load__template__with_template_encoding(self):
-         """
-@@ -252,14 +252,14 @@ class SpecLoaderTests(unittest.TestCase, AssertIsMixin, AssertStringMixin,
- 
-         """
-         custom = TemplateSpec()
--        custom.template = u'é'.encode('utf-8')
-+        custom.template = 'é'.encode('utf-8')
- 
-         spec_loader = self._make_specloader()
- 
--        self.assertRaises(UnicodeDecodeError, self._assert_template, spec_loader, custom, u'é')
-+        self.assertRaises(UnicodeDecodeError, self._assert_template, spec_loader, custom, 'é')
- 
-         custom.template_encoding = 'utf-8'
--        self._assert_template(spec_loader, custom, u'é')
-+        self._assert_template(spec_loader, custom, 'é')
- 
-     # TODO: make this test complete.
-     def test_load__template__correct_loader(self):
-@@ -279,10 +279,10 @@ class SpecLoaderTests(unittest.TestCase, AssertIsMixin, AssertStringMixin,
-                 self.encoding = None
- 
-             # Overrides the existing method.
--            def unicode(self, s, encoding=None):
-+            def str(self, s, encoding=None):
-                 self.s = s
-                 self.encoding = encoding
--                return u"foo"
-+                return "foo"
- 
-         loader = MockLoader()
-         custom_loader = SpecLoader()
-@@ -293,7 +293,7 @@ class SpecLoaderTests(unittest.TestCase, AssertIsMixin, AssertStringMixin,
-         view.template_encoding = "encoding-foo"
- 
-         # Check that our unicode() above was called.
--        self._assert_template(custom_loader, view, u'foo')
-+        self._assert_template(custom_loader, view, 'foo')
-         self.assertEqual(loader.s, "template-foo")
-         self.assertEqual(loader.encoding, "encoding-foo")
- 
-@@ -410,7 +410,7 @@ class TemplateSpecTests(unittest.TestCase, AssertPathsMixin):
-         loader = self._make_loader()
-         actual = loader.load(custom)
- 
--        self.assertEqual(type(actual), unicode)
-+        self.assertEqual(type(actual), str)
-         self.assertEqual(actual, expected)
- 
-     def test_get_template(self):
-@@ -420,7 +420,7 @@ class TemplateSpecTests(unittest.TestCase, AssertPathsMixin):
-         """
-         view = SampleView()
- 
--        self._assert_get_template(view, u"ascii: abc")
-+        self._assert_get_template(view, "ascii: abc")
- 
-     def test_get_template__template_encoding(self):
-         """
-@@ -432,4 +432,4 @@ class TemplateSpecTests(unittest.TestCase, AssertPathsMixin):
-         self.assertRaises(UnicodeDecodeError, self._assert_get_template, view, 'foo')
- 
-         view.template_encoding = 'utf-8'
--        self._assert_get_template(view, u"non-ascii: é")
-+        self._assert_get_template(view, "non-ascii: é")
-diff --git a/setup.cfg b/setup.cfg
-index 861a9f5..f6f1279 100644
---- a/setup.cfg
-+++ b/setup.cfg
-@@ -1,5 +1,71 @@
--[egg_info]
--tag_build = 
--tag_date = 0
--tag_svn_revision = 0
-+[metadata]
-+name = pystache
-+version = attr: pystache.__version__
-+author = Chris Wanstrath
-+author_email = chris@ozmm.org
-+maintainer = Steve Arnold
-+maintainer_email = nerdboy@gentoo.org
-+description = Mustache for Python
-+url = https://github.com/sarnold/pystache
-+license = MIT
-+license_files = LICENSE
-+classifiers =
-+    Development Status :: 4 - Beta
-+    Intended Audience :: Developers
-+    License :: OSI Approved :: MIT License
-+    Programming Language :: Python :: 3
-+    Programming Language :: Python :: 3.6
-+    Programming Language :: Python :: 3.7
-+    Programming Language :: Python :: 3.8
-+    Programming Language :: Python :: 3.9
- 
-+[options]
-+python_requires = >=3.6
-+zip_safe = True
-+include_package_data = True
-+packages = find:
-+
-+[options.package_data]
-+* = *.mustache, *.txt
-+
-+[options.entry_points]
-+console_scripts =
-+    pystache=pystache.commands.render:main
-+    pystache-test=pystache.commands.test:main
-+
-+[options.extras_require]
-+test =
-+    nose
-+
-+cov =
-+    coverage
-+
-+[bdist_wheel]
-+universal = 0
-+
-+[check-manifest]
-+ignore =
-+    .codeclimate.yml
-+    .gitattributes
-+    .coveragerc
-+    .gitignore
-+    .pep8speaks.yml
-+    codecov.yml
-+
-+[flake8]
-+exclude =
-+    .git,
-+    __pycache__,
-+    build,
-+    dist
-+
-+max-line-length = 110
-+
-+[nosetests]
-+traverse-namespace = 1
-+verbosity = 3
-+with-coverage = 1
-+with-doctest = 1
-+doctest-extension = rst
-+cover-package = pystache
-+cover-xml = 1
-diff --git a/setup.py b/setup.py
-index 0d99aae..f0b7d7f 100644
---- a/setup.py
-+++ b/setup.py
-@@ -28,7 +28,7 @@ it on the PyPI project page.  If PyPI finds any issues, it will render it
- instead as plain-text, which we do not want.
- 
- To check in advance that PyPI will accept and parse the reST file as HTML,
--you can use the rst2html program installed by the docutils package
-+you can use the rst2html.py program installed by the docutils package
- (http://docutils.sourceforge.net/).  To install docutils:
- 
-     $ pip install docutils
-@@ -89,30 +89,7 @@ import os
- import shutil
- import sys
- 
--
--py_version = sys.version_info
--
--# distutils does not seem to support the following setup() arguments.
--# It displays a UserWarning when setup() is passed those options:
--#
--#  * entry_points
--#  * install_requires
--#
--# distribute works with Python 2.3.5 and above:
--#
--#   http://packages.python.org/distribute/setuptools.html#building-and-distributing-packages-with-distribute
--#
--if py_version < (2, 3, 5):
--    # TODO: this might not work yet.
--    import distutils as dist
--    from distutils import core
--    setup = core.setup
--else:
--    import setuptools as dist
--    setup = dist.setup
--
--
--VERSION = '0.5.4'  # Also change in pystache/__init__.py.
-+from setuptools import setup
- 
- FILE_ENCODING = 'utf-8'
- 
-@@ -126,22 +103,6 @@ TEMP_EXTENSION = '.temp'
- 
- PREP_COMMAND = 'prep'
- 
--CLASSIFIERS = (
--    'Development Status :: 4 - Beta',
--    'License :: OSI Approved :: MIT License',
--    'Programming Language :: Python',
--    'Programming Language :: Python :: 2',
--    'Programming Language :: Python :: 2.4',
--    'Programming Language :: Python :: 2.5',
--    'Programming Language :: Python :: 2.6',
--    'Programming Language :: Python :: 2.7',
--    'Programming Language :: Python :: 3',
--    'Programming Language :: Python :: 3.1',
--    'Programming Language :: Python :: 3.2',
--    'Programming Language :: Python :: 3.3',
--    'Programming Language :: Python :: Implementation :: PyPy',
--)
--
- # Comments in reST begin with two dots.
- RST_LONG_DESCRIPTION_INTRO = """\
- .. Do not edit this file.  This file is auto-generated for PyPI by setup.py
-@@ -221,7 +182,7 @@ def convert_md_to_rst(md_path, rst_temp_path):
- 
-     """
-     # Pandoc uses the UTF-8 character encoding for both input and output.
--    command = "pandoc --write=rst --output=%s %s" % (rst_temp_path, md_path)
-+    command = "pandoc -f markdown-smart --write=rst --output=%s %s" % (rst_temp_path, md_path)
-     print("converting with pandoc: %s to %s\n-->%s" % (md_path, rst_temp_path,
-                                                        command))
- 
-@@ -308,65 +269,9 @@ Run the following command and commit the changes--
-     os.system('python setup.py sdist upload')
- 
- 
--# We use the package simplejson for older Python versions since Python
--# does not contain the module json before 2.6:
--#
--#   http://docs.python.org/library/json.html
--#
--# Moreover, simplejson stopped officially support for Python 2.4 in version 2.1.0:
--#
--#   https://github.com/simplejson/simplejson/blob/master/CHANGES.txt
--#
--requires = []
--if py_version < (2, 5):
--    requires.append('simplejson<2.1')
--elif py_version < (2, 6):
--    requires.append('simplejson')
--
--INSTALL_REQUIRES = requires
--
--# TODO: decide whether to use find_packages() instead.  I'm not sure that
--#   find_packages() is available with distutils, for example.
--PACKAGES = [
--    'pystache',
--    'pystache.commands',
--    # The following packages are only for testing.
--    'pystache.tests',
--    'pystache.tests.data',
--    'pystache.tests.data.locator',
--    'pystache.tests.examples',
--]
--
--
--# The purpose of this function is to follow the guidance suggested here:
--#
--#   http://packages.python.org/distribute/python3.html#note-on-compatibility-with-setuptools
--#
--# The guidance is for better compatibility when using setuptools (e.g. with
--# earlier versions of Python 2) instead of Distribute, because of new
--# keyword arguments to setup() that setuptools may not recognize.
--def get_extra_args():
--    """
--    Return a dictionary of extra args to pass to setup().
--
--    """
--    extra = {}
--    # TODO: it might be more correct to check whether we are using
--    #   Distribute instead of setuptools, since use_2to3 doesn't take
--    #   effect when using Python 2, even when using Distribute.
--    if py_version >= (3, ):
--        # Causes 2to3 to be run during the build step.
--        extra['use_2to3'] = True
--
--    return extra
--
--
- def main(sys_argv):
- 
-     # TODO: use the logging module instead of printing.
--    # TODO: include the following in a verbose mode.
--    sys.stderr.write("pystache: using: version %s of %s\n" % (repr(dist.__version__), repr(dist)))
--
-     command = sys_argv[-1]
- 
-     if command == 'publish':
-@@ -377,35 +282,10 @@ def main(sys_argv):
-         sys.exit()
- 
-     long_description = read(RST_DESCRIPTION_PATH)
--    template_files = ['*.mustache', '*.txt']
--    extra_args = get_extra_args()
--
--    setup(name='pystache',
--          version=VERSION,
--          license='MIT',
--          description='Mustache for Python',
--          long_description=long_description,
--          author='Chris Wanstrath',
--          author_email='chris@ozmm.org',
--          maintainer='Chris Jerdonek',
--          maintainer_email='chris.jerdonek@gmail.com',
--          url='http://github.com/defunkt/pystache',
--          install_requires=INSTALL_REQUIRES,
--          packages=PACKAGES,
--          package_data = {
--              # Include template files so tests can be run.
--              'pystache.tests.data': template_files,
--              'pystache.tests.data.locator': template_files,
--              'pystache.tests.examples': template_files,
--          },
--          entry_points = {
--            'console_scripts': [
--                'pystache=pystache.commands.render:main',
--                'pystache-test=pystache.commands.test:main',
--            ],
--          },
--          classifiers = CLASSIFIERS,
--          **extra_args
-+
-+    setup(
-+        long_description=long_description,
-+        long_description_content_type='text/x-rst',
-     )
- 
- 
-diff --git a/setup_description.rst b/setup_description.rst
-index 724c457..d7f1bc0 100644
---- a/setup_description.rst
-+++ b/setup_description.rst
-@@ -4,13 +4,17 @@
- Pystache
- ========
- 
--.. figure:: http://defunkt.github.com/pystache/images/logo_phillips.png
--   :alt: mustachioed, monocled snake by David Phillips
-+|ci| |Conda| |Wheels| |Release| |Python|
- 
--.. figure:: https://secure.travis-ci.org/defunkt/pystache.png
--   :alt: Travis CI current build status
-+|Latest release| |License| |Maintainability| |codecov|
- 
--`Pystache <http://defunkt.github.com/pystache>`__ is a Python
-+This updated fork of Pystache is currently tested on Python 3.6+ and in
-+Conda, on Linux, Macos, and Windows (Python 2.7 support has been
-+removed).
-+
-+|image9|
-+
-+`Pystache <http://sarnold.github.com/pystache>`__ is a Python
- implementation of `Mustache <http://mustache.github.com/>`__. Mustache
- is a framework-agnostic, logic-free templating system inspired by
- `ctemplate <http://code.google.com/p/google-ctemplate/>`__ and
-@@ -23,62 +27,45 @@ page provides a good introduction to Mustache's syntax. For a more
- complete (and more current) description of Mustache's behavior, see the
- official `Mustache spec <https://github.com/mustache/spec>`__.
- 
--Pystache is `semantically versioned <http://semver.org>`__ and can be
--found on `PyPI <http://pypi.python.org/pypi/pystache>`__. This version
--of Pystache passes all tests in `version
--1.1.2 <https://github.com/mustache/spec/tree/v1.1.2>`__ of the spec.
-+Pystache is `semantically versioned <http://semver.org>`__ and older
-+versions can still be found on
-+`PyPI <http://pypi.python.org/pypi/pystache>`__. This version of
-+Pystache now passes all tests in `version
-+1.1.3 <https://github.com/mustache/spec/tree/v1.1.3>`__ of the spec.
- 
- Requirements
- ------------
- 
- Pystache is tested with--
- 
---  Python 2.4 (requires simplejson `version
--   2.0.9 <http://pypi.python.org/pypi/simplejson/2.0.9>`__ or earlier)
---  Python 2.5 (requires
--   `simplejson <http://pypi.python.org/pypi/simplejson/>`__)
---  Python 2.6
---  Python 2.7
---  Python 3.1
---  Python 3.2
---  Python 3.3
---  `PyPy <http://pypy.org/>`__
-+-  Python 3.6
-+-  Python 3.7
-+-  Python 3.8
-+-  Python 3.9
-+-  Conda (py36-py39)
- 
- `Distribute <http://packages.python.org/distribute/>`__ (the setuptools
--fork) is recommended over
--`setuptools <http://pypi.python.org/pypi/setuptools>`__, and is required
--in some cases (e.g. for Python 3 support). If you use
--`pip <http://www.pip-installer.org/>`__, you probably already satisfy
--this requirement.
-+fork) is no longer required over
-+`setuptools <http://pypi.python.org/pypi/setuptools>`__, as the current
-+packaging is now PEP517-compliant.
- 
- JSON support is needed only for the command-line interface and to run
--the spec tests. We require simplejson for earlier versions of Python
--since Python's `json <http://docs.python.org/library/json.html>`__
--module was added in Python 2.6.
--
--For Python 2.4 we require an earlier version of simplejson since
--simplejson stopped officially supporting Python 2.4 in simplejson
--version 2.1.0. Earlier versions of simplejson can be installed manually,
--as follows:
--
--::
--
--    pip install 'simplejson<2.1.0'
-+the spec tests; PyYAML can still be used (see the Develop section).
- 
--Official support for Python 2.4 will end with Pystache version 0.6.0.
-+Official support for Python 2 will end with Pystache version 0.6.0.
- 
- Install It
- ----------
- 
- ::
- 
--    pip install pystache
-+   pip install -U pystache -f https://github.com/sarnold/pystache/releases/
- 
- And test it--
- 
- ::
- 
--    pystache-test
-+   pystache-test
- 
- To install and test from source (e.g. from GitHub), see the Develop
- section.
-@@ -88,68 +75,68 @@ Use It
- 
- ::
- 
--    >>> import pystache
--    >>> print pystache.render('Hi {{person}}!', {'person': 'Mom'})
--    Hi Mom!
-+   >>> import pystache
-+   >>> print(pystache.render('Hi {{person}}!', {'person': 'Mom'}))
-+   Hi Mom!
- 
- You can also create dedicated view classes to hold your view logic.
- 
--Here's your view class (in .../examples/readme.py):
-+Here's your view class (in ../pystache/tests/examples/readme.py):
- 
- ::
- 
--    class SayHello(object):
--        def to(self):
--            return "Pizza"
-+   class SayHello(object):
-+       def to(self):
-+           return "Pizza"
- 
- Instantiating like so:
- 
- ::
- 
--    >>> from pystache.tests.examples.readme import SayHello
--    >>> hello = SayHello()
-+   >>> from pystache.tests.examples.readme import SayHello
-+   >>> hello = SayHello()
- 
--Then your template, say\_hello.mustache (by default in the same
--directory as your class definition):
-+Then your template, say_hello.mustache (by default in the same directory
-+as your class definition):
- 
- ::
- 
--    Hello, {{to}}!
-+   Hello, {{to}}!
- 
- Pull it together:
- 
- ::
- 
--    >>> renderer = pystache.Renderer()
--    >>> print renderer.render(hello)
--    Hello, Pizza!
-+   >>> renderer = pystache.Renderer()
-+   >>> print(renderer.render(hello))
-+   Hello, Pizza!
- 
- For greater control over rendering (e.g. to specify a custom template
- directory), use the ``Renderer`` class like above. One can pass
- attributes to the Renderer class constructor or set them on a Renderer
- instance. To customize template loading on a per-view basis, subclass
- ``TemplateSpec``. See the docstrings of the
--`Renderer <https://github.com/defunkt/pystache/blob/master/pystache/renderer.py>`__
-+`Renderer <https://github.com/sarnold/pystache/blob/master/pystache/renderer.py>`__
- class and
--`TemplateSpec <https://github.com/defunkt/pystache/blob/master/pystache/template_spec.py>`__
-+`TemplateSpec <https://github.com/sarnold/pystache/blob/master/pystache/template_spec.py>`__
- class for more information.
- 
- You can also pre-parse a template:
- 
- ::
- 
--    >>> parsed = pystache.parse(u"Hey {{#who}}{{.}}!{{/who}}")
--    >>> print parsed
--    [u'Hey ', _SectionNode(key=u'who', index_begin=12, index_end=18, parsed=[_EscapeNode(key=u'.'), u'!'])]
-+   >>> parsed = pystache.parse(u"Hey {{#who}}{{.}}!{{/who}}")
-+   >>> print(parsed)
-+   ['Hey ', _SectionNode(key='who', index_begin=12, index_end=18, parsed=[_EscapeNode(key='.'), '!'])]
- 
- And then:
- 
- ::
- 
--    >>> print renderer.render(parsed, {'who': 'Pops'})
--    Hey Pops!
--    >>> print renderer.render(parsed, {'who': 'you'})
--    Hey you!
-+   >>> print(renderer.render(parsed, {'who': 'Pops'}))
-+   Hey Pops!
-+   >>> print(renderer.render(parsed, {'who': 'you'}))
-+   Hey you!
- 
- Python 3
- --------
-@@ -211,22 +198,24 @@ To test from a source distribution (without installing)--
- 
- ::
- 
--    python test_pystache.py
-+   python test_pystache.py
- 
- To test Pystache with multiple versions of Python (with a single
--command!), you can use `tox <http://pypi.python.org/pypi/tox>`__:
-+command!) and different platforms, you can use
-+`tox <http://pypi.python.org/pypi/tox>`__:
- 
- ::
- 
--    pip install 'virtualenv<1.8'  # Version 1.8 dropped support for Python 2.4.
--    pip install 'tox<1.4'  # Version 1.4 dropped support for Python 2.4.
--    tox
-+   pip install tox
-+   tox -e setup
- 
--If you do not have all Python versions listed in ``tox.ini``--
-+To run tests on multiple versions with coverage, run:
- 
- ::
- 
--    tox -e py26,py32  # for example
-+   tox -e py38-linux,py39-linux  # for example
-+
-+(substitute your platform above, eg, macos or windows)
- 
- The source distribution tests also include doctests and tests from the
- Mustache spec. To include tests from the Mustache spec in your test
-@@ -234,8 +223,8 @@ runs:
- 
- ::
- 
--    git submodule init
--    git submodule update
-+   git submodule init
-+   git submodule update
- 
- The test harness parses the spec's (more human-readable) yaml files if
- `PyYAML <http://pypi.python.org/pypi/PyYAML>`__ is present. Otherwise,
-@@ -243,94 +232,113 @@ it parses the json files. To install PyYAML--
- 
- ::
- 
--    pip install pyyaml
-+   pip install pyyaml
-+
-+Once the submodule is available, you can run the full test set with:
-+
-+::
-+
-+   tox -e setup . ext/spec/specs
- 
- To run a subset of the tests, you can use
- `nose <http://somethingaboutorange.com/mrl/projects/nose/0.11.1/testing.html>`__:
- 
- ::
- 
--    pip install nose
--    nosetests --tests pystache/tests/test_context.py:GetValueTests.test_dictionary__key_present
-+   pip install nose
-+   nosetests --tests pystache/tests/test_context.py:GetValueTests.test_dictionary__key_present
- 
--Using Python 3 with Pystache from source
--~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-+Mailing List (old)
-+------------------
- 
--Pystache is written in Python 2 and must be converted to Python 3 prior
--to using it with Python 3. The installation process (and tox) do this
--automatically.
-+There is(was) a `mailing
-+list <http://librelist.com/browser/pystache/>`__. Note that there is a
-+bit of a delay between posting a message and seeing it appear in the
-+mailing list archive.
- 
--To convert the code to Python 3 manually (while using Python 3)--
-+Credits
-+-------
- 
- ::
- 
--    python setup.py build
-+   >>> import pystache
-+   >>> context = { 'author': 'Chris Wanstrath', 'maintainer': 'Chris Jerdonek','refurbisher': 'Steve Arnold' }
-+   >>> print(pystache.render("Author: {{author}}\nMaintainer: {{maintainer}}\nRefurbisher: {{refurbisher}}", context))
-+   Author: Chris Wanstrath
-+   Maintainer: Chris Jerdonek
-+   Refurbisher: Steve Arnold
- 
--This writes the converted code to a subdirectory called ``build``. By
--design, Python 3 builds
--`cannot <https://bitbucket.org/tarek/distribute/issue/292/allow-use_2to3-with-python-2>`__
--be created from Python 2.
-+Pystache logo by `David Phillips <http://davidphillips.us/>`__ is
-+licensed under a `Creative Commons Attribution-ShareAlike 3.0 Unported
-+License <http://creativecommons.org/licenses/by-sa/3.0/deed.en_US>`__.
-+|image10|
- 
--To convert the code without using setup.py, you can use
--`2to3 <http://docs.python.org/library/2to3.html>`__ as follows (two
--steps)--
-+History
-+=======
- 
--::
-+**Note:** Official support for Python 2.7 will end with Pystache version
-+0.6.0.
- 
--    2to3 --write --nobackups --no-diffs --doctests_only pystache
--    2to3 --write --nobackups --no-diffs pystache
-+0.6.0 (2021-03-04)
-+------------------
- 
--This converts the code (and doctests) in place.
-+-  Bump spec versions to latest => v1.1.3
-+-  Modernize python and CI tools, update docs/doctests
-+-  Update unicode conversion test for py3-only
-+-  Add pep8speaks cfg, cleanup warnings
-+-  Remove superfluous setup test/unused imports
-+-  Add conda recipe/CI build
- 
--To ``import pystache`` from a source distribution while using Python 3,
--be sure that you are importing from a directory containing a converted
--version of the code (e.g. from the ``build`` directory after
--converting), and not from the original (unconverted) source directory.
--Otherwise, you will get a syntax error. You can help prevent this by not
--running the Python IDE from the project directory when importing
--Pystache while using Python 3.
-+.. _section-1:
- 
--Mailing List
--------------
-+0.5.6 (2021-02-28)
-+------------------
- 
--There is a `mailing list <http://librelist.com/browser/pystache/>`__.
--Note that there is a bit of a delay between posting a message and seeing
--it appear in the mailing list archive.
-+-  Use correct wheel name in release workflow, limit wheels
-+-  Add install check/test of downloaded wheel
-+-  Update/add ci workflows and tox cfg, bump to next dev0 version
- 
--Credits
---------
-+.. _section-2:
- 
--::
-+0.5.5 (2020-12-16)
-+------------------
- 
--    >>> context = { 'author': 'Chris Wanstrath', 'maintainer': 'Chris Jerdonek' }
--    >>> print pystache.render("Author: {{author}}\nMaintainer: {{maintainer}}", context)
--    Author: Chris Wanstrath
--    Maintainer: Chris Jerdonek
-+-  fix document processing, update pandoc args and history
-+-  add release.yml to CI, test env settings
-+-  fix bogus commit message, update versions and tox cf
-+-  add post-test steps for building pkgs with/without doc updates
-+-  add CI build check, fix MANIFEST.in pruning
- 
--Pystache logo by `David Phillips <http://davidphillips.us/>`__ is
--licensed under a `Creative Commons Attribution-ShareAlike 3.0 Unported
--License <http://creativecommons.org/licenses/by-sa/3.0/deed.en_US>`__.
--|image0|
-+.. _section-3:
- 
--History
--=======
-+0.5.4-2 (2020-11-09)
-+--------------------
- 
--**Note:** Official support for Python 2.4 will end with Pystache version
--0.6.0.
-+-  Merge pull request #1 from sarnold/rebase-up
-+-  Bugfix: test_specloader.py: fix test_find__with_directory on other
-+   OSs
-+-  Bugfix: pystache/loader.py: remove stray windows line-endings
-+-  fix crufty (and insecure) http urls
-+-  Bugfix: modernize python versions (keep py27) and fix spec_test load
-+   cmd
-+
-+.. _section-4:
- 
- 0.5.4 (2014-07-11)
- ------------------
- 
- -  Bugfix: made test with filenames OS agnostic (issue #162).
- 
-+.. _section-5:
-+
- 0.5.3 (2012-11-03)
- ------------------
- 
- -  Added ability to customize string coercion (e.g. to have None render
-    as ``''``) (issue #130).
---  Added Renderer.render\_name() to render a template by name (issue
-+-  Added Renderer.render_name() to render a template by name (issue
-    #122).
---  Added TemplateSpec.template\_path to specify an absolute path to a
-+-  Added TemplateSpec.template_path to specify an absolute path to a
-    template (issue #41).
- -  Added option of raising errors on missing tags/partials:
-    ``Renderer(missing_tags='strict')`` (issue #110).
-@@ -355,6 +363,8 @@ History
- -  More robust handling of byte strings in Python 3.
- -  Added Creative Commons license for David Phillips's logo.
- 
-+.. _section-6:
-+
- 0.5.2 (2012-05-03)
- ------------------
- 
-@@ -367,16 +377,20 @@ History
-    context stack (issue #113).
- -  Bugfix: lists of lambdas for sections were not rendered (issue #114).
- 
-+.. _section-7:
-+
- 0.5.1 (2012-04-24)
- ------------------
- 
- -  Added support for Python 3.1 and 3.2.
- -  Added tox support to test multiple Python versions.
- -  Added test script entry point: pystache-test.
---  Added \_\_version\_\_ package attribute.
-+-  Added \__version_\_ package attribute.
- -  Test harness now supports both YAML and JSON forms of Mustache spec.
- -  Test harness no longer requires nose.
- 
-+.. _section-8:
-+
- 0.5.0 (2012-04-03)
- ------------------
- 
-@@ -435,11 +449,15 @@ Bug fixes:
- -  Passing ``**kwargs`` to ``Template()`` with no context no longer
-    raises an exception.
- 
-+.. _section-9:
-+
- 0.4.1 (2012-03-25)
- ------------------
- 
- -  Added support for Python 2.4. [wangtz, jvantuyl]
- 
-+.. _section-10:
-+
- 0.4.0 (2011-01-12)
- ------------------
- 
-@@ -447,19 +465,25 @@ Bug fixes:
- -  Add support for inverted lists
- -  Decoupled template loading
- 
-+.. _section-11:
-+
- 0.3.1 (2010-05-07)
- ------------------
- 
- -  Fix package
- 
-+.. _section-12:
-+
- 0.3.0 (2010-05-03)
- ------------------
- 
---  View.template\_path can now hold a list of path
-+-  View.template_path can now hold a list of path
- -  Add {{& blah}} as an alias for {{{ blah }}}
- -  Higher Order Sections
- -  Inverted sections
- 
-+.. _section-13:
-+
- 0.2.0 (2010-02-15)
- ------------------
- 
-@@ -473,12 +497,16 @@ Bug fixes:
-    [enaeseth]
- -  Template file encoding awareness. [enaeseth]
- 
-+.. _section-14:
-+
- 0.1.1 (2009-11-13)
- ------------------
- 
- -  Ensure we're dealing with strings, always
- -  Tests can be run by executing the test file directly
- 
-+.. _section-15:
-+
- 0.1.0 (2009-11-12)
- ------------------
- 
-@@ -510,4 +538,23 @@ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- 
--.. |image0| image:: http://i.creativecommons.org/l/by-sa/3.0/88x31.png
-+.. |ci| image:: https://github.com/sarnold/pystache/actions/workflows/ci.yml/badge.svg
-+   :target: https://github.com/sarnold/pystache/actions/workflows/ci.yml
-+.. |Conda| image:: https://github.com/sarnold/pystache/actions/workflows/conda.yml/badge.svg
-+   :target: https://github.com/sarnold/pystache/actions/workflows/conda.yml
-+.. |Wheels| image:: https://github.com/sarnold/pystache/actions/workflows/wheels.yml/badge.svg
-+   :target: https://github.com/sarnold/pystache/actions/workflows/wheels.yml
-+.. |Release| image:: https://github.com/sarnold/pystache/actions/workflows/release.yml/badge.svg
-+   :target: https://github.com/sarnold/pystache/actions/workflows/release.yml
-+.. |Python| image:: https://img.shields.io/badge/python-3.6+-blue.svg
-+   :target: https://www.python.org/downloads/
-+.. |Latest release| image:: https://img.shields.io/github/v/release/sarnold/pystache?include_prereleases
-+   :target: https://github.com/sarnold/pystache/releases/latest
-+.. |License| image:: https://img.shields.io/github/license/sarnold/pystache
-+   :target: https://github.com/sarnold/pystache/blob/master/LICENSE
-+.. |Maintainability| image:: https://api.codeclimate.com/v1/badges/a8fa1bf4638bfc6581b6/maintainability
-+   :target: https://codeclimate.com/github/sarnold/pystache/maintainability
-+.. |codecov| image:: https://codecov.io/gh/sarnold/pystache/branch/master/graph/badge.svg?token=5PZNMZBI6K
-+   :target: https://codecov.io/gh/sarnold/pystache
-+.. |image9| image:: gh/images/logo_phillips_small.png
-+.. |image10| image:: http://i.creativecommons.org/l/by-sa/3.0/88x31.png
-diff --git a/tox.ini b/tox.ini
-index d1eaebf..66c4515 100644
---- a/tox.ini
-+++ b/tox.ini
-@@ -1,36 +1,110 @@
--# A tox configuration file to test across multiple Python versions.
--#
--#   http://pypi.python.org/pypi/tox
--#
- [tox]
--# Tox 1.4 drops py24 and adds py33.  In the current version, we want to
--# support 2.4, so we can't simultaneously support 3.3.
--envlist = py24,py25,py26,py27,py27-yaml,py27-noargs,py31,py32,pypy
-+envlist = py{36,37,38,39}-{linux,macos,windows}
-+skip_missing_interpreters = true
-+isolated_build = true
-+#skipsdist = true
-+
-+[gh-actions]
-+python =
-+    3.6: py36
-+    3.7: py37
-+    3.8: py38
-+    3.9: py39
-+
-+[gh-actions:env]
-+PLATFORM =
-+    ubuntu-18.04: linux
-+    macos-latest: macos
-+    windows-latest: windows
- 
- [testenv]
-+passenv = CI PYTHON PYTHONIOENCODING
-+
-+deps =
-+    pip>=20.0.1
-+    nose
-+    coverage
-+
-+commands =
-+    nosetests -sx . {posargs}
-+
-+[testenv:bare]
- # Change the working directory so that we don't import the pystache located
- # in the original location.
-+deps =
-+    pip>=20.0.1
-+    -e .
-+
- changedir =
-     {envbindir}
-+
- commands =
--    pystache-test {toxinidir}
-+    pystache-test
-+
-+[testenv:bench]
-+passenv = CI PYTHON PYTHONIOENCODING
- 
--# Check that the spec tests work with PyYAML.
--[testenv:py27-yaml]
--basepython =
--    python2.7
- deps =
--    PyYAML
--changedir =
--    {envbindir}
-+    pip>=20.0.1
-+    # uncomment for comparison, posargs expects a number, eg, 10000
-+    #chevron
-+
-+commands_pre =
-+    pip install .
-+
- commands =
--    pystache-test {toxinidir}
-+    python pystache/tests/benchmark.py {posargs}
-+
-+[testenv:setup]
-+passenv = CI PYTHON PYTHONIOENCODING
-+
-+deps =
-+    pyyaml
-+    twine
-+
-+commands =
-+    python setup.py install
-+    twine check dist/*
-+    pystache-test {posargs}
-+
-+[testenv:deploy]
-+passenv = CI PYTHON PYTHONIOENCODING
-+allowlist_externals = bash
-+
-+deps =
-+    pip>=19.0.1
-+    wheel
-+    pep517
-+    twine
-+
-+commands =
-+    python -m pep517.build .
-+    twine check dist/*
-+
-+[testenv:check]
-+passenv = CI PYTHON PYTHONIOENCODING
-+skip_install = true
-+
-+allowlist_externals = bash
-+
-+deps =
-+    pip>=20.0.1
- 
--# Check that pystache-test works from an install with no arguments.
--[testenv:py27-noargs]
--basepython =
--    python2.7
--changedir =
--    {envbindir}
- commands =
-+    bash -c 'export WHL_FILE=$(ls dist/*.whl); \
-+        python -m pip install $WHL_FILE'
-     pystache-test
-+
-+[testenv:docs]
-+passenv = CI PYTHON PYTHONIOENCODING
-+allowlist_externals = bash
-+
-+deps =
-+    pip>=19.0.1
-+    wheel
-+    docutils
-+    # apt/emerge pandoc first
-+
-+commands =
-+    python setup.py prep
-+    bash -c 'python setup.py --long-description | rst2html.py -v --no-raw > out.html'
-diff --git a/travis.yml_disabled b/travis.yml_disabled
-new file mode 100644
-index 0000000..f0b4042
---- /dev/null
-+++ b/travis.yml_disabled
-@@ -0,0 +1,52 @@
-+dist: xenial
-+language: python
-+
-+# Travis CI has no plans to support Jython and no longer supports Python 2.5.
-+python:
-+  - "2.7"
-+  - "3.5"
-+  - "3.6"
-+  - "3.7"
-+  - "3.8"
-+  - "3.9-dev"
-+  - "nightly"
-+
-+matrix:
-+  fast_finish: true
-+  include:
-+    - os: osx
-+      # osx is goofy, ``python`` is always py2, images mutate fast
-+      language: shell
-+      before_install:
-+        - pip3 install --upgrade pip wheel
-+      install:
-+        - python3 setup.py install
-+      script:
-+        - pystache-test . ext/spec/specs
-+    - os: windows
-+      # windows is even goofier, install path is different for python/python3
-+      # but either way you get python3 and the cmd is always ``python``  o.O 
-+      # (also versions mutuate like bacteria)
-+      language: shell
-+      before_install:
-+        - choco install python3 --params "/InstallDir:C:\\Python"
-+        - python -m pip install --upgrade pip wheel
-+      env: PATH="/c/Python:/c/Python/Scripts:$PATH"
-+      install:
-+        - python setup.py install
-+      script:
-+        - pystache-test . ext/spec/specs
-+  allow_failures:
-+    - python: "nightly"
-+
-+# command to install dependencies
-+install:
-+  - pip install --upgrade pip
-+  - pip install codecov
-+
-+script:
-+  - python setup.py install
-+  # Include the spec tests directory for Mustache spec tests and the
-+  # project directory for doctests.
-+  - pystache-test . ext/spec/specs
-+  #- tox
--- 
-2.33.0
-
diff --git a/meta-python/recipes-devtools/python/python3-pystache_0.5.4.bb b/meta-python/recipes-devtools/python/python3-pystache_0.5.4.bb
deleted file mode 100644
index 0ae5a19115..0000000000
--- a/meta-python/recipes-devtools/python/python3-pystache_0.5.4.bb
+++ /dev/null
@@ -1,17 +0,0 @@
-SUMMARY = "Python implementation of Mustache"
-HOMEPAGE = "https://github.com/defunkt/pystache"
-LICENSE = "MIT"
-LIC_FILES_CHKSUM = "file://LICENSE;md5=eb4417802c56384aac71b34505528a60"
-
-SRC_URI += "file://0001-Modernize-python-versions-remove-py2x-and-fix-tests-.patch"
-
-SRC_URI[md5sum] = "485885e67a0f6411d5252e69b20a35ca"
-SRC_URI[sha256sum] = "f7bbc265fb957b4d6c7c042b336563179444ab313fb93a719759111eabd3b85a"
-
-inherit pypi setuptools3
-
-RDEPENDS:${PN} += " \
-    ${PYTHON_PN}-netserver \
-"
-
-BBCLASSEXTEND = "native nativesdk"
-- 
2.25.1



^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH 3/9] python3-configparser: remove, not needed for Python 3
  2022-03-10 13:25 [PATCH 1/9] packagegroup-meta-python: add poetry-core and unattended-upgrade Ross Burton
  2022-03-10 13:25 ` [PATCH 2/9] python3-pystache: remove, unmaintained Ross Burton
@ 2022-03-10 13:25 ` Ross Burton
  2022-03-10 13:25 ` [PATCH 4/9] python3-backports-functional-lru-cache: " Ross Burton
                   ` (5 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Ross Burton @ 2022-03-10 13:25 UTC (permalink / raw)
  To: openembedded-devel

This is a backport of the Python 3 configparser for Python 2 users, so
obviously it makes no sense to have for Python 3.

Signed-off-by: Ross Burton <ross.burton@arm.com>
---
 .../packagegroups/packagegroup-meta-python.bb       |  1 -
 .../python/python3-configparser_5.2.0.bb            | 13 -------------
 2 files changed, 14 deletions(-)
 delete mode 100644 meta-python/recipes-devtools/python/python3-configparser_5.2.0.bb

diff --git a/meta-python/recipes-core/packagegroups/packagegroup-meta-python.bb b/meta-python/recipes-core/packagegroups/packagegroup-meta-python.bb
index ae454e789b..6eb803bd2a 100644
--- a/meta-python/recipes-core/packagegroups/packagegroup-meta-python.bb
+++ b/meta-python/recipes-core/packagegroups/packagegroup-meta-python.bb
@@ -82,7 +82,6 @@ RDEPENDS:packagegroup-meta-python3 = "\
     python3-colorzero \
     python3-configargparse \
     python3-configobj \
-    python3-configparser \
     python3-configshell-fb \
     python3-constantly \
     python3-contextlib2 \
diff --git a/meta-python/recipes-devtools/python/python3-configparser_5.2.0.bb b/meta-python/recipes-devtools/python/python3-configparser_5.2.0.bb
deleted file mode 100644
index e629331330..0000000000
--- a/meta-python/recipes-devtools/python/python3-configparser_5.2.0.bb
+++ /dev/null
@@ -1,13 +0,0 @@
-SUMMARY = "This module provides the ConfigParser class which implements a basic configuration language which provides a structure similar to what's found in Microsoft Windows INI files."
-SECTION = "devel/python"
-HOMEPAGE = "https://docs.python.org/3/library/configparser.html"
-LICENSE = "MIT"
-
-LIC_FILES_CHKSUM = "file://PKG-INFO;beginline=10;endline=10;md5=23f9ad5cad3d8cc0336e2a5d8a87e1fa"
-
-SRC_URI[sha256sum] = "1b35798fdf1713f1c3139016cfcbc461f09edbf099d1fb658d4b7479fcaa3daa"
-
-DEPENDS += "${PYTHON_PN}-setuptools-scm-native ${PYTHON_PN}-toml-native"
-inherit pypi setuptools3
-
-BBCLASSEXTEND = "native nativesdk"
-- 
2.25.1



^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH 4/9] python3-backports-functional-lru-cache: remove, not needed for Python 3
  2022-03-10 13:25 [PATCH 1/9] packagegroup-meta-python: add poetry-core and unattended-upgrade Ross Burton
  2022-03-10 13:25 ` [PATCH 2/9] python3-pystache: remove, unmaintained Ross Burton
  2022-03-10 13:25 ` [PATCH 3/9] python3-configparser: remove, not needed for Python 3 Ross Burton
@ 2022-03-10 13:25 ` Ross Burton
  2022-03-10 13:25 ` [PATCH 5/9] python3-pyzmq: clean up recipe Ross Burton
                   ` (4 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Ross Burton @ 2022-03-10 13:25 UTC (permalink / raw)
  To: openembedded-devel

This is a backport of the Python 3 lru_cache for Python 2 users, so
obviously it makes no sense to have for Python 3.

Signed-off-by: Ross Burton <ross.burton@arm.com>
---
 .../packagegroups/packagegroup-meta-python.bb |  2 --
 ...on3-backports-functools-lru-cache_1.6.4.bb | 31 -------------------
 2 files changed, 33 deletions(-)
 delete mode 100644 meta-python/recipes-devtools/python/python3-backports-functools-lru-cache_1.6.4.bb

diff --git a/meta-python/recipes-core/packagegroups/packagegroup-meta-python.bb b/meta-python/recipes-core/packagegroups/packagegroup-meta-python.bb
index 6eb803bd2a..66a11d2dd9 100644
--- a/meta-python/recipes-core/packagegroups/packagegroup-meta-python.bb
+++ b/meta-python/recipes-core/packagegroups/packagegroup-meta-python.bb
@@ -46,7 +46,6 @@ RDEPENDS:packagegroup-meta-python3 = "\
     python3-aws-iot-device-sdk-python \
     python3-babel \
     python3-backcall \
-    python3-backports-functools-lru-cache \
     python3-bandit \
     python3-bcrypt \
     python3-beautifulsoup4 \
@@ -484,7 +483,6 @@ RDEPENDS:packagegroup-meta-python3-ptest = "\
     python3-markupsafe-ptest \
     python3-ansicolors-ptest \
     python3-appdirs-ptest \
-    python3-backports-functools-lru-cache-ptest \
     python3-bcrypt-ptest \
     python3-betamax-ptest \
     python3-blinker-ptest \
diff --git a/meta-python/recipes-devtools/python/python3-backports-functools-lru-cache_1.6.4.bb b/meta-python/recipes-devtools/python/python3-backports-functools-lru-cache_1.6.4.bb
deleted file mode 100644
index 392c044bfc..0000000000
--- a/meta-python/recipes-devtools/python/python3-backports-functools-lru-cache_1.6.4.bb
+++ /dev/null
@@ -1,31 +0,0 @@
-SUMMARY = "Backport of functools.lru_cache from Python 3.3"
-HOMEPAGE = "https://github.com/jaraco/backports.functools_lru_cache"
-SECTION = "devel/python"
-LICENSE = "MIT"
-LIC_FILES_CHKSUM = "file://LICENSE;md5=7a7126e068206290f3fe9f8d6c713ea6"
-
-PYPI_PACKAGE = "backports.functools_lru_cache"
-
-SRC_URI[sha256sum] = "d5ed2169378b67d3c545e5600d363a923b09c456dab1593914935a68ad478271"
-
-DEPENDS += "${PYTHON_PN}-setuptools-scm-native"
-
-inherit pypi setuptools3 ptest
-
-SRC_URI += " \
-	file://run-ptest \
-"
-
-RDEPENDS:${PN}-ptest += " \
-	${PYTHON_PN}-pytest \
-"
-
-do_install_ptest() {
-	install -d ${D}${PTEST_PATH}/tests
-	cp -rf ${S}/tests/* ${D}${PTEST_PATH}/tests/
-}
-
-RDEPENDS:${PN} += "\
-    ${PYTHON_PN}-pickle \
-    ${PYTHON_PN}-threading \
-    "
-- 
2.25.1



^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH 5/9] python3-pyzmq: clean up recipe
  2022-03-10 13:25 [PATCH 1/9] packagegroup-meta-python: add poetry-core and unattended-upgrade Ross Burton
                   ` (2 preceding siblings ...)
  2022-03-10 13:25 ` [PATCH 4/9] python3-backports-functional-lru-cache: " Ross Burton
@ 2022-03-10 13:25 ` Ross Burton
  2022-03-10 13:25 ` [PATCH 6/9] python3-pycurl: fix DEPENDS Ross Burton
                   ` (3 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Ross Burton @ 2022-03-10 13:25 UTC (permalink / raw)
  To: openembedded-devel

Put the patch into a directory named after PN to avoid needing to set
FILESEXTRAPATHS.

Remove explicit FILES:${PN}-dbg, as these are packaged automatically.

Signed-off-by: Ross Burton <ross.burton@arm.com>
---
 .../{python-pyzmq => python3-pyzmq}/club-rpath-out.patch      | 0
 meta-python/recipes-devtools/python/python3-pyzmq_22.3.0.bb   | 4 ----
 2 files changed, 4 deletions(-)
 rename meta-python/recipes-devtools/python/{python-pyzmq => python3-pyzmq}/club-rpath-out.patch (100%)

diff --git a/meta-python/recipes-devtools/python/python-pyzmq/club-rpath-out.patch b/meta-python/recipes-devtools/python/python3-pyzmq/club-rpath-out.patch
similarity index 100%
rename from meta-python/recipes-devtools/python/python-pyzmq/club-rpath-out.patch
rename to meta-python/recipes-devtools/python/python3-pyzmq/club-rpath-out.patch
diff --git a/meta-python/recipes-devtools/python/python3-pyzmq_22.3.0.bb b/meta-python/recipes-devtools/python/python3-pyzmq_22.3.0.bb
index 09e7341877..d2893ccbb1 100644
--- a/meta-python/recipes-devtools/python/python3-pyzmq_22.3.0.bb
+++ b/meta-python/recipes-devtools/python/python3-pyzmq_22.3.0.bb
@@ -5,8 +5,6 @@ LIC_FILES_CHKSUM = "file://COPYING.BSD;md5=11c65680f637c3df7f58bbc8d133e96e \
                     file://COPYING.LESSER;md5=12c592fa0bcfff3fb0977b066e9cb69e"
 DEPENDS = "zeromq"
 
-FILESEXTRAPATHS:prepend := "${THISDIR}/python-pyzmq:"
-
 SRC_URI += "file://club-rpath-out.patch"
 SRC_URI[sha256sum] = "8eddc033e716f8c91c6a2112f0a8ebc5e00532b4a6ae1eb0ccc48e027f9c671c"
 
@@ -17,8 +15,6 @@ RDEPENDS:${PN} += " \
 	${PYTHON_PN}-json \
 "
 
-FILES:${PN}-dbg =+ "${PYTHON_SITEPACKAGES_DIR}/zmq/backend/cython/.debug"
-
 do_compile:prepend() {
     echo [global] > ${S}/setup.cfg
     echo zmq_prefix = ${STAGING_DIR_HOST} >> ${S}/setup.cfg
-- 
2.25.1



^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH 6/9] python3-pycurl: fix DEPENDS
  2022-03-10 13:25 [PATCH 1/9] packagegroup-meta-python: add poetry-core and unattended-upgrade Ross Burton
                   ` (3 preceding siblings ...)
  2022-03-10 13:25 ` [PATCH 5/9] python3-pyzmq: clean up recipe Ross Burton
@ 2022-03-10 13:25 ` Ross Burton
  2022-03-10 13:25 ` [PATCH 7/9] python3-twisted: remove empty PN-src and PN-dbg Ross Burton
                   ` (2 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Ross Burton @ 2022-03-10 13:25 UTC (permalink / raw)
  To: openembedded-devel

By assigning directly to DEPENDS the dependencies in setuptools3 are
overwritten, so python3-setuptools-native is present to let the build
succeed entirely through luck.

Signed-off-by: Ross Burton <ross.burton@arm.com>
---
 .../recipes-devtools/python/python3-pycurl_7.44.1.bb       | 7 ++-----
 1 file changed, 2 insertions(+), 5 deletions(-)

diff --git a/meta-python/recipes-devtools/python/python3-pycurl_7.44.1.bb b/meta-python/recipes-devtools/python/python3-pycurl_7.44.1.bb
index 0f1ae3caca..c9b3b71873 100644
--- a/meta-python/recipes-devtools/python/python3-pycurl_7.44.1.bb
+++ b/meta-python/recipes-devtools/python/python3-pycurl_7.44.1.bb
@@ -14,9 +14,6 @@ LIC_FILES_CHKSUM = "file://COPYING-LGPL;md5=4fbd65380cdd255951079008b364516c \
 
 SRC_URI[sha256sum] = "5bcef4d988b74b99653602101e17d8401338d596b9234d263c728a0c3df003e8"
 
-inherit pypi setuptools3
+DEPENDS = "curl"
 
-DEPENDS = "\
-    curl \
-    ${PYTHON_PN}\
-"
+inherit pypi setuptools3
-- 
2.25.1



^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH 7/9] python3-twisted: remove empty PN-src and PN-dbg
  2022-03-10 13:25 [PATCH 1/9] packagegroup-meta-python: add poetry-core and unattended-upgrade Ross Burton
                   ` (4 preceding siblings ...)
  2022-03-10 13:25 ` [PATCH 6/9] python3-pycurl: fix DEPENDS Ross Burton
@ 2022-03-10 13:25 ` Ross Burton
  2022-03-10 13:25 ` [PATCH 8/9] python3-pylint: upgrade to 2.12.2 Ross Burton
  2022-03-10 13:25 ` [PATCH 9/9] meta-python: migrate away from setuptool3 where possible Ross Burton
  7 siblings, 0 replies; 9+ messages in thread
From: Ross Burton @ 2022-03-10 13:25 UTC (permalink / raw)
  To: openembedded-devel

Nothing is packaged in these, there are no debug symbols and the sources
are packaged into the regular packages.

Signed-off-by: Ross Burton <ross.burton@arm.com>
---
 .../python/python3-twisted_22.2.0.bb                | 13 -------------
 1 file changed, 13 deletions(-)

diff --git a/meta-python/recipes-devtools/python/python3-twisted_22.2.0.bb b/meta-python/recipes-devtools/python/python3-twisted_22.2.0.bb
index 2cf5ccc65d..5a000bc6a1 100644
--- a/meta-python/recipes-devtools/python/python3-twisted_22.2.0.bb
+++ b/meta-python/recipes-devtools/python/python3-twisted_22.2.0.bb
@@ -78,7 +78,6 @@ RDEPENDS:${PN}-web += "${PN}-core ${PN}-protocols"
 RDEPENDS:${PN}-words += "${PN}-core"
 RDEPENDS:${PN}-flow += "${PN}-core"
 RDEPENDS:${PN}-pair += "${PN}-core"
-RDEPENDS:${PN}-dbg = "${PN}"
 
 FILES:${PN} = "${PYTHON_SITEPACKAGES_DIR}/${PYPI_PACKAGE}-${PV}.dist-info/*"
 
@@ -243,22 +242,10 @@ ${libdir}/${PYTHON_DIR}/site-packages/twisted/plugins/twisted_pair.py* \
 ${libdir}/${PYTHON_DIR}/site-packages/twisted/pair \
 "
 
-FILES:${PN}-dbg += " \
-${libdir}/${PYTHON_DIR}/site-packages/twisted/*/.debug \
-${libdir}/${PYTHON_DIR}/site-packages/twisted/*/*/.debug \
-"
-
 FILES:${PN}-doc += " \
     ${libdir}/${PYTHON_DIR}/site-packages/twisted/python/_pydoctortemplates/ \
 "
 
-RDEPENDS:${PN}-src = "${PN}"
-FILES:${PN}-src = " \
-    ${libdir}/${PYTHON_DIR}/site-packages/twisted/*.py \
-    ${libdir}/${PYTHON_DIR}/site-packages/twisted/*/*.py \
-    ${libdir}/${PYTHON_DIR}/site-packages/twisted/*/*/*.py \
-"
-
 FILES:${PN}-core:append = " \
   ${libdir}/${PYTHON_DIR}/site-packages/twisted/__pycache__ \
   ${libdir}/${PYTHON_DIR}/site-packages/twisted/python/__pycache__/*pyc \
-- 
2.25.1



^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH 8/9] python3-pylint: upgrade to 2.12.2
  2022-03-10 13:25 [PATCH 1/9] packagegroup-meta-python: add poetry-core and unattended-upgrade Ross Burton
                   ` (5 preceding siblings ...)
  2022-03-10 13:25 ` [PATCH 7/9] python3-twisted: remove empty PN-src and PN-dbg Ross Burton
@ 2022-03-10 13:25 ` Ross Burton
  2022-03-10 13:25 ` [PATCH 9/9] meta-python: migrate away from setuptool3 where possible Ross Burton
  7 siblings, 0 replies; 9+ messages in thread
From: Ross Burton @ 2022-03-10 13:25 UTC (permalink / raw)
  To: openembedded-devel

The test suite is no longer shipped in the sources, so remove PN-tests.

Signed-off-by: Ross Burton <ross.burton@arm.com>
---
 .../python/python3-pylint_1.8.3.bb            | 38 -------------------
 .../python/python3-pylint_2.12.2.bb           | 18 +++++++++
 2 files changed, 18 insertions(+), 38 deletions(-)
 delete mode 100644 meta-python/recipes-devtools/python/python3-pylint_1.8.3.bb
 create mode 100644 meta-python/recipes-devtools/python/python3-pylint_2.12.2.bb

diff --git a/meta-python/recipes-devtools/python/python3-pylint_1.8.3.bb b/meta-python/recipes-devtools/python/python3-pylint_1.8.3.bb
deleted file mode 100644
index 60726df09d..0000000000
--- a/meta-python/recipes-devtools/python/python3-pylint_1.8.3.bb
+++ /dev/null
@@ -1,38 +0,0 @@
-SUMMARY="Pylint is a Python source code analyzer"
-HOMEPAGE= "http://www.pylint.org/"
-LICENSE = "GPL-2.0-only"
-LIC_FILES_CHKSUM = "file://COPYING;md5=4325afd396febcb659c36b49533135d4"
-
-SRC_URI[md5sum] = "2eb5f3cb8fe567eaf5420dd415012202"
-SRC_URI[sha256sum] = "c77311859e0c2d7932095f30d2b1bfdc4b6fe111f534450ba727a52eae330ef2"
-
-inherit pypi setuptools3 python3-dir
-
-DEPENDS += "${PYTHON_PN}-pytest-runner-native"
-
-do_install:append(){
-    rm ${D}${bindir}/pylint
-    cat >> ${D}${bindir}/pylint <<EOF
-#!/usr/bin/env ${PYTHON_PN}
-from pylint import run_pylint
-run_pylint()
-EOF
-    chmod 755 ${D}${bindir}/pylint
-    sed -i -e 's:^#!/usr/bin/python:#!/usr/bin/env\ ${PYTHON_PN}:g' ${D}/${PYTHON_SITEPACKAGES_DIR}/pylint/test/data/ascript
-}
-
-PACKAGES =+ "${PN}-tests"
-FILES:${PN}-tests+= " \
-    ${PYTHON_SITEPACKAGES_DIR}/pylint/test/ \
-    ${PYTHON_SITEPACKAGES_DIR}/pylint/testutils.py \
-"
-
-RDEPENDS:${PN} += "${PYTHON_PN}-astroid \
-                   ${PYTHON_PN}-isort \
-                   ${PYTHON_PN}-numbers \
-                   ${PYTHON_PN}-shell \
-                   ${PYTHON_PN}-json \
-                   ${PYTHON_PN}-pkgutil \
-                   ${PYTHON_PN}-difflib \
-                   ${PYTHON_PN}-netserver \
-                  "
diff --git a/meta-python/recipes-devtools/python/python3-pylint_2.12.2.bb b/meta-python/recipes-devtools/python/python3-pylint_2.12.2.bb
new file mode 100644
index 0000000000..6407417d7b
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-pylint_2.12.2.bb
@@ -0,0 +1,18 @@
+SUMMARY="Pylint is a Python source code analyzer"
+HOMEPAGE= "http://www.pylint.org/"
+LICENSE = "GPL-2.0-only"
+LIC_FILES_CHKSUM = "file://LICENSE;md5=c107cf754550e65755c42985a5d4e9c9"
+
+SRC_URI[sha256sum] = "9d945a73640e1fec07ee34b42f5669b770c759acd536ec7b16d7e4b87a9c9ff9"
+
+inherit pypi setuptools3
+
+RDEPENDS:${PN} += "${PYTHON_PN}-astroid \
+                   ${PYTHON_PN}-isort \
+                   ${PYTHON_PN}-numbers \
+                   ${PYTHON_PN}-shell \
+                   ${PYTHON_PN}-json \
+                   ${PYTHON_PN}-pkgutil \
+                   ${PYTHON_PN}-difflib \
+                   ${PYTHON_PN}-netserver \
+                  "
-- 
2.25.1



^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH 9/9] meta-python: migrate away from setuptool3 where possible
  2022-03-10 13:25 [PATCH 1/9] packagegroup-meta-python: add poetry-core and unattended-upgrade Ross Burton
                   ` (6 preceding siblings ...)
  2022-03-10 13:25 ` [PATCH 8/9] python3-pylint: upgrade to 2.12.2 Ross Burton
@ 2022-03-10 13:25 ` Ross Burton
  7 siblings, 0 replies; 9+ messages in thread
From: Ross Burton @ 2022-03-10 13:25 UTC (permalink / raw)
  To: openembedded-devel

Many recipes are currently building with setuptools3 but can use a more
modern tool: typically setuptools_build_meta but ordered-set can use
flit_core and pyrad can use poetry_core.

Signed-off-by: Ross Burton <ross.burton@arm.com>
---
 .../recipes-devtools/python/python3-aiohttp_3.8.1.bb |  3 ++-
 .../python/python3-ansi2html_1.7.0.bb                |  7 +------
 .../python/python3-asttokens_2.0.5.bb                |  7 ++-----
 .../python/python3-async-timeout_4.0.2.bb            |  2 +-
 .../recipes-devtools/python/python3-bcrypt_3.2.0.bb  |  2 +-
 .../recipes-devtools/python/python3-bidict_0.21.4.bb |  2 +-
 .../python/python3-cachetools_4.2.4.bb               |  2 +-
 .../recipes-devtools/python/python3-cbor2_5.4.2.bb   |  2 +-
 .../python/python3-dateutil_2.8.2.bb                 |  2 +-
 .../python/python3-engineio_4.3.1.bb                 |  2 +-
 .../python/python3-fasteners_0.17.3.bb               |  7 +------
 .../python/python3-flask-migrate_3.1.0.bb            |  2 +-
 .../python/python3-flask-socketio_5.1.1.bb           |  2 +-
 .../python/python3-frozenlist_1.3.0.bb               |  2 +-
 .../python/python3-httplib2_0.20.4.bb                |  2 +-
 .../python/python3-humanize_4.0.0.bb                 |  2 +-
 .../python/python3-hyperlink_21.0.0.bb               |  2 +-
 .../recipes-devtools/python/python3-icu_2.8.1.bb     |  2 +-
 .../recipes-devtools/python/python3-iso3166_2.0.2.bb |  2 +-
 .../python/python3-license-expression_21.6.14.bb     |  7 ++-----
 .../python/python3-luma-core_2.3.1.bb                |  4 +---
 .../recipes-devtools/python/python3-lz4_4.0.0.bb     |  2 +-
 .../recipes-devtools/python/python3-mypy_0.910.bb    |  2 +-
 .../python/python3-ordered-set_4.1.0.bb              |  2 +-
 .../recipes-devtools/python/python3-pint_0.18.bb     |  2 +-
 .../python/python3-pyhamcrest_2.0.3.bb               |  2 +-
 .../recipes-devtools/python/python3-pynacl_1.5.0.bb  |  3 +--
 .../recipes-devtools/python/python3-pyrad_2.4.bb     |  2 +-
 .../python/python3-pyscaffold_4.1.5.bb               |  2 +-
 .../python/python3-pytest-forked_1.4.0.bb            |  2 +-
 .../python3-pytest-helpers-namespace_2021.4.29.bb    | 12 +-----------
 .../python/python3-pytest-html_3.1.1.bb              |  3 +--
 .../python/python3-pytest-runner_5.3.1.bb            |  4 ++--
 .../python/python3-pytest-xdist_2.5.0.bb             |  2 +-
 .../python3-pytz-deprecation-shim_0.1.0.post0.bb     |  7 +------
 .../recipes-devtools/python/python3-pyzmq_22.3.0.bb  |  2 +-
 .../python/python3-simpleeval_0.9.12.bb              |  6 +-----
 .../python/python3-socketio_5.5.2.bb                 |  2 +-
 .../python/python3-soupsieve_2.3.1.bb                |  2 +-
 .../recipes-devtools/python/python3-tqdm_4.63.0.bb   |  2 +-
 .../python/python3-traitlets_5.1.1.bb                |  2 +-
 .../recipes-devtools/python/python3-twine_3.8.0.bb   |  7 +------
 .../python/python3-twisted_22.2.0.bb                 |  2 +-
 .../python/python3-typeguard_2.13.3.bb               |  2 +-
 .../recipes-devtools/python/python3-tzlocal_4.1.bb   |  2 +-
 .../python/python3-waitress_2.1.0.bb                 |  2 +-
 .../python/python3-yamlloader_1.1.0.bb               |  2 +-
 47 files changed, 51 insertions(+), 94 deletions(-)

diff --git a/meta-python/recipes-devtools/python/python3-aiohttp_3.8.1.bb b/meta-python/recipes-devtools/python/python3-aiohttp_3.8.1.bb
index 1d8434e3ca..3a4c510144 100644
--- a/meta-python/recipes-devtools/python/python3-aiohttp_3.8.1.bb
+++ b/meta-python/recipes-devtools/python/python3-aiohttp_3.8.1.bb
@@ -7,7 +7,8 @@ LIC_FILES_CHKSUM = "file://LICENSE.txt;md5=8074d6c6e217873b2a018a4522243ea3"
 SRC_URI[sha256sum] = "fc5471e1a54de15ef71c1bc6ebe80d4dc681ea600e68bfd1cbce40427f0b7578"
 
 PYPI_PACKAGE = "aiohttp"
-inherit setuptools3 pypi
+inherit setuptools_build_meta pypi
+
 RDEPENDS:${PN} = "\
     ${PYTHON_PN}-async-timeout \
     ${PYTHON_PN}-attrs \
diff --git a/meta-python/recipes-devtools/python/python3-ansi2html_1.7.0.bb b/meta-python/recipes-devtools/python/python3-ansi2html_1.7.0.bb
index 0a81ebdded..9a6e0f7a3a 100644
--- a/meta-python/recipes-devtools/python/python3-ansi2html_1.7.0.bb
+++ b/meta-python/recipes-devtools/python/python3-ansi2html_1.7.0.bb
@@ -7,7 +7,7 @@ PYPI_PACKAGE = "ansi2html"
 
 SRC_URI[sha256sum] = "69316be8c68ac91c5582d397c2890e69c993cc7cda52062ac7e45fcb660d8edc"
 
-inherit pypi setuptools3
+inherit pypi setuptools_build_meta
 
 DEPENDS += " \
 	${PYTHON_PN}-setuptools-scm-native \
@@ -18,8 +18,3 @@ RDEPENDS:${PN} = " \
 	${PYTHON_PN}-six \
 	${PYTHON_PN}-compression \
 "
-
-do_compile:prepend() {
-	echo "from setuptools import setup" > ${S}/setup.py
-	echo "setup()" >> ${S}/setup.py
-}
diff --git a/meta-python/recipes-devtools/python/python3-asttokens_2.0.5.bb b/meta-python/recipes-devtools/python/python3-asttokens_2.0.5.bb
index 429a56bae6..d45e70ce8a 100644
--- a/meta-python/recipes-devtools/python/python3-asttokens_2.0.5.bb
+++ b/meta-python/recipes-devtools/python/python3-asttokens_2.0.5.bb
@@ -5,13 +5,10 @@ LIC_FILES_CHKSUM = "file://LICENSE;md5=e3fc50a88d0a364313df4b21ef20c29e"
 
 PYPI_PACKAGE = "asttokens"
 
-inherit pypi setuptools3
+inherit pypi setuptools_build_meta
 
 SRC_URI[sha256sum] = "9a54c114f02c7a9480d56550932546a3f1fe71d8a02f1bc7ccd0ee3ee35cf4d5"
 
-DEPENDS += "\
-    python3-setuptools-scm-native \
-    python3-wheel-native \
-"
+DEPENDS += "python3-setuptools-scm-native"
 
 BBCLASSEXTEND = "native"
diff --git a/meta-python/recipes-devtools/python/python3-async-timeout_4.0.2.bb b/meta-python/recipes-devtools/python/python3-async-timeout_4.0.2.bb
index 7355f00131..9545b40712 100644
--- a/meta-python/recipes-devtools/python/python3-async-timeout_4.0.2.bb
+++ b/meta-python/recipes-devtools/python/python3-async-timeout_4.0.2.bb
@@ -11,7 +11,7 @@ LIC_FILES_CHKSUM = "file://LICENSE;md5=4fa41f15bb5f23b6d3560c5845eb8d57"
 SRC_URI[sha256sum] = "2163e1640ddb52b7a8c80d0a67a08587e5d245cc9c553a74a847056bc2976b15"
 
 PYPI_PACKAGE = "async-timeout"
-inherit pypi setuptools3
+inherit pypi setuptools_build_meta
 
 RDEPENDS:${PN} = "\
     ${PYTHON_PN}-asyncio \
diff --git a/meta-python/recipes-devtools/python/python3-bcrypt_3.2.0.bb b/meta-python/recipes-devtools/python/python3-bcrypt_3.2.0.bb
index a6d5007069..92a6a0d8c5 100644
--- a/meta-python/recipes-devtools/python/python3-bcrypt_3.2.0.bb
+++ b/meta-python/recipes-devtools/python/python3-bcrypt_3.2.0.bb
@@ -7,7 +7,7 @@ DEPENDS += "${PYTHON_PN}-cffi-native"
 SRC_URI[md5sum] = "fe31390dab603728f756cd3d6830c80a"
 SRC_URI[sha256sum] = "5b93c1726e50a93a033c36e5ca7fdcd29a5c7395af50a6892f5d9e7c6cfbfb29"
 
-inherit pypi setuptools3 ptest
+inherit pypi setuptools_build_meta ptest
 
 SRC_URI += " \
 	file://run-ptest \
diff --git a/meta-python/recipes-devtools/python/python3-bidict_0.21.4.bb b/meta-python/recipes-devtools/python/python3-bidict_0.21.4.bb
index 266dc606a2..95426a4ae7 100644
--- a/meta-python/recipes-devtools/python/python3-bidict_0.21.4.bb
+++ b/meta-python/recipes-devtools/python/python3-bidict_0.21.4.bb
@@ -6,6 +6,6 @@ LIC_FILES_CHKSUM = "file://LICENSE;md5=9741c346eef56131163e13b9db1241b3"
 
 SRC_URI[sha256sum] = "42c84ffbe6f8de898af6073b4be9ea7ccedcd78d3474aa844c54e49d5a079f6f"
 
-inherit pypi setuptools3
+inherit pypi setuptools_build_meta
 
 DEPENDS += "python3-setuptools-scm-native"
diff --git a/meta-python/recipes-devtools/python/python3-cachetools_4.2.4.bb b/meta-python/recipes-devtools/python/python3-cachetools_4.2.4.bb
index 1040dc7e5a..060a615d0b 100644
--- a/meta-python/recipes-devtools/python/python3-cachetools_4.2.4.bb
+++ b/meta-python/recipes-devtools/python/python3-cachetools_4.2.4.bb
@@ -8,7 +8,7 @@ SECTION = "devel/python"
 LICENSE = "MIT"
 LIC_FILES_CHKSUM = "file://LICENSE;md5=439a07e400525964c3c82684146e46eb"
 
-inherit pypi setuptools3 ptest
+inherit pypi setuptools_build_meta ptest
 
 SRC_URI += " \
 	file://run-ptest \
diff --git a/meta-python/recipes-devtools/python/python3-cbor2_5.4.2.bb b/meta-python/recipes-devtools/python/python3-cbor2_5.4.2.bb
index d3f6cd8c16..8d357b0ebd 100644
--- a/meta-python/recipes-devtools/python/python3-cbor2_5.4.2.bb
+++ b/meta-python/recipes-devtools/python/python3-cbor2_5.4.2.bb
@@ -6,7 +6,7 @@ LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/Apache-2.0;md5=89aea4e17d99a7ca
 
 SRC_URI[sha256sum] = "e283e70b55a049ff364cc5e648fde587e4d9b0e87e4b2664c69e639135e6b3b8"
 
-inherit pypi setuptools3 ptest
+inherit pypi setuptools_build_meta ptest
 
 SRC_URI += " \
         file://run-ptest \
diff --git a/meta-python/recipes-devtools/python/python3-dateutil_2.8.2.bb b/meta-python/recipes-devtools/python/python3-dateutil_2.8.2.bb
index 75221d8f9d..588a5f9ab0 100644
--- a/meta-python/recipes-devtools/python/python3-dateutil_2.8.2.bb
+++ b/meta-python/recipes-devtools/python/python3-dateutil_2.8.2.bb
@@ -8,7 +8,7 @@ SRC_URI[sha256sum] = "0123cacc1627ae19ddf3c27a5de5bd67ee4586fbdd6440d9748f8abb48
 
 PYPI_PACKAGE = "python-dateutil"
 PIP_INSTALL_PACKAGE = "python_dateutil"
-inherit pypi setuptools3
+inherit pypi setuptools_build_meta
 
 PACKAGES =+ "${PN}-zoneinfo"
 FILES:${PN}-zoneinfo = "${libdir}/${PYTHON_DIR}/site-packages/dateutil/zoneinfo"
diff --git a/meta-python/recipes-devtools/python/python3-engineio_4.3.1.bb b/meta-python/recipes-devtools/python/python3-engineio_4.3.1.bb
index a16306effb..c5a8851ffc 100644
--- a/meta-python/recipes-devtools/python/python3-engineio_4.3.1.bb
+++ b/meta-python/recipes-devtools/python/python3-engineio_4.3.1.bb
@@ -5,7 +5,7 @@ SECTION = "devel/python"
 LICENSE = "MIT"
 LIC_FILES_CHKSUM = "file://LICENSE;md5=42d0a9e728978f0eeb759c3be91536b8"
 
-inherit pypi setuptools3
+inherit pypi setuptools_build_meta
 
 PYPI_PACKAGE = "python-engineio"
 
diff --git a/meta-python/recipes-devtools/python/python3-fasteners_0.17.3.bb b/meta-python/recipes-devtools/python/python3-fasteners_0.17.3.bb
index d672708776..9baf23b7c0 100644
--- a/meta-python/recipes-devtools/python/python3-fasteners_0.17.3.bb
+++ b/meta-python/recipes-devtools/python/python3-fasteners_0.17.3.bb
@@ -5,14 +5,9 @@ LIC_FILES_CHKSUM = "file://LICENSE;md5=4476c4be31402271e101d9a4a3430d52"
 
 SRC_URI[sha256sum] = "a9a42a208573d4074c77d041447336cf4e3c1389a256fd3e113ef59cf29b7980"
 
-inherit pypi setuptools3
+inherit pypi setuptools_build_meta
 
 RDEPENDS:${PN} += "\
 	${PYTHON_PN}-logging \
 	${PYTHON_PN}-fcntl \
 "
-
-do_compile:prepend() {
-	echo "from setuptools import setup" > ${S}/setup.py
-	echo "setup()" >> ${S}/setup.py
-}
diff --git a/meta-python/recipes-devtools/python/python3-flask-migrate_3.1.0.bb b/meta-python/recipes-devtools/python/python3-flask-migrate_3.1.0.bb
index 7a7c3fa3f3..b6e565f471 100644
--- a/meta-python/recipes-devtools/python/python3-flask-migrate_3.1.0.bb
+++ b/meta-python/recipes-devtools/python/python3-flask-migrate_3.1.0.bb
@@ -6,7 +6,7 @@ SRC_URI[sha256sum] = "57d6060839e3a7f150eaab6fe4e726d9e3e7cffe2150fb223d73f92421
 
 PYPI_PACKAGE = "Flask-Migrate"
 
-inherit pypi setuptools3
+inherit pypi setuptools_build_meta
 
 RDEPENDS:${PN} += "\
     ${PYTHON_PN}-flask-sqlalchemy \
diff --git a/meta-python/recipes-devtools/python/python3-flask-socketio_5.1.1.bb b/meta-python/recipes-devtools/python/python3-flask-socketio_5.1.1.bb
index 3d7a1cb6a8..b854ce7f72 100644
--- a/meta-python/recipes-devtools/python/python3-flask-socketio_5.1.1.bb
+++ b/meta-python/recipes-devtools/python/python3-flask-socketio_5.1.1.bb
@@ -5,7 +5,7 @@ SECTION = "devel/python"
 LICENSE = "MIT"
 LIC_FILES_CHKSUM = "file://LICENSE;md5=38cc21254909604298ce763a6e4440a0"
 
-inherit pypi setuptools3
+inherit pypi setuptools_build_meta
 
 PYPI_PACKAGE = "Flask-SocketIO"
 
diff --git a/meta-python/recipes-devtools/python/python3-frozenlist_1.3.0.bb b/meta-python/recipes-devtools/python/python3-frozenlist_1.3.0.bb
index e3a932f773..2297d7c883 100644
--- a/meta-python/recipes-devtools/python/python3-frozenlist_1.3.0.bb
+++ b/meta-python/recipes-devtools/python/python3-frozenlist_1.3.0.bb
@@ -5,7 +5,7 @@ LIC_FILES_CHKSUM = "file://LICENSE;md5=cf056e8e7a0a5477451af18b7b5aa98c"
 
 SRC_URI[sha256sum] = "ce6f2ba0edb7b0c1d8976565298ad2deba6f8064d2bebb6ffce2ca896eb35b0b"
 
-inherit pypi setuptools3
+inherit pypi setuptools_build_meta
 
 BBCLASSEXTEND = "native nativesdk"
 
diff --git a/meta-python/recipes-devtools/python/python3-httplib2_0.20.4.bb b/meta-python/recipes-devtools/python/python3-httplib2_0.20.4.bb
index 6d22286caf..94568fc691 100644
--- a/meta-python/recipes-devtools/python/python3-httplib2_0.20.4.bb
+++ b/meta-python/recipes-devtools/python/python3-httplib2_0.20.4.bb
@@ -6,7 +6,7 @@ LIC_FILES_CHKSUM = "file://LICENSE;md5=56e5e931172b6164b62dc7c4aba6c8cf"
 
 SRC_URI[sha256sum] = "58a98e45b4b1a48273073f905d2961666ecf0fbac4250ea5b47aef259eb5c585"
 
-inherit pypi setuptools3
+inherit pypi setuptools_build_meta
 
 RDEPENDS:${PN} += "\
     ${PYTHON_PN}-compression \
diff --git a/meta-python/recipes-devtools/python/python3-humanize_4.0.0.bb b/meta-python/recipes-devtools/python/python3-humanize_4.0.0.bb
index f84034f3cd..5d6a6c9d08 100644
--- a/meta-python/recipes-devtools/python/python3-humanize_4.0.0.bb
+++ b/meta-python/recipes-devtools/python/python3-humanize_4.0.0.bb
@@ -7,7 +7,7 @@ LIC_FILES_CHKSUM = "file://LICENCE;md5=4ecc42519e84f6f3e23529464df7bd1d"
 
 SRC_URI[sha256sum] = "ee1f872fdfc7d2ef4a28d4f80ddde9f96d36955b5d6b0dac4bdeb99502bddb00"
 
-inherit pypi setuptools3
+inherit pypi setuptools_build_meta
 
 DEPENDS += "\
     ${PYTHON_PN}-setuptools-scm-native \
diff --git a/meta-python/recipes-devtools/python/python3-hyperlink_21.0.0.bb b/meta-python/recipes-devtools/python/python3-hyperlink_21.0.0.bb
index e9bf92aa1a..7be4b66a85 100644
--- a/meta-python/recipes-devtools/python/python3-hyperlink_21.0.0.bb
+++ b/meta-python/recipes-devtools/python/python3-hyperlink_21.0.0.bb
@@ -5,7 +5,7 @@ LIC_FILES_CHKSUM = "file://LICENSE;md5=6dc5b4bd3d02faedf08461621aa2aeca"
 
 SRC_URI[sha256sum] = "427af957daa58bc909471c6c40f74c5450fa123dd093fc53efd2e91d2705a56b"
 
-inherit pypi setuptools3
+inherit pypi setuptools_build_meta
 
 RDEPENDS:${PN} += "${PYTHON_PN}-stringold ${PYTHON_PN}-netclient ${PYTHON_PN}-idna"
 
diff --git a/meta-python/recipes-devtools/python/python3-icu_2.8.1.bb b/meta-python/recipes-devtools/python/python3-icu_2.8.1.bb
index 09543d753d..e958309664 100644
--- a/meta-python/recipes-devtools/python/python3-icu_2.8.1.bb
+++ b/meta-python/recipes-devtools/python/python3-icu_2.8.1.bb
@@ -12,4 +12,4 @@ SRC_URI[sha256sum] = "f0b9549a87f87ba7c413f13679d137271e0b37f1f39b0109ace38257d4
 
 SRC_URI += "file://0001-Fix-host-contamination-of-include-files.patch"
 
-inherit pkgconfig pypi setuptools3
+inherit pkgconfig pypi setuptools_build_meta
diff --git a/meta-python/recipes-devtools/python/python3-iso3166_2.0.2.bb b/meta-python/recipes-devtools/python/python3-iso3166_2.0.2.bb
index bc05f066a6..f3ef467f4b 100644
--- a/meta-python/recipes-devtools/python/python3-iso3166_2.0.2.bb
+++ b/meta-python/recipes-devtools/python/python3-iso3166_2.0.2.bb
@@ -5,7 +5,7 @@ LIC_FILES_CHKSUM = "file://LICENSE.txt;md5=5e2f4edc7e7408a82e4a1d05f229b695"
 
 SRC_URI[sha256sum] = "04d02cfcfc18a6f8a9a4edb4d0a55e2e4fc575626c29d702f750de415e88d372"
 
-inherit pypi setuptools3 ptest
+inherit pypi setuptools_build_meta ptest
 
 SRC_URI += " \
 	file://run-ptest \
diff --git a/meta-python/recipes-devtools/python/python3-license-expression_21.6.14.bb b/meta-python/recipes-devtools/python/python3-license-expression_21.6.14.bb
index efa8854411..01a5a94e1a 100644
--- a/meta-python/recipes-devtools/python/python3-license-expression_21.6.14.bb
+++ b/meta-python/recipes-devtools/python/python3-license-expression_21.6.14.bb
@@ -6,12 +6,9 @@ LIC_FILES_CHKSUM = "file://apache-2.0.LICENSE;md5=9429839cdc4b292ff46e88b524c6e0
 
 SRC_URI[sha256sum] = "9de87a427c9a449eee7913472fb9ed03b63036295547369fdbf95f76a8b924b2"
 
-inherit pypi ptest setuptools3
+inherit pypi ptest setuptools_build_meta
 
-DEPENDS += "\
-    ${PYTHON_PN}-setuptools-scm-native \
-    ${PYTHON_PN}-wheel-native \
-"
+DEPENDS += "${PYTHON_PN}-setuptools-scm-native"
 
 RDEPENDS:${PN} += "\
     ${PYTHON_PN}-booleanpy \
diff --git a/meta-python/recipes-devtools/python/python3-luma-core_2.3.1.bb b/meta-python/recipes-devtools/python/python3-luma-core_2.3.1.bb
index c37cc22c46..9614039f01 100644
--- a/meta-python/recipes-devtools/python/python3-luma-core_2.3.1.bb
+++ b/meta-python/recipes-devtools/python/python3-luma-core_2.3.1.bb
@@ -4,12 +4,10 @@ HOMEPAGE = "https://github.com/rm-hull/luma.core"
 LICENSE = "MIT"
 LIC_FILES_CHKSUM = "file://LICENSE.rst;md5=3b1d500f5911ec7522f1f790d616e0ee"
 
-inherit pypi setuptools3
+inherit pypi setuptools_build_meta
 
 SRC_URI[sha256sum] = "f293f5fff8946eea62af3a5d5d7da55c37d2b64aac6c9c90180a385da9f7d003"
 
-CLEANBROKEN = "1"
-
 PYPI_PACKAGE = "luma.core"
 
 RDEPENDS:${PN} += " \
diff --git a/meta-python/recipes-devtools/python/python3-lz4_4.0.0.bb b/meta-python/recipes-devtools/python/python3-lz4_4.0.0.bb
index 472e152db2..40b2186b2c 100644
--- a/meta-python/recipes-devtools/python/python3-lz4_4.0.0.bb
+++ b/meta-python/recipes-devtools/python/python3-lz4_4.0.0.bb
@@ -10,6 +10,6 @@ DEPENDS += " \
 
 SRC_URI[sha256sum] = "57c5dfd3b7dae833b0d2b2c1aafd7f9d0dfcab40683d183d010c67c9fd1beca3"
 
-inherit pypi setuptools3
+inherit pypi setuptools_build_meta
 
 BBCLASSEXTEND = "native nativesdk"
diff --git a/meta-python/recipes-devtools/python/python3-mypy_0.910.bb b/meta-python/recipes-devtools/python/python3-mypy_0.910.bb
index 1a494af5af..be9ad3f66a 100644
--- a/meta-python/recipes-devtools/python/python3-mypy_0.910.bb
+++ b/meta-python/recipes-devtools/python/python3-mypy_0.910.bb
@@ -5,7 +5,7 @@ LIC_FILES_CHKSUM = "file://LICENSE;md5=17b7180fcfc43c4e70c07c71588604c4"
 
 PYPI_PACKAGE = "mypy"
 
-inherit pypi setuptools3
+inherit pypi setuptools_build_meta
 
 SRC_URI[sha256sum] = "704098302473cb31a218f1775a873b376b30b4c18229421e9e9dc8916fd16150"
 
diff --git a/meta-python/recipes-devtools/python/python3-ordered-set_4.1.0.bb b/meta-python/recipes-devtools/python/python3-ordered-set_4.1.0.bb
index 2740b33551..b3600d093a 100644
--- a/meta-python/recipes-devtools/python/python3-ordered-set_4.1.0.bb
+++ b/meta-python/recipes-devtools/python/python3-ordered-set_4.1.0.bb
@@ -5,7 +5,7 @@ LIC_FILES_CHKSUM = "file://MIT-LICENSE;md5=3bf5e1ad64c0d99032c3143361fa234e"
 
 SRC_URI[sha256sum] = "694a8e44c87657c59292ede72891eb91d34131f6531463aab3009191c77364a8"
 
-inherit pypi setuptools3 ptest
+inherit pypi flit_core ptest
 
 DEPENDS += "python3-pytest-runner-native"
 
diff --git a/meta-python/recipes-devtools/python/python3-pint_0.18.bb b/meta-python/recipes-devtools/python/python3-pint_0.18.bb
index a7a1384da1..c8a394b922 100644
--- a/meta-python/recipes-devtools/python/python3-pint_0.18.bb
+++ b/meta-python/recipes-devtools/python/python3-pint_0.18.bb
@@ -8,7 +8,7 @@ LIC_FILES_CHKSUM = "file://LICENSE;md5=bccf824202692270a1e0829a62e3f47b"
 
 PYPI_PACKAGE := "Pint"
 
-inherit pypi ptest setuptools3
+inherit pypi ptest setuptools_build_meta
 
 SRC_URI[sha256sum] = "8c4bce884c269051feb7abc69dbfd18403c0c764abc83da132e8a7222f8ba801"
 
diff --git a/meta-python/recipes-devtools/python/python3-pyhamcrest_2.0.3.bb b/meta-python/recipes-devtools/python/python3-pyhamcrest_2.0.3.bb
index 7c0824c2d1..4f047368f6 100644
--- a/meta-python/recipes-devtools/python/python3-pyhamcrest_2.0.3.bb
+++ b/meta-python/recipes-devtools/python/python3-pyhamcrest_2.0.3.bb
@@ -7,6 +7,6 @@ PYPI_PACKAGE = "PyHamcrest"
 
 SRC_URI[sha256sum] = "dfb19cf6d71743e086fbb761ed7faea5aacbc8ec10c17a08b93ecde39192a3db"
 
-inherit pypi setuptools3
+inherit pypi setuptools_build_meta
 
 RDEPENDS:${PN} += "${PYTHON_PN}-six"
diff --git a/meta-python/recipes-devtools/python/python3-pynacl_1.5.0.bb b/meta-python/recipes-devtools/python/python3-pynacl_1.5.0.bb
index 10f624b484..fd27c62d15 100644
--- a/meta-python/recipes-devtools/python/python3-pynacl_1.5.0.bb
+++ b/meta-python/recipes-devtools/python/python3-pynacl_1.5.0.bb
@@ -8,10 +8,9 @@ SRC_URI[sha256sum] = "8ac7448f09ab85811607bdd21ec2464495ac8b7c66d146bf545b0f08fb
 
 PYPI_PACKAGE = "PyNaCl"
 
-inherit pypi setuptools3
+inherit pypi setuptools_build_meta
 
 DEPENDS += "\
-    ${PYTHON_PN}-wheel-native \
     ${PYTHON_PN}-cffi-native \
     libsodium \
 "
diff --git a/meta-python/recipes-devtools/python/python3-pyrad_2.4.bb b/meta-python/recipes-devtools/python/python3-pyrad_2.4.bb
index 86a95a4aa4..665aaf38bd 100644
--- a/meta-python/recipes-devtools/python/python3-pyrad_2.4.bb
+++ b/meta-python/recipes-devtools/python/python3-pyrad_2.4.bb
@@ -6,4 +6,4 @@ LIC_FILES_CHKSUM = "file://PKG-INFO;beginline=8;endline=8;md5=e910b35b0ef4e1f665
 PYPI_PACKAGE = "pyrad"
 SRC_URI[sha256sum] = "057de4b7e89d8da57ba782c1bde45c63ebee720ae2c0b0a69beaff15c47e30d9"
 
-inherit pypi setuptools3
+inherit pypi poetry_core
diff --git a/meta-python/recipes-devtools/python/python3-pyscaffold_4.1.5.bb b/meta-python/recipes-devtools/python/python3-pyscaffold_4.1.5.bb
index cd160a69eb..9cf876ae36 100644
--- a/meta-python/recipes-devtools/python/python3-pyscaffold_4.1.5.bb
+++ b/meta-python/recipes-devtools/python/python3-pyscaffold_4.1.5.bb
@@ -11,7 +11,7 @@ DEPENDS += "python3-setuptools-scm-native"
 
 SRC_URI[sha256sum] = "55f6532fd6d62b3b698d604257f7a7eda6a87557bbec22760f8c0d9549454802"
 
-inherit pypi setuptools3
+inherit pypi setuptools_build_meta
 PYPI_PACKAGE = "PyScaffold"
 
 RDEPENDS:${PN} += " \
diff --git a/meta-python/recipes-devtools/python/python3-pytest-forked_1.4.0.bb b/meta-python/recipes-devtools/python/python3-pytest-forked_1.4.0.bb
index c6f352bc61..d75dd401d1 100644
--- a/meta-python/recipes-devtools/python/python3-pytest-forked_1.4.0.bb
+++ b/meta-python/recipes-devtools/python/python3-pytest-forked_1.4.0.bb
@@ -5,7 +5,7 @@ LIC_FILES_CHKSUM = "file://LICENSE;md5=772fcdaca14b378878d05c7d857e6c3e"
 
 SRC_URI[sha256sum] = "8b67587c8f98cbbadfdd804539ed5455b6ed03802203485dd2f53c1422d7440e"
 
-inherit pypi setuptools3
+inherit pypi setuptools_build_meta
 
 DEPENDS += "python3-setuptools-scm-native"
 
diff --git a/meta-python/recipes-devtools/python/python3-pytest-helpers-namespace_2021.4.29.bb b/meta-python/recipes-devtools/python/python3-pytest-helpers-namespace_2021.4.29.bb
index 0ee1bd6866..6ccf365f43 100644
--- a/meta-python/recipes-devtools/python/python3-pytest-helpers-namespace_2021.4.29.bb
+++ b/meta-python/recipes-devtools/python/python3-pytest-helpers-namespace_2021.4.29.bb
@@ -6,17 +6,7 @@ LIC_FILES_CHKSUM = "file://LICENSE;md5=440a4cdb311cd7ad181efb4cba06d562"
 
 SRC_URI[sha256sum] = "183524e3db4e2a1fea92e0ca3662a624ba44c9f3568da15679d7535ba6838a6a"
 
-inherit pypi setuptools3
-
-# Workaround for network access issue during compile step
-# this needs to be fixed in the recipes buildsystem to move
-# this such that it can be accomplished during do_fetch task
-do_compile[network] = "1"
-
-DEPENDS += "\
-    ${PYTHON_PN}-wheel-native \
-    ${PYTHON_PN}-pip-native \
-"
+inherit pypi setuptools_build_meta
 
 RDEPENDS:${PN} += " \
     ${PYTHON_PN}-pytest \
diff --git a/meta-python/recipes-devtools/python/python3-pytest-html_3.1.1.bb b/meta-python/recipes-devtools/python/python3-pytest-html_3.1.1.bb
index cd0450f519..4b4aff01ce 100644
--- a/meta-python/recipes-devtools/python/python3-pytest-html_3.1.1.bb
+++ b/meta-python/recipes-devtools/python/python3-pytest-html_3.1.1.bb
@@ -6,10 +6,9 @@ LIC_FILES_CHKSUM = "file://LICENSE;md5=5d425c8f3157dbf212db2ec53d9e5132"
 
 SRC_URI[sha256sum] = "3ee1cf319c913d19fe53aeb0bc400e7b0bc2dbeb477553733db1dad12eb75ee3"
 
-
 PYPI_PACKAGE = "pytest-html"
 
-inherit pypi setuptools3
+inherit pypi setuptools_build_meta
 
 RDEPENDS:${PN} += " \
     ${PYTHON_PN}-pytest \
diff --git a/meta-python/recipes-devtools/python/python3-pytest-runner_5.3.1.bb b/meta-python/recipes-devtools/python/python3-pytest-runner_5.3.1.bb
index 0ca007dd44..fed2d91140 100644
--- a/meta-python/recipes-devtools/python/python3-pytest-runner_5.3.1.bb
+++ b/meta-python/recipes-devtools/python/python3-pytest-runner_5.3.1.bb
@@ -4,8 +4,8 @@ LIC_FILES_CHKSUM = "file://LICENSE;md5=7a7126e068206290f3fe9f8d6c713ea6"
 
 SRC_URI[sha256sum] = "0fce5b8dc68760f353979d99fdd6b3ad46330b6b1837e2077a89ebcf204aac91"
 
-inherit pypi setuptools3
-PIP_INSTALL_PACKAGE = "pytest_runner"
+inherit pypi setuptools_build_meta
+
 DEPENDS += " \
     ${PYTHON_PN}-setuptools-scm-native"
 
diff --git a/meta-python/recipes-devtools/python/python3-pytest-xdist_2.5.0.bb b/meta-python/recipes-devtools/python/python3-pytest-xdist_2.5.0.bb
index a10ac8cc49..6ad01d08e5 100644
--- a/meta-python/recipes-devtools/python/python3-pytest-xdist_2.5.0.bb
+++ b/meta-python/recipes-devtools/python/python3-pytest-xdist_2.5.0.bb
@@ -5,7 +5,7 @@ LIC_FILES_CHKSUM = "file://LICENSE;md5=772fcdaca14b378878d05c7d857e6c3e"
 
 SRC_URI[sha256sum] = "4580deca3ff04ddb2ac53eba39d76cb5dd5edeac050cb6fbc768b0dd712b4edf"
 
-inherit pypi setuptools3
+inherit pypi setuptools_build_meta
 
 DEPENDS += "python3-setuptools-scm-native"
 
diff --git a/meta-python/recipes-devtools/python/python3-pytz-deprecation-shim_0.1.0.post0.bb b/meta-python/recipes-devtools/python/python3-pytz-deprecation-shim_0.1.0.post0.bb
index 76487c830f..96f1522b76 100644
--- a/meta-python/recipes-devtools/python/python3-pytz-deprecation-shim_0.1.0.post0.bb
+++ b/meta-python/recipes-devtools/python/python3-pytz-deprecation-shim_0.1.0.post0.bb
@@ -8,9 +8,4 @@ SRC_URI[sha256sum] = "af097bae1b616dde5c5744441e2ddc69e74dfdcb0c263129610d85b874
 PYPI_PACKAGE = "pytz_deprecation_shim"
 PYPI_SRC_URI = "https://files.pythonhosted.org/packages/94/f0/909f94fea74759654390a3e1a9e4e185b6cd9aa810e533e3586f39da3097/${PYPI_PACKAGE}-${PV}.tar.gz"
 
-inherit pypi setuptools3
-
-do_compile:prepend() {
-	echo "from setuptools import setup" > ${S}/setup.py
-	echo "setup()" >> ${S}/setup.py
-}
+inherit pypi setuptools_build_meta
diff --git a/meta-python/recipes-devtools/python/python3-pyzmq_22.3.0.bb b/meta-python/recipes-devtools/python/python3-pyzmq_22.3.0.bb
index d2893ccbb1..7f0d998f3b 100644
--- a/meta-python/recipes-devtools/python/python3-pyzmq_22.3.0.bb
+++ b/meta-python/recipes-devtools/python/python3-pyzmq_22.3.0.bb
@@ -8,7 +8,7 @@ DEPENDS = "zeromq"
 SRC_URI += "file://club-rpath-out.patch"
 SRC_URI[sha256sum] = "8eddc033e716f8c91c6a2112f0a8ebc5e00532b4a6ae1eb0ccc48e027f9c671c"
 
-inherit pypi pkgconfig setuptools3
+inherit pypi pkgconfig setuptools_build_meta
 
 RDEPENDS:${PN} += " \
 	${PYTHON_PN}-multiprocessing \
diff --git a/meta-python/recipes-devtools/python/python3-simpleeval_0.9.12.bb b/meta-python/recipes-devtools/python/python3-simpleeval_0.9.12.bb
index 8ad6acc875..279c2562fe 100644
--- a/meta-python/recipes-devtools/python/python3-simpleeval_0.9.12.bb
+++ b/meta-python/recipes-devtools/python/python3-simpleeval_0.9.12.bb
@@ -5,7 +5,7 @@ LIC_FILES_CHKSUM = "file://LICENCE;md5=dc9277482effe59b734b004cbcc1fee7"
 
 SRC_URI[sha256sum] = "3e0be507486d4e21cf9d08847c7e57dd61a1603950399985f7c5a0be7fd33e36"
 
-inherit pypi setuptools3 ptest
+inherit pypi setuptools_build_meta ptest
 
 BBCLASSEXTEND = "native nativesdk"
 
@@ -21,10 +21,6 @@ RDEPENDS:${PN}-ptest += " \
 	${PYTHON_PN}-pytest \
 "
 
-do_configure:prepend() {
-	sed -i -e "/use_2to3=True,/d" ${S}/setup.py
-}
-
 do_install_ptest() {
 	cp -f ${S}/test_simpleeval.py ${D}${PTEST_PATH}/
 }
diff --git a/meta-python/recipes-devtools/python/python3-socketio_5.5.2.bb b/meta-python/recipes-devtools/python/python3-socketio_5.5.2.bb
index 4b22a73553..67e5bb71f2 100644
--- a/meta-python/recipes-devtools/python/python3-socketio_5.5.2.bb
+++ b/meta-python/recipes-devtools/python/python3-socketio_5.5.2.bb
@@ -5,7 +5,7 @@ SECTION = "devel/python"
 LICENSE = "MIT"
 LIC_FILES_CHKSUM = "file://LICENSE;md5=42d0a9e728978f0eeb759c3be91536b8"
 
-inherit pypi setuptools3
+inherit pypi setuptools_build_meta
 
 PYPI_PACKAGE = "python-socketio"
 
diff --git a/meta-python/recipes-devtools/python/python3-soupsieve_2.3.1.bb b/meta-python/recipes-devtools/python/python3-soupsieve_2.3.1.bb
index f4cf93daba..cb87ec936c 100644
--- a/meta-python/recipes-devtools/python/python3-soupsieve_2.3.1.bb
+++ b/meta-python/recipes-devtools/python/python3-soupsieve_2.3.1.bb
@@ -6,7 +6,7 @@ LIC_FILES_CHKSUM = "file://LICENSE.md;md5=33c3a77def9b3ad83e01c65bdcc1af67"
 
 SRC_URI[sha256sum] = "b8d49b1cd4f037c7082a9683dfa1801aa2597fb11c3a1155b7a5b94829b4f1f9"
 
-inherit pypi setuptools3 ptest
+inherit pypi setuptools_build_meta ptest
 
 SRC_URI += " \
         file://run-ptest \
diff --git a/meta-python/recipes-devtools/python/python3-tqdm_4.63.0.bb b/meta-python/recipes-devtools/python/python3-tqdm_4.63.0.bb
index cd5f1aab53..e7ba1d4e82 100644
--- a/meta-python/recipes-devtools/python/python3-tqdm_4.63.0.bb
+++ b/meta-python/recipes-devtools/python/python3-tqdm_4.63.0.bb
@@ -7,7 +7,7 @@ LIC_FILES_CHKSUM = "file://LICENCE;md5=1672e2674934fd93a31c09cf17f34100"
 
 SRC_URI[sha256sum] = "1d9835ede8e394bb8c9dcbffbca02d717217113adc679236873eeaac5bc0b3cd"
 
-inherit pypi setuptools3
+inherit pypi setuptools_build_meta
 
 DEPENDS += "${PYTHON_PN}-setuptools-scm-native"
 
diff --git a/meta-python/recipes-devtools/python/python3-traitlets_5.1.1.bb b/meta-python/recipes-devtools/python/python3-traitlets_5.1.1.bb
index bfed02d6f5..b9301ecaf9 100644
--- a/meta-python/recipes-devtools/python/python3-traitlets_5.1.1.bb
+++ b/meta-python/recipes-devtools/python/python3-traitlets_5.1.1.bb
@@ -13,4 +13,4 @@ RDEPENDS:${PN} = "\
     ${PYTHON_PN}-decorator \
 "
 
-inherit setuptools3 pypi
+inherit pypi setuptools_build_meta
diff --git a/meta-python/recipes-devtools/python/python3-twine_3.8.0.bb b/meta-python/recipes-devtools/python/python3-twine_3.8.0.bb
index d9aa3dce93..b96e153b5a 100644
--- a/meta-python/recipes-devtools/python/python3-twine_3.8.0.bb
+++ b/meta-python/recipes-devtools/python/python3-twine_3.8.0.bb
@@ -5,7 +5,7 @@ LIC_FILES_CHKSUM = "file://LICENSE;md5=a3d1106b253a8d50dd82a4202a045b4c"
 
 SRC_URI[sha256sum] = "8efa52658e0ae770686a13b675569328f1fba9837e5de1867bfe5f46a9aefe19"
 
-inherit pypi setuptools3
+inherit pypi setuptools_build_meta
 
 DEPENDS += "\
 	${PYTHON_PN}-setuptools-scm-native \
@@ -15,9 +15,4 @@ RDEPENDS:${PN} += " \
 	${PYTHON_PN}-importlib-metadata \
 "
 
-do_compile:prepend() {
-	echo "from setuptools import setup" > ${S}/setup.py
-	echo "setup()" >> ${S}/setup.py
-}
-
 BBCLASSEXTEND = "native"
diff --git a/meta-python/recipes-devtools/python/python3-twisted_22.2.0.bb b/meta-python/recipes-devtools/python/python3-twisted_22.2.0.bb
index 5a000bc6a1..053b5c0619 100644
--- a/meta-python/recipes-devtools/python/python3-twisted_22.2.0.bb
+++ b/meta-python/recipes-devtools/python/python3-twisted_22.2.0.bb
@@ -11,7 +11,7 @@ SRC_URI[sha256sum] = "57f32b1f6838facb8c004c89467840367ad38e9e535f8252091345dba5
 
 PYPI_PACKAGE = "Twisted"
 
-inherit pypi setuptools3
+inherit pypi setuptools_build_meta
 
 do_install:append() {
     # remove some useless files before packaging
diff --git a/meta-python/recipes-devtools/python/python3-typeguard_2.13.3.bb b/meta-python/recipes-devtools/python/python3-typeguard_2.13.3.bb
index 21ca439505..368112b0b2 100644
--- a/meta-python/recipes-devtools/python/python3-typeguard_2.13.3.bb
+++ b/meta-python/recipes-devtools/python/python3-typeguard_2.13.3.bb
@@ -5,7 +5,7 @@ LIC_FILES_CHKSUM = "file://LICENSE;md5=f0e423eea5c91e7aa21bdb70184b3e53"
 
 SRC_URI[sha256sum] = "00edaa8da3a133674796cf5ea87d9f4b4c367d77476e185e80251cc13dfbb8c4"
 
-inherit pypi setuptools3 ptest
+inherit pypi setuptools_build_meta ptest
 
 SRC_URI += " \
         file://run-ptest \
diff --git a/meta-python/recipes-devtools/python/python3-tzlocal_4.1.bb b/meta-python/recipes-devtools/python/python3-tzlocal_4.1.bb
index 29a69f8b8f..a323f1fff0 100644
--- a/meta-python/recipes-devtools/python/python3-tzlocal_4.1.bb
+++ b/meta-python/recipes-devtools/python/python3-tzlocal_4.1.bb
@@ -5,7 +5,7 @@ LIC_FILES_CHKSUM = "file://LICENSE.txt;md5=57e0bd61643d81d05683cdce65b11d10"
 
 SRC_URI[sha256sum] = "0f28015ac68a5c067210400a9197fc5d36ba9bc3f8eaf1da3cbd59acdfed9e09"
 
-inherit pypi setuptools3
+inherit pypi setuptools_build_meta
 
 RDEPENDS:${PN} += "\
 	${PYTHON_PN}-pytz-deprecation-shim \
diff --git a/meta-python/recipes-devtools/python/python3-waitress_2.1.0.bb b/meta-python/recipes-devtools/python/python3-waitress_2.1.0.bb
index 99e483962f..31a77c5b9e 100644
--- a/meta-python/recipes-devtools/python/python3-waitress_2.1.0.bb
+++ b/meta-python/recipes-devtools/python/python3-waitress_2.1.0.bb
@@ -8,4 +8,4 @@ LIC_FILES_CHKSUM = "file://LICENSE.txt;md5=78ccb3640dc841e1baecb3e27a6966b2"
 
 SRC_URI[sha256sum] = "ec8a8d9b6b15f3bb2c1a82b8f3929a029c333c35fcafb08c185a9e562d8cc9c2"
 
-inherit setuptools3 pypi
+inherit setuptools_build_meta pypi
diff --git a/meta-python/recipes-devtools/python/python3-yamlloader_1.1.0.bb b/meta-python/recipes-devtools/python/python3-yamlloader_1.1.0.bb
index a5510d5dc7..06f3488921 100644
--- a/meta-python/recipes-devtools/python/python3-yamlloader_1.1.0.bb
+++ b/meta-python/recipes-devtools/python/python3-yamlloader_1.1.0.bb
@@ -5,7 +5,7 @@ LIC_FILES_CHKSUM = "file://LICENSE;md5=6831ef36faa29329bce2420c5356f97e"
 
 SRC_URI[sha256sum] = "8a297c7a197683ba02e5e2b882ffd6c6180d01bdefb534b69cd3962df020bfe6"
 
-inherit pypi setuptools3
+inherit pypi setuptools_build_meta
 
 RDEPENDS:${PN}:class-target += "\
     ${PYTHON_PN}-pyyaml \
-- 
2.25.1



^ permalink raw reply related	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2022-03-10 13:25 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-03-10 13:25 [PATCH 1/9] packagegroup-meta-python: add poetry-core and unattended-upgrade Ross Burton
2022-03-10 13:25 ` [PATCH 2/9] python3-pystache: remove, unmaintained Ross Burton
2022-03-10 13:25 ` [PATCH 3/9] python3-configparser: remove, not needed for Python 3 Ross Burton
2022-03-10 13:25 ` [PATCH 4/9] python3-backports-functional-lru-cache: " Ross Burton
2022-03-10 13:25 ` [PATCH 5/9] python3-pyzmq: clean up recipe Ross Burton
2022-03-10 13:25 ` [PATCH 6/9] python3-pycurl: fix DEPENDS Ross Burton
2022-03-10 13:25 ` [PATCH 7/9] python3-twisted: remove empty PN-src and PN-dbg Ross Burton
2022-03-10 13:25 ` [PATCH 8/9] python3-pylint: upgrade to 2.12.2 Ross Burton
2022-03-10 13:25 ` [PATCH 9/9] meta-python: migrate away from setuptool3 where possible Ross Burton

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.