New Upstream Release - pyhamcrest
Ready changes
Summary
Merged new upstream version: 2.0.4 (was: 2.0.3).
Diff
diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml
index 04de374..0a44639 100644
--- a/.github/workflows/main.yml
+++ b/.github/workflows/main.yml
@@ -8,6 +8,9 @@ on:
pull_request:
branches: ["main", "master"]
+ schedule:
+ - cron: "0 6 * * MON" # Every Monday morning
+
workflow_dispatch:
jobs:
@@ -25,16 +28,19 @@ jobs:
- "3.7"
- "3.8"
- "3.9"
- - "3.10.0"
- - "pypy2"
- - "pypy3"
+ - "3.10"
+ - "3.11.0-beta.5"
+ - "pypy3.9"
exclude:
- os: macos-latest
python-version: pypy3
steps:
- - uses: "actions/checkout@v2"
- - uses: "actions/setup-python@v2"
+ - uses: "actions/checkout@v3"
+ with:
+ # We want our tags here
+ fetch-depth: 0
+ - uses: "actions/setup-python@v4"
with:
python-version: "${{ matrix.python-version }}"
- name: "Install dependencies"
@@ -59,8 +65,8 @@ jobs:
- tests
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v2
- - uses: actions/setup-python@v2
+ - uses: actions/checkout@v3
+ - uses: actions/setup-python@v4
with:
python-version: "3.10"
@@ -94,8 +100,11 @@ jobs:
runs-on: "ubuntu-latest"
steps:
- - uses: "actions/checkout@v2"
- - uses: "actions/setup-python@v1"
+ - uses: "actions/checkout@v3"
+ with:
+ # We want our tags here
+ fetch-depth: 0
+ - uses: "actions/setup-python@v4"
with:
python-version: "3.10"
@@ -105,6 +114,7 @@ jobs:
if: "${{ env.TEST_PYPI_API_TOKEN != '' }}"
run: |
echo "DO_PUBLISH=yes" >> $GITHUB_ENV
+ echo "SETUPTOOLS_SCM_PRETEND_VERSION=0.0.1" >> $GITHUB_ENV
- name: "Install pep517 and twine"
run: "python -m pip install pep517 twine"
@@ -132,10 +142,10 @@ jobs:
runs-on: "${{ matrix.os }}"
steps:
- - uses: "actions/checkout@v2"
- - uses: "actions/setup-python@v2"
+ - uses: "actions/checkout@v3"
+ - uses: "actions/setup-python@v4"
with:
- python-version: "3.9"
+ python-version: "3.10"
- name: "Install in dev mode"
run: "python -m pip install -e .[dev]"
- name: "Import package"
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
new file mode 100644
index 0000000..66c92ba
--- /dev/null
+++ b/.github/workflows/release.yml
@@ -0,0 +1,56 @@
+name: Release
+on:
+ push:
+ tags:
+ - V*
+ branches:
+ - main
+ pull_request:
+ branches:
+ - main
+ workflow_dispatch:
+
+jobs:
+ pure-python-wheel-and-sdist:
+ name: Build a pure Python wheel and source distribution
+ runs-on: ubuntu-latest
+
+ steps:
+ - uses: actions/checkout@v2
+ with:
+ # Fetch all tags; this is needed for hatch-vcs
+ fetch-depth: 0
+
+ - name: Install build dependencies
+ run: python -m pip install --upgrade build
+
+ - name: Build
+ run: python -m build
+
+ - uses: actions/upload-artifact@v2
+ with:
+ name: artifacts
+ path: dist/*
+ if-no-files-found: error
+
+ publish:
+ name: Publish release
+ needs:
+ - pure-python-wheel-and-sdist
+ runs-on: ubuntu-latest
+ if: |
+ (github.event_name == 'push' && startsWith(github.event.ref, 'refs/tags')) ||
+ (github.event_name == 'workflow_dispatch' && startsWith(github.event.ref, 'refs/tags'))
+
+ steps:
+ - uses: actions/download-artifact@v2
+ with:
+ name: artifacts
+ path: dist
+
+ - name: Push build artifacts to PyPI
+ uses: pypa/gh-action-pypi-publish@v1.4.2
+ with:
+ skip_existing: true
+ user: __token__
+ password: ${{ secrets.PYPI_API_TOKEN }}
diff --git a/.gitignore b/.gitignore
index ceb92ea..ed9dbb4 100644
--- a/.gitignore
+++ b/.gitignore
@@ -9,5 +9,12 @@ dist/
*~
.python-version
.mypy_cache/
+.pytest_cache/
requirements.txt
requirements.in
+.envrc
+.direnv/
+doc/_build/
+htmlcov/
+src/hamcrest/_version.py
+.tool-versions
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index 5af67ff..951aff7 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -5,12 +5,12 @@ repos:
- id: check-useless-excludes
- repo: https://github.com/pre-commit/pre-commit-hooks
- rev: v4.0.1
+ rev: v4.3.0
hooks:
- id: debug-statements
- repo: https://github.com/asottile/blacken-docs
- rev: v1.12.0
+ rev: v1.12.1
hooks:
- id: blacken-docs
# args: ["-l100"]
@@ -26,7 +26,7 @@ repos:
)
- repo: https://github.com/psf/black
- rev: 21.12b0
+ rev: 22.6.0
hooks:
- id: black
# args: ["-l100"]
diff --git a/CHANGELOG.rst b/CHANGELOG.rst
index b7c9c30..57f1300 100644
--- a/CHANGELOG.rst
+++ b/CHANGELOG.rst
@@ -1,7 +1,33 @@
+Hamcrest 2.0.4 (2022-08-07)
+==========================================
+
+Bugfixes
+--------
+
+- ``has_properties`` now returns ``Matcher[Any]`` type, which addresses type checking errors when nested as a matcher. (`#207 <https://github.com/hamcrest/PyHamcrest/issues/207>`_)
+
+
+`#207 <https://github.com/hamcrest/PyHamcrest/issues/207>`_
+
+
+Features
+^^^^^^^^
+
+ - Added Python 3.11 testing
+
+`#206 <https://github.com/hamcrest/PyHamcrest/issues/206>`_
+
+
+ Misc ^^^^
+
+ - `#175 <https://github.com/hamcrest/PyHamcrest/issues/175>`_
+
+
2.0.3 (2021-12-12)
------------------
- Features ^^^^^^^^
+Features
+^^^^^^^^
- * Adds the tests to the sdist. Fixed by #150
@@ -14,15 +40,16 @@
`#170 <https://github.com/hamcrest/PyHamcrest/issues/170>`_
- Bugfixes ^^^^^^^^
+Bugfixes
+^^^^^^^^
- - * Test coverage is now submitted to codecov.io.
+- Test coverage is now submitted to codecov.io.
Fixed by #150
`#135 <https://github.com/hamcrest/PyHamcrest/issues/135>`_
- - Change to the ``has_entry()`` matcher - if exactly one key matches, but the value does not, report only the mismatching
- value.
+
+- Change to the ``has_entry()`` matcher - if exactly one key matches, but the value does not, report only the mismatching value.
Fixed by #157
@@ -36,12 +63,6 @@
- `#150 <https://github.com/hamcrest/PyHamcrest/issues/150>`_, `#159 <https://github.com/hamcrest/PyHamcrest/issues/159>`_, `#162 <https://github.com/hamcrest/PyHamcrest/issues/162>`_, `#163 <https://github.com/hamcrest/PyHamcrest/issues/163>`_, `#166 <https://github.com/hamcrest/PyHamcrest/issues/166>`_, `#175 <https://github.com/hamcrest/PyHamcrest/issues/175>`_
-
- ----
-
-
-Changelog
-=========
Version 2.0.2
-------------
@@ -86,7 +107,7 @@ Fix #62 - Return result of a deferred call
Version 1.8.5
-------------
-Fix #56 - incorrect handling of () in is_ matcher
+Fix #56 - incorrect handling of () in ``is_`` matcher
Fix #60 - correct calling API call with args
Version 1.8.4
@@ -107,7 +128,7 @@ Version 1.8.2
Version 1.8.1
-------------
-* Added not_ alias for is_not [Matteo Bertini]
+* Added ``not_`` alias for is_not [Matteo Bertini]
* Added doc directory to the sdist [Alex Brandt]
Version 1.8
@@ -127,34 +148,36 @@ Version 1.7
-----------
2 Sep 2013 (Version 1.7.2)
+
* Supported versions
- - As of this version, support for Python 3.1 has been dropped due to no available CI platform.
- - Added support for Python 3.3
+ - As of this version, support for Python 3.1 has been dropped due to no available CI platform.
+ - Added support for Python 3.3
* Bug fixes:
- - string_contains_in_order is now used in the test as it would be in an application, and is properly exported. (Romilly Cocking)
- - Fix mismatch description of containing_inanyorder (David Keijser)
- - added import of stringmatches to text/__init__.py (Eric Scheidemantle)
- - added matches_regexp to __all__ list to library/__init__.py (Eric Scheidemantle)
+ - string_contains_in_order is now used in the test as it would be in an application, and is properly exported. (Romilly Cocking)
+ - Fix mismatch description of containing_inanyorder (David Keijser)
+ - added import of stringmatches to text/__init__.py (Eric Scheidemantle)
+ - added matches_regexp to __all__ list to library/__init__.py (Eric Scheidemantle)
5 Jan 2010 (Version 1.7.1)
+
* Bug fixes:
- - included a fix by jaimegildesagredo for issue #28 (has_properties was not importable)
- - included a fix by keys for contains_inanyorder
+ - included a fix by jaimegildesagredo for issue #28 (has_properties was not importable)
+ - included a fix by keys for contains_inanyorder
29 Dec 2012
(All changes by Chris Rose unless otherwise noted.)
* New matchers:
- - matches_regexp matches a regular expression in a string.
- - has_properties matches an object with more than one property.
- - is_empty matches any object with length 0.
+ - matches_regexp matches a regular expression in a string.
+ - has_properties matches an object with more than one property.
+ - is_empty matches any object with length 0.
* Improvements:
- - Can now do matching against old-style classes.
- - Sequence matchers handle generators, as well as actual sequences and
- pseudo-sequences.
- - README enhancements by ming13
+ - Can now do matching against old-style classes.
+ - Sequence matchers handle generators, as well as actual sequences and
+ pseudo-sequences.
+ - README enhancements by ming13
Version 1.6
@@ -181,46 +204,48 @@ Version 1.5
-----------
29 Apr 2011
+
* Packaging:
- - Python 3.1 support. Thanks to: Chris Rose
- - Easier installation with bootstrapping. Thanks to: Chris Rose
+ - Python 3.1 support. Thanks to: Chris Rose
+ - Easier installation with bootstrapping. Thanks to: Chris Rose
* Mock integration:
- - "match_equality" wraps a matcher to define equality in terms of satisfying the matcher. This allows Hamcrest matchers to be used in libraries that are not Hamcrest-aware, such as Michael Foord's mock library. Thanks to: Chris Rose
+ - "match_equality" wraps a matcher to define equality in terms of satisfying the matcher. This allows Hamcrest matchers to be used in libraries that are not Hamcrest-aware, such as Michael Foord's mock library. Thanks to: Chris Rose
* New matcher:
- - "string_contains_in_order" matches string containing given list of substrings, in order. Thanks to: Romilly Cocking
+ - "string_contains_in_order" matches string containing given list of substrings, in order. Thanks to: Romilly Cocking
* Improved matchers:
- - For consistency, changed "any_of" and "all_of" to implicitly wrap non-matcher values in EqualTo. Thanks to: Chris Rose
- - Changed "sameInstance" mismatch description to omit address when describing
- None.
+ - For consistency, changed "any_of" and "all_of" to implicitly wrap non-matcher values in EqualTo. Thanks to: Chris Rose
+ - Changed "sameInstance" mismatch description to omit address when describing None.
Version 1.4
-----------
13 Feb 2011
+
* New matchers:
- - "has_entries" matches dictionary containing key-value pairs satisfying a given list of alternating keys and value matchers.
+ - "has_entries" matches dictionary containing key-value pairs satisfying a given list of alternating keys and value matchers.
* "assert_that" can be invoked with a single boolean argument; the reason message is now optional. This is a convenience replacement for assertTrue. Thanks to: Jeong-Min Lee
* Improved descriptions:
- - Reverted 1.3 change: Describe None as "<None>" after all, since it is an object.
- - "is_" no longer says "is ..." in its description, but just lets the inner description pass through.
- - Consistently use articles to begin descriptions, such as "a sequence containing" instead of "sequence containing".
+ - Reverted 1.3 change: Describe None as "<None>" after all, since it is an object.
+ - "``is_``" no longer says "is ..." in its description, but just lets the inner description pass through.
+ - Consistently use articles to begin descriptions, such as "a sequence containing" instead of "sequence containing".
Version 1.3
-----------
04 Feb 2011
+
* PyHamcrest is now compatible with Python 3! To install PyHamcrest on Python 3:
- - Install the "distribute" package, http://pypi.python.org/pypi/distribute
- - Run "python3 setup.py install"
- Unit tests are not converted by the install procedure. Run "2to3 -nw ." separately to convert them. You may discover import statements in the __init__.py files (and one in core/base_description.py) that need dot prefixes.
- Thanks to: Jeong-Min Lee
+ - Install the "distribute" package, http://pypi.python.org/pypi/distribute
+ - Run "python3 setup.py install"
+ Unit tests are not converted by the install procedure. Run "2to3 -nw ." separately to convert them. You may discover import statements in the __init__.py files (and one in core/base_description.py) that need dot prefixes.
+ Thanks to: Jeong-Min Lee
* Improved descriptions and mismatch descriptions of several matchers, including:
- Fixed "contains" and "contains_inanyorder" to describe mismatch if item is not a sequence.
@@ -236,15 +261,16 @@ Version 1.2.1
-------------
04 Jan 2011
+
* Fixed "assert_that" to describe the diagnosis of the mismatch, not just the
mismatched value. PyHamcrest will now give even more useful information.
* Expanded BaseDescription.append_description_of to handle all types of values, not just self-describing values.
* Deprecated:
- - Description.append_value no longer needed; call append_description_of instead.
- - BaseDescription.append_value_list no longer needed; call append_list instead.
- - SelfDescribingValue no longer needed.
+ - Description.append_value no longer needed; call append_description_of instead.
+ - BaseDescription.append_value_list no longer needed; call append_list instead.
+ - SelfDescribingValue no longer needed.
1.2.1 fixes to 1.2:
- Corrected manifest so install works. Thanks to: Jeong-Min Lee
@@ -254,9 +280,10 @@ Version 1.1
-----------
28 Dec 2010
+
* New matchers:
- - "contains" matches sequence containing matching items in order.
- - "contains_inanyorder" matches sequence containing matching items in any order.
+ - "contains" matches sequence containing matching items in order.
+ - "contains_inanyorder" matches sequence containing matching items in any order.
* Added Sphinx documentation support.
diff --git a/README.rst b/README.rst
index 9be6c1b..55f6a51 100644
--- a/README.rst
+++ b/README.rst
@@ -55,7 +55,7 @@ the standard set of matchers:
.. code:: python
- from hamcrest import *
+ from hamcrest import assert_that, equal_to
import unittest
@@ -266,7 +266,7 @@ could use it in our test by importing the factory function ``on_a_saturday``:
.. code:: python
- from hamcrest import *
+ from hamcrest import assert_that, is_
import unittest
from isgivendayofweek import on_a_saturday
diff --git a/debian/changelog b/debian/changelog
index 97e2312..6f456bb 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,9 @@
+pyhamcrest (2.0.4-1) UNRELEASED; urgency=low
+
+ * New upstream release.
+
+ -- Debian Janitor <janitor@jelmer.uk> Sat, 01 Apr 2023 06:05:12 -0000
+
pyhamcrest (2.0.3-2) unstable; urgency=medium
[ Debian Janitor ]
diff --git a/doc/tutorial.rst b/doc/tutorial.rst
index baa3d6d..13ded0c 100644
--- a/doc/tutorial.rst
+++ b/doc/tutorial.rst
@@ -29,7 +29,7 @@ We'll start by writing a very simple PyUnit test, but instead of using PyUnit's
:py:func:`~hamcrest.core.matcher_assert.assert_that` construct and the standard
set of matchers::
- from hamcrest import *
+ from hamcrest import assert_that, equal_to
import unittest
class BiscuitTest(unittest.TestCase):
@@ -81,7 +81,7 @@ assure that the right issue was found::
assert_that(calling(parse, bad_data), raises(ValueError))
- assert_that(calling(translate).with_(curse_words), raises(LanguageError, "\w+very naughty"))
+ assert_that(calling(translate).with_args(curse_words), raises(LanguageError, "\w+very naughty"))
assert_that(broken_function, raises(Exception))
diff --git a/pyproject.toml b/pyproject.toml
index 859a8e2..e1045b0 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -1,7 +1,105 @@
[build-system]
-requires = ["setuptools>=40.6.0", "wheel"]
-build-backend = "setuptools.build_meta"
+requires = ["hatchling", "hatch-vcs"]
+build-backend = "hatchling.build"
+[project]
+name = "PyHamcrest"
+description = "Hamcrest framework for matcher objects"
+readme = "README.rst"
+requires-python = ">= 3.6"
+license = { file = "LICENSE.txt" }
+keywords = [
+ "hamcrest",
+ "matchers",
+ "pyunit",
+ "unit",
+ "test",
+ "testing",
+ "unittest",
+ "unittesting",
+]
+authors = [
+ { name = "Chris Rose", email="offline@offby1.net" },
+ { name = "Simon Brunning" },
+ { name = "Jon Reid" },
+]
+classifiers = [
+ "Development Status :: 5 - Production/Stable",
+ "Environment :: Console",
+ "Intended Audience :: Developers",
+ "License :: OSI Approved :: BSD License",
+ "Natural Language :: English",
+ "Operating System :: OS Independent",
+ "Programming Language :: Python :: 3",
+ "Programming Language :: Python :: 3.6",
+ "Programming Language :: Python :: 3.7",
+ "Programming Language :: Python :: 3.8",
+ "Programming Language :: Python :: 3.9",
+ "Programming Language :: Python :: 3.10",
+ "Programming Language :: Python :: 3.11",
+ "Programming Language :: Python :: Implementation :: CPython",
+ "Programming Language :: Python :: Implementation :: Jython",
+ "Programming Language :: Python :: Implementation :: PyPy",
+ "Topic :: Software Development",
+ "Topic :: Software Development :: Quality Assurance",
+ "Topic :: Software Development :: Testing",
+]
+dynamic = ["version"]
+
+[project.optional-dependencies]
+docs = ["sphinx~=4.0", "alabaster~=0.7"]
+tests = [
+ "pytest>=5.0",
+ "pytest-sugar",
+ "pytest-xdist",
+ "coverage[toml]",
+ # No point on Pypy thanks to https://github.com/python/typed_ast/issues/111
+ "pytest-mypy-plugins; platform_python_implementation != 'PyPy'",
+ # Can't use 0.940: https://github.com/python/mypy/issues/12339
+ "mypy!=0.940; platform_python_implementation != 'PyPy'",
+ "types-mock",
+ "dataclasses; python_version<'3.7'",
+ "types-dataclasses; python_version<'3.7'",
+]
+tests-numpy = [
+ "PyHamcrest[tests]",
+ "numpy",
+]
+dev = [
+ "PyHamcrest[docs,tests]",
+ "towncrier",
+ "twine",
+ "pytest-mypy",
+ "flake8",
+ "black",
+ "tox",
+ "tox-asdf",
+]
+
+[project.urls]
+History = "https://github.com/hamcrest/PyHamcrest/blob/main/CHANGELOG.rst"
+Source = "https://github.com/hamcrest/PyHamcrest/"
+Issues = "https://github.com/hamcrest/PyHamcrest/issues"
+
+[tool.hatch.version]
+source = "vcs"
+
+[tool.hatch.build.hooks.vcs]
+version-file = "src/hamcrest/_version.py"
+
+[tool.hatch.build.targets.sdist]
+exclude = [
+ "/changelog.d/*.rst",
+ "/release.sh",
+ "/.github",
+]
+[tool.hatch.build.targets.wheel]
+exclude = [
+ "/examples",
+]
+packages = [
+ "src/hamcrest",
+]
[tool.coverage.run]
parallel = true
@@ -45,13 +143,9 @@ profile = "hamcrests"
known_first_party = "hamcrest"
known_third_party = ["hypothesis", "pytest", "setuptools", "six"]
-
[tool.towncrier]
-package = "hamcrest"
-package_dir = "src"
-filename = "CHANGELOG.rst"
-template = "changelog.d/towncrier_template.rst"
-issue_format = "`#{issue} <https://github.com/hamcrest/PyHamcrest/issues/{issue}>`_"
-directory = "changelog.d"
-title_format = "{version} ({project_date})"
-underlines = ["-", "^"]
+ package = "hamcrest"
+ package_dir = "src"
+ filename = "CHANGELOG.rst"
+ directory = "changelog.d"
+ issue_format = "`#{issue} <https://github.com/hamcrest/PyHamcrest/issues/{issue}>`_"
diff --git a/setup.py b/setup.py
deleted file mode 100755
index b68895b..0000000
--- a/setup.py
+++ /dev/null
@@ -1,104 +0,0 @@
-import os
-import re
-
-from setuptools import find_packages, setup
-
-# need to kill off link if we're in docker builds
-if os.environ.get("PYTHON_BUILD_DOCKER", None) == "true":
- del os.link
-
-os.chdir(os.path.dirname(os.path.realpath(__file__)))
-
-
-def read(fname):
- return open(fname).read()
-
-
-# On Python 3, we can't "from hamcrest import __version__" (get ImportError),
-# so we extract the variable assignment and execute it ourselves.
-fh = open("src/hamcrest/__init__.py")
-
-# this will be overridden
-__version__ = None
-try:
- for line in fh:
- if re.match("__version__.*", line):
- exec(line)
-
-finally:
- if fh:
- fh.close()
-
-assert __version__ is not None
-
-REQUIREMENTS_DOCS = ["sphinx~=3.0", "alabaster~=0.7"]
-TESTS_BASIC = [
- "pytest>=5.0",
- "pytest-sugar",
- "pytest-xdist",
- "coverage[toml]",
- # No point on Pypy thanks to https://github.com/python/typed_ast/issues/111
- "pytest-mypy-plugins; platform_python_implementation != 'PyPy'",
- "types-mock",
-]
-TESTS_NUMPY = ["numpy"]
-DEV_TOOLS = [
- "towncrier",
- "twine",
- "pytest-mypy",
- "flake8",
- "black",
- "tox",
- "tox-pyenv",
- "tox-asdf",
-]
-
-
-params = dict(
- name="PyHamcrest",
- version=__version__, # flake8:noqa
- author="Chris Rose",
- author_email="offline@offby1.net",
- description="Hamcrest framework for matcher objects",
- license="New BSD",
- platforms=["All"],
- keywords="hamcrest matchers pyunit unit test testing unittest unittesting",
- url="https://github.com/hamcrest/PyHamcrest",
- download_url="http://pypi.python.org/packages/source/P/PyHamcrest/PyHamcrest-%s.tar.gz"
- % __version__,
- packages=find_packages("src"),
- package_dir={"": "src"},
- package_data={"hamcrest": ["py.typed"]},
- provides=["hamcrest"],
- long_description=read("README.rst"),
- long_description_content_type="text/x-rst",
- python_requires=">=3.5",
- install_requires=[],
- extras_require={
- "docs": REQUIREMENTS_DOCS,
- "tests": TESTS_BASIC,
- "tests-numpy": TESTS_BASIC + TESTS_NUMPY,
- "dev": REQUIREMENTS_DOCS + TESTS_BASIC + DEV_TOOLS,
- },
- classifiers=[
- "Development Status :: 5 - Production/Stable",
- "Environment :: Console",
- "Intended Audience :: Developers",
- "License :: OSI Approved :: BSD License",
- "Natural Language :: English",
- "Operating System :: OS Independent",
- "Programming Language :: Python :: 3",
- "Programming Language :: Python :: 3.6",
- "Programming Language :: Python :: 3.7",
- "Programming Language :: Python :: 3.8",
- "Programming Language :: Python :: Implementation :: CPython",
- "Programming Language :: Python :: Implementation :: Jython",
- "Programming Language :: Python :: Implementation :: PyPy",
- "Topic :: Software Development",
- "Topic :: Software Development :: Quality Assurance",
- "Topic :: Software Development :: Testing",
- ],
-)
-
-all_params = dict(params.items())
-setup(**all_params)
diff --git a/src/hamcrest/__init__.py b/src/hamcrest/__init__.py
index b307591..b40f701 100644
--- a/src/hamcrest/__init__.py
+++ b/src/hamcrest/__init__.py
@@ -1,8 +1,9 @@
from hamcrest.core import *
from hamcrest.library import *
from hamcrest import core, library
+from hamcrest._version import version
-__version__ = "2.0.3"
+__version__ = version
__author__ = "Chris Rose"
__copyright__ = "Copyright 2020 hamcrest.org"
__license__ = "BSD, see License.txt"
diff --git a/src/hamcrest/core/assert_that.py b/src/hamcrest/core/assert_that.py
index c8882bb..a31cf3a 100644
--- a/src/hamcrest/core/assert_that.py
+++ b/src/hamcrest/core/assert_that.py
@@ -16,16 +16,16 @@ T = TypeVar("T")
@overload
-def assert_that(actual: T, matcher: Matcher[T], reason: str = "") -> None:
+def assert_that(actual_or_assertion: T, matcher: Matcher[T], reason: str = "") -> None:
...
@overload
-def assert_that(assertion: bool, reason: str = "") -> None:
+def assert_that(actual_or_assertion: bool, reason: str = "") -> None:
...
-def assert_that(actual, matcher=None, reason=""):
+def assert_that(actual_or_assertion, matcher=None, reason=""):
"""Asserts that actual value satisfies matcher. (Can also assert plain
boolean condition.)
@@ -55,11 +55,11 @@ def assert_that(actual, matcher=None, reason=""):
"""
if isinstance(matcher, Matcher):
- _assert_match(actual=actual, matcher=matcher, reason=reason)
+ _assert_match(actual=actual_or_assertion, matcher=matcher, reason=reason)
else:
- if isinstance(actual, Matcher):
- warnings.warn("arg1 should be boolean, but was {}".format(type(actual)))
- _assert_bool(assertion=cast(bool, actual), reason=cast(str, matcher))
+ if isinstance(actual_or_assertion, Matcher):
+ warnings.warn("arg1 should be boolean, but was {}".format(type(actual_or_assertion)))
+ _assert_bool(assertion=cast(bool, actual_or_assertion), reason=cast(str, matcher))
def _assert_match(actual: T, matcher: Matcher[T], reason: str) -> None:
diff --git a/src/hamcrest/library/integration/__init__.py b/src/hamcrest/library/integration/__init__.py
index b28371c..e87d6e1 100644
--- a/src/hamcrest/library/integration/__init__.py
+++ b/src/hamcrest/library/integration/__init__.py
@@ -5,3 +5,5 @@ from .match_equality import match_equality
__author__ = "Jon Reid"
__copyright__ = "Copyright 2011 hamcrest.org"
__license__ = "BSD, see License.txt"
+
+__all__ = ["match_equality"]
diff --git a/src/hamcrest/library/number/__init__.py b/src/hamcrest/library/number/__init__.py
index ca9b151..85f4cf6 100644
--- a/src/hamcrest/library/number/__init__.py
+++ b/src/hamcrest/library/number/__init__.py
@@ -11,3 +11,11 @@ from .ordering_comparison import (
__author__ = "Jon Reid"
__copyright__ = "Copyright 2011 hamcrest.org"
__license__ = "BSD, see License.txt"
+
+__all__ = [
+ "close_to",
+ "greater_than",
+ "greater_than_or_equal_to",
+ "less_than",
+ "less_than_or_equal_to",
+]
diff --git a/src/hamcrest/library/number/ordering_comparison.py b/src/hamcrest/library/number/ordering_comparison.py
index 6c6275d..f121caf 100644
--- a/src/hamcrest/library/number/ordering_comparison.py
+++ b/src/hamcrest/library/number/ordering_comparison.py
@@ -22,7 +22,10 @@ class OrderingComparison(BaseMatcher[Any]):
self.comparison_description = comparison_description
def _matches(self, item: Any) -> bool:
- return self.comparison_function(item, self.value)
+ try:
+ return self.comparison_function(item, self.value)
+ except TypeError:
+ return False
def describe_to(self, description: Description) -> None:
description.append_text("a value ").append_text(self.comparison_description).append_text(
diff --git a/src/hamcrest/library/object/__init__.py b/src/hamcrest/library/object/__init__.py
index af84d7e..e015671 100644
--- a/src/hamcrest/library/object/__init__.py
+++ b/src/hamcrest/library/object/__init__.py
@@ -7,3 +7,10 @@ from .hasstring import has_string
__author__ = "Jon Reid"
__copyright__ = "Copyright 2011 hamcrest.org"
__license__ = "BSD, see License.txt"
+
+__all__ = [
+ "has_length",
+ "has_properties",
+ "has_property",
+ "has_string",
+]
diff --git a/src/hamcrest/library/object/hasproperty.py b/src/hamcrest/library/object/hasproperty.py
index b27036d..ea2519f 100644
--- a/src/hamcrest/library/object/hasproperty.py
+++ b/src/hamcrest/library/object/hasproperty.py
@@ -94,19 +94,19 @@ def has_property(name: str, match: Union[None, Matcher[V], V] = None) -> Matcher
# Keyword argument form
@overload
-def has_properties(**keys_valuematchers: Union[Matcher[V], V]) -> Matcher[object]:
+def has_properties(**keys_valuematchers: Union[Matcher[V], V]) -> Matcher[Any]:
...
# Name to matcher dict form
@overload
-def has_properties(keys_valuematchers: Mapping[str, Union[Matcher[V], V]]) -> Matcher[object]:
+def has_properties(keys_valuematchers: Mapping[str, Union[Matcher[V], V]]) -> Matcher[Any]:
...
# Alternating name/matcher form
@overload
-def has_properties(*keys_valuematchers: Any) -> Matcher[object]:
+def has_properties(*keys_valuematchers: Any) -> Matcher[Any]:
...
diff --git a/src/hamcrest/library/text/__init__.py b/src/hamcrest/library/text/__init__.py
index 291ac31..19e46c4 100644
--- a/src/hamcrest/library/text/__init__.py
+++ b/src/hamcrest/library/text/__init__.py
@@ -11,3 +11,13 @@ from .stringstartswith import starts_with
__author__ = "Jon Reid"
__copyright__ = "Copyright 2011 hamcrest.org"
__license__ = "BSD, see License.txt"
+
+__all__ = [
+ "contains_string",
+ "ends_with",
+ "equal_to_ignoring_case",
+ "equal_to_ignoring_whitespace",
+ "matches_regexp",
+ "starts_with",
+ "string_contains_in_order",
+]
diff --git a/tests/hamcrest_unit_test/collection/is_empty_test.py b/tests/hamcrest_unit_test/collection/is_empty_test.py
index 84f8eb8..44b5292 100644
--- a/tests/hamcrest_unit_test/collection/is_empty_test.py
+++ b/tests/hamcrest_unit_test/collection/is_empty_test.py
@@ -19,7 +19,7 @@ class EmptyCollectionTest(MatcherTest):
matcher = empty()
self.assert_matches("empty tuple", matcher, ())
self.assert_matches("empty list", matcher, [])
- self.assert_matches("emtpy dictionary", matcher, {})
+ self.assert_matches("empty dictionary", matcher, {})
def testReturnsTrueForEmptyCollectionLike(self):
matcher = empty()
@@ -29,7 +29,7 @@ class EmptyCollectionTest(MatcherTest):
matcher = empty()
self.assert_does_not_match("non-empty tuple", matcher, (1,))
self.assert_does_not_match("non-empty list", matcher, [1])
- self.assert_does_not_match("emtpy dictionary", matcher, {1: 2})
+ self.assert_does_not_match("empty dictionary", matcher, {1: 2})
def testReturnsFalseForNonEmptyCollectionLike(self):
matcher = empty()
diff --git a/tests/hamcrest_unit_test/collection/issequence_containinginanyorder_test.py b/tests/hamcrest_unit_test/collection/issequence_containinginanyorder_test.py
index 5c21fbb..b36d192 100644
--- a/tests/hamcrest_unit_test/collection/issequence_containinginanyorder_test.py
+++ b/tests/hamcrest_unit_test/collection/issequence_containinginanyorder_test.py
@@ -1,5 +1,6 @@
import unittest
+from hamcrest import greater_than
from hamcrest.core.core.isequal import equal_to
from hamcrest.library.collection.issequence_containinginanyorder import contains_inanyorder
from hamcrest_unit_test.matcher_test import MatcherTest
@@ -84,6 +85,16 @@ class IsSequenceContainingInAnyOrderBase(object):
"no item matches: <2> in [<3>, <1>]", matcher, self._sequence(3, 1)
)
+ def testIncomparableTypes(self):
+ self.assert_matches("Incomparable types", contains_inanyorder(*[4, "a"]), ["a", 4])
+
+ def testIncomparableTypesInNestedMatcher(self):
+ self.assert_matches(
+ "Incomparable types in nested matcher",
+ contains_inanyorder(*[greater_than(0), "a"]),
+ ["a", 4],
+ )
+
class IsConcreteSequenceContainingInAnyOrderTest(
MatcherTest, IsSequenceContainingInAnyOrderBase, SequenceForm
diff --git a/tests/hamcrest_unit_test/number/ordering_comparison_test.py b/tests/hamcrest_unit_test/number/ordering_comparison_test.py
index 76143df..d944519 100644
--- a/tests/hamcrest_unit_test/number/ordering_comparison_test.py
+++ b/tests/hamcrest_unit_test/number/ordering_comparison_test.py
@@ -67,6 +67,9 @@ class OrderingComparisonTest(MatcherTest):
self.assert_describe_mismatch("was <0>", greater_than_or_equal_to(1), 0)
self.assert_describe_mismatch("was <2>", less_than_or_equal_to(1), 2)
+ def testIncomparableTypes(self):
+ self.assert_does_not_match("incomparable types", greater_than(1), "a")
+
if __name__ == "__main__":
unittest.main()
diff --git a/tests/type-hinting/library/collection/test_empty.yml b/tests/type-hinting/library/collection/test_empty.yml
index 5264802..cf815c7 100644
--- a/tests/type-hinting/library/collection/test_empty.yml
+++ b/tests/type-hinting/library/collection/test_empty.yml
@@ -5,4 +5,4 @@
from hamcrest import assert_that, is_, empty
assert_that([], empty())
- assert_that(99, empty()) # E: Cannot infer type argument 1 of "assert_that"
\ No newline at end of file
+ assert_that(99, empty()) # E: Cannot infer type argument 1 of "assert_that"
diff --git a/tests/type-hinting/library/collection/test_generics.yml b/tests/type-hinting/library/collection/test_generics.yml
new file mode 100644
index 0000000..4666d5f
--- /dev/null
+++ b/tests/type-hinting/library/collection/test_generics.yml
@@ -0,0 +1,27 @@
+- case: valid_has_items_has_properties
+ skip: platform.python_implementation() == "PyPy"
+ main: |
+ from dataclasses import dataclass
+ from hamcrest import assert_that, has_items, has_properties
+
+ @dataclass
+ class Example:
+ name: str
+
+ items = [Example("dave"), Example("wave")]
+
+ a = assert_that(items, has_items(has_properties(name="dave")))
+
+- case: valid_has_item_has_properties
+ skip: platform.python_implementation() == "PyPy"
+ main: |
+ from dataclasses import dataclass
+ from hamcrest import assert_that, has_item, has_properties
+
+ @dataclass
+ class Example:
+ name: str
+
+ items = [Example("dave"), Example("wave")]
+ matcher = has_item(has_properties(name="dave"))
+ a = assert_that(items, matcher)
diff --git a/tox.ini b/tox.ini
index 037665a..6c0c1fd 100644
--- a/tox.ini
+++ b/tox.ini
@@ -17,6 +17,7 @@ python =
3.8: py38, py38-numpy
3.9: py39, py39-numpy, lint, manifest, typing, changelog, docs
3.10: py310
+ 3.11: py311
pypy-2: pypy2
pypy-3: pypy3
@@ -96,6 +97,16 @@ setenv =
extras = {env:TOX_AP_TEST_EXTRAS:tests}
commands = coverage run -m pytest {posargs}
+[testenv:py311]
+# Python 3.6+ has a number of compile-time warnings on invalid string escapes.
+# PYTHONWARNINGS=d and --no-compile below make them visible during the Tox run.
+basepython = python3.11
+install_command = pip install --no-compile {opts} {packages}
+setenv =
+ PYTHONWARNINGS=d
+extras = {env:TOX_AP_TEST_EXTRAS:tests}
+commands = coverage run -m pytest {posargs}
+
[testenv:coverage-report]
basepython = python3.9
skip_install = true
@@ -104,7 +115,6 @@ commands =
coverage combine
coverage report
-
[testenv:lint]
basepython = python3.9
skip_install = true
@@ -125,9 +135,11 @@ commands =
[testenv:manifest]
basepython = python3.9
-deps = check-manifest
+deps =
+ check-manifest
+ setuptools-scm
skip_install = true
-commands = check-manifest
+commands = check-manifest --ignore src/hamcrest/_version.py
[testenv:pypi-description]
More details
Historical runs
- failed: E: pybuild pybuild:128: cannot detect build system, please use --system option or set PYBUILD_SYSTEM env. variable
- new-upstream-tarball-missing: New upstream version (pyhamcrest/2.0.4+ds) found, but was missing when retrieved as tarball from <UScanSource(<GitWorkingTree of /tmp/janitoria004law/pyhamcrest>, subpath='', top_level=False, auto_fix=True)>.
- new-upstream-tarball-missing: New upstream version (pyhamcrest/2.0.4+ds) found, but was missing when retrieved as tarball from <UScanSource(<GitWorkingTree of /tmp/janitorhyvg_xtv/pyhamcrest>, subpath='', top_level=False, auto_fix=True)>.
- new-upstream-tarball-missing: New upstream version (pyhamcrest/2.0.4+ds) found, but was missing when retrieved as tarball from <UScanSource(<GitWorkingTree of /tmp/janitorapv2zd8h/pyhamcrest>, subpath='', top_level=False, auto_fix=True)>.
- success: Merged new upstream version 2.0.3