Science Score: 26.0%
This score indicates how likely this project is to be science-related based on various indicators:
-
○CITATION.cff file
-
✓codemeta.json file
Found codemeta.json file -
✓.zenodo.json file
Found .zenodo.json file -
○DOI references
-
○Academic publication links
-
○Committers with academic emails
-
○Institutional organization owner
-
○JOSS paper metadata
-
○Scientific vocabulary similarity
Low similarity (16.0%) to scientific vocabulary
Keywords
Keywords from Contributors
Repository
:pancakes: The sweeter pytest snapshot plugin
Basic Info
- Host: GitHub
- Owner: syrupy-project
- License: mit
- Language: Python
- Default Branch: main
- Homepage: https://syrupy-project.github.io/syrupy/
- Size: 12.2 MB
Statistics
- Stars: 685
- Watchers: 5
- Forks: 43
- Open Issues: 21
- Releases: 0
Topics
Metadata Files
README.md
syrupy
Note that the main branch points to the v5 pre-release. To see documentation for the latest stable release, see the README for v4.9.1.

Overview
Syrupy is a zero-dependency pytest snapshot plugin. It enables developers to write tests which assert immutability of computed results.
Motivation
The most popular snapshot test plugin compatible with pytest has some core limitations which this package attempts to address by upholding some key values:
- Extensible: If a particular data type is not supported, users should be able to easily and quickly add support.
- Idiomatic: Snapshot testing should fit naturally among other test cases in pytest, e.g.
assert x == snapshotvs.snapshot.assert_match(x). - Soundness: Snapshot tests should uncover even the most minute issues. Unlike other snapshot libraries, Syrupy will fail a test suite if a snapshot does not exist, not just on snapshot differences.
Installation
shell
python -m pip install syrupy
Migration from snapshottest
You cannot use syrupy alongside snapshottest due to argument conflicts. To ease migration, we've made syrupy aware of snapshottest call syntax. Simply uninstall snapshottest and remove old snapshots:
shell
pip uninstall snapshottest -y;
find . -type d ! -path '*/\.*' -name 'snapshots' | xargs rm -r
Pytest and Python Compatibility
Syrupy will always be compatible with the latest version of Python and Pytest. If you're running an old version of Python or Pytest, you will need to use an older major version of Syrupy:
| Syrupy Version | Python Support | Pytest Support | | -------------- | -------------- | -------------- | | 5.x.x | >3.9 | >=8 | | 4.x.x | >3.8.1, | >=7, <9 | | 3.x.x | >=3.7, <4 | >=5.1, <8 | | 2.x.x | >=3.6, <4 | >=5.1, <8 |
Usage
Basic Usage
In a pytest test file test_file.py:
python
def test_foo(snapshot):
actual = "Some computed value!"
assert actual == snapshot
when you run pytest, the above test should fail due to a missing snapshot. Re-run pytest with the update snapshots flag like so:
shell
pytest --snapshot-update
A snapshot file should be generated under a __snapshots__ directory in the same directory as test_file.py. The __snapshots__ directory and all its children should be committed along with your test code.
Custom Objects
The default serializer supports all python built-in types and provides a sensible default for custom objects.
Representation
If you need to customise your object snapshot, it is as easy as overriding the default __repr__ implementation.
python
def __repr__(self) -> str:
return "MyCustomClass(...)"
If you need bypass a custom object representation to use the amber standard, it is easy using the following helpers.
python
def test_object_as_named_tuple(snapshot):
assert snapshot == AmberDataSerializer.object_as_named_tuple(obj_with_custom_repr)
See
test_snapshot_object_as_named_tuple_classfor an example on automatically doing this for all nested properties
Attributes
If you want to limit what properties are serialized at a class type level you could either:
A. Provide a filter function to the snapshot exclude configuration option.
```py def limitfooattrs(prop, path): allowedfooattrs = {"do", "not", "serialize", "these", "attrs"} return isinstance(path[-1][1], Foo) and prop in allowedfooattrs
def testbar(snapshot): actual = Foo(...) assert actual == snapshot(exclude=limitfoo_attrs) ```
B. Provide a filter function to the snapshot include configuration option.
```py def limitfooattrs(prop, path): allowedfooattrs = {"only", "serialize", "these", "attrs"} return isinstance(path[-1][1], Foo) and prop in allowedfooattrs
def testbar(snapshot): actual = Foo(...) assert actual == snapshot(include=limitfoo_attrs) ```
C. Or override the __dir__ implementation to control the attribute list.
```py class Foo: def dir(self): return ["only", "serialize", "these", "attrs"]
def test_bar(snapshot): actual = Foo(...) assert actual == snapshot ```
Both options will generate equivalent snapshots but the latter is only viable when you have control over the class implementation and do not need to share the exclusion logic with other objects.
CLI Options
These are the cli options exposed to pytest by the plugin.
| Option | Description | Default |
| ------------------------------ |--------------------------------------------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------|
| --snapshot-update | Snapshots will be updated to match assertions and unused snapshots will be deleted. | False |
| --snapshot-details | Includes details of unused, generated, and updated snapshots (test name and snapshot location) in the final report. | False |
| --snapshot-warn-unused | Prints a warning on unused snapshots rather than fail the test suite. | False |
| --snapshot-default-extension | Use to change the default snapshot extension class. | AmberSnapshotExtension |
| --snapshot-no-colors | Disable test results output highlighting. Equivalent to setting the environment variables ANSI_COLORS_DISABLED or NO_COLOR | Disabled by default if not in terminal. |
| --snapshot-patch-pycharm-diff| Override PyCharm's default diffs viewer when looking at snapshot diffs. See IDE Integrations | False |
| --snapshot-diff-mode | Configures how diffs are displayed on assertion failure. If working with very large snapshots, disabling the diff can improve performance. | detailed |
| --snapshot-ignore-file-extensions | Comma separated list of file extensions to ignore when walking the file tree and discovering used/unused snapshots. | No extensions are ignored by default. |
Assertion Options
These are the options available on the snapshot assertion fixture.
Use of these options are one shot and do not persist across assertions.
For more persistent options see advanced usage.
matcher
This allows you to match on a property path and value to control how specific object shapes are serialized.
The matcher is a function that takes two keyword arguments. It should return the replacement value to be serialized or the original unmutated value.
| Argument | Description |
| -------- | ------------------------------------------------------------------------------------------------------------------ |
| data | Current serializable value being matched on |
| path | Ordered path traversed to the current value e.g. (("a", dict), ("b", dict)) from { "a": { "b": { "c": 1 } } }} |
NOTE: Do not mutate the value received as it could cause unintended side effects.
Composing Matchers
Multiple matchers can be composed together using matchers, e.g.:
```py from syrupy.matchers import compose_matchers
def testmultiplematchers(snapshot): data = { "number": 1, "datetime": datetime.datetime.now(), "float": 1.3 }
assert data == snapshot(
matcher=compose_matchers(
path_type(types=(int, float), replacer=lambda *_: "MATCHER_1"),
path_type(types=(datetime.datetime,), replacer=lambda *_: "MATCHER_2"),
),
)
```
Built-In Matchers
Syrupy comes with built-in helpers that can be used to make easy work of using property matchers.
path_type(mapping=None, *, types=(), strict=True, regex=False)
Easy way to build a matcher that uses the path and value type to replace serialized data.
When strict, this will raise a ValueError if the types specified are not matched.
| Argument | Description |
| ---------- | ---------------------------------------------------------------------------------------------------------------------------------- |
| mapping | Dict of path string to tuples of class types, including primitives e.g. (MyClass, UUID, datetime, int, str) |
| types | Tuple of class types used if none of the path strings from the mapping are matched |
| strict | If a path is matched but the value at the path does not match one of the class types in the tuple then a PathTypeError is raised |
| regex | If true, the mapping key is treated as a regular expression when matching paths |
| replacer | Called with any matched value and result is used as the replacement that is serialized. Defaults to the object type when not given |
```py from syrupy.matchers import path_type
def testbar(snapshot): actual = { "datecreated": datetime.now(), "value": "Some computed value!!", } assert actual == snapshot(matcher=pathtype({ "datecreated": (datetime,), "nested.path.id": (int,), })) ```
```py
name: test_bar
dict({ 'date_created': datetime, 'value': 'Some computed value!!', })
---
```
NOTE: When
regexisTrueall matcher mappings are treated as regex patterns
path_value(mapping=None, *, **kwargs)
Shares the same kwargs as path_type matcher, with the exception of the mapping argument type.
Only runs replacement for objects at a matching path where the value of the mapping also matches the object data string repr.
| Argument | Description |
| --------- | ---------------------------------------------------------- |
| mapping | Dict of path string to object value string representations |
See
test_regex_matcher_str_valuefor example usage.
exclude
This allows you to filter out object properties from the serialized snapshot.
The exclude parameter takes a filter function that accepts two keyword arguments.
It should return true if the property should be excluded, or false if the property should be included.
| Argument | Description |
| -------- | --------------------------------------------------------------------------------------------------------------------------------------------- |
| prop | Current property on the object, could be any hashable value that can be used to retrieve a value e.g. 1, "prop_str", SomeHashableObject |
| path | Ordered path traversed to the current value e.g. (("a", dict), ("b", dict)) from { "a": { "b": { "c": 1 } } }} |
Built-In Filters
Syrupy comes with built-in helpers that can be used to make easy work of using the filter options.
props(prop_name, *prop_name)
Easy way to build a filter that excludes based on string based property names.
Takes an argument list of property names, with support for indexed iterables.
```py from syrupy.filters import props
def test_bar(snapshot): actual = { "id": uuid.uuid4(), "list": [1,2,3], } assert actual == snapshot(exclude=props("id", "1")) ```
```py
name: test_bar
dict({ 'list': list([ 1, 3, ]), })
---
```
paths(path_string, *path_strings)
Easy way to build a filter that uses full path strings delimited with ..
Takes an argument list of path strings.
```py from syrupy.filters import paths
def test_bar(snapshot): actual = { "date": datetime.now(), "list": [1,2,3], } assert actual == snapshot(exclude=paths("date", "list.1")) ```
```py
name: test_bar
dict({ 'list': list([ 1, 3, ]), })
---
```
include
This allows you filter an object's properties to a subset using a predicate. This is the opposite of exclude. All the same property filters supporterd by exclude are supported for include.
The include parameter takes a filter function that accepts two keyword arguments.
It should return true if the property should be include, or false if the property should not be included.
| Argument | Description |
| -------- | --------------------------------------------------------------------------------------------------------------------------------------------- |
| prop | Current property on the object, could be any hashable value that can be used to retrieve a value e.g. 1, "prop_str", SomeHashableObject |
| path | Ordered path traversed to the current value e.g. (("a", dict), ("b", dict)) from { "a": { "b": { "c": 1 } } }}
Note that include has some caveats which make it a bit more difficult to use than exclude. Both include and exclude are evaluated for each key of an object before traversing down nested paths. This means if you want to include a nested path, you must include all parents of the nested path, otherwise the nested child will never be reached to be evaluated against the include predicate. For example:
py
obj = {
"nested": { "key": True }
}
assert obj == snapshot(include=paths("nested", "nested.key"))
The extra "nested" is required, otherwise the nested dictionary will never be searched -- it'd get pruned too early.
To avoid adding duplicate path parts, we provide a convenient paths_include which supports a list/tuple instead of a string for each path to match:
py
obj = {
"other": False,
"nested": { "key": True }
}
assert obj == snapshot(include=paths_include(["other"], ["nested", "key"]))
extension_class
This is a way to modify how the snapshot matches and serializes your data in a single assertion.
py
def test_foo(snapshot):
actual_svg = "<svg></svg>"
assert actual_svg == snapshot(extension_class=SVGImageSnapshotExtension)
diff
This is an option to snapshot only the diff between the actual object and a previous snapshot, with the diff argument being the previous snapshot index/name.
```py def test_diff(snapshot): actual0 = [1,2,3,4] actual1 = [0,1,3,4]
assert actual0 == snapshot
assert actual1 == snapshot(diff=0)
# This is equivalent to the lines above
# Must use the index name to diff when given
assert actual0 == snapshot(name='snap_name')
assert actual1 == snapshot(diff='snap_name')
```
Built-In Extensions
Syrupy comes with a few built-in preset configurations for you to choose from. You should also feel free to extend the AbstractSyrupyExtension if your project has a need not captured by one our built-ins.
Amber Extensions
AmberSnapshotExtension: This is the default extension which generates.ambrfiles. Serialization of most data types are supported.- Line control characters are normalised when snapshots are generated i.e.
\rand\ncharacters are all written as\n. This is to allow interoperability of snapshots between operating systems that use disparate line control characters.
- Line control characters are normalised when snapshots are generated i.e.
SingleFileAmberSnapshotExtension: A variant of theAmberSnapshotExtensionwhich writes 1 snapshot per file.
Other Formats
SingleFileSnapshotExtension: This extension creates one.rawfile per test case. Note that the default behaviour of the SingleFileSnapshotExtension is to write raw bytes to disk. There is no further "serialization" that happens. TheSingleFileSnapshotExtensionis mostly used as a building block for other extensions such as the image extensions, the JSON extension, as well as theSingleFileAmberSnapshotExtensionextension. In the default "binary" mode, attempting to serialize a non-byte-like object will throw a TypeError.PNGImageSnapshotExtension: An extension of single file, this should be used to produce.pngfiles from a byte string.SVGImageSnapshotExtension: Another extension of single file. This produces.svgfiles from an svg string.JSONSnapshotExtension: Another extension of single file. This produces.jsonfiles from dictionaries and lists.
name
By default, if you make multiple snapshot assertions within a single test case, an auto-increment identifier will be used to index the snapshots. You can override this behaviour by specifying a custom snapshot name to use in place of the auto-increment number.
py
def test_case(snapshot):
assert "actual" == snapshot(name="case_a")
assert "other" == snapshot(name="case_b")
Warning: If you use a custom name, you must make sure the name is not re-used within a test case.
Advanced Usage
By overriding the provided AbstractSyrupyExtension you can implement varied custom behaviours.
See examples of how syrupy can be used and extended in the test examples.
Overriding defaults
It is possible to override include, exclude, matchers and extension_class on a more global level just once,
instead of every time per test. By default, after every assertion the modified values per snapshot assert are reverted
to their default values. However, it is possible to override those default values with ones you would like persisted,
which will be treated as the new defaults.
To achieve that you can use snapshot.with_defaults, which will create new instance of SnapshotAssertion with the provided values.
snapshot.use_extension is retained for compatibility. However, it is limited to only overriding the default extension class.
JSONSnapshotExtension
This extension can be useful when testing API responses, or when you have to deal with long dictionaries that are cumbersome to validate inside a test. For example:
```python import pytest
from syrupy.extensions.json import JSONSnapshotExtension
@pytest.fixture def snapshotjson(snapshot): return snapshot.withdefaults(extensionclass=JSONSnapshotExtension) # or return snapshot.useextension(JSONSnapshotExtension)
def testapicall(client, snapshotjson): resp = client.post("/endpoint") assert resp.statuscode == 200 assert snapshot_json == resp.json() ```
API responses often contain dynamic data, like IDs or dates. You can still validate and store other data of a response by leveraging syrupy matchers. For example:
```py from datetime import datetime
from syrupy.matchers import path_type
def testapicall(client, snapshotjson): resp = client.post("/user", json={"name": "Jane"}) assert resp.statuscode == 201
matcher = path_type({
"id": (int,),
"registeredAt": (datetime,)
})
assert snapshot_json(matcher=matcher) == resp.json()
```
The generated snapshot:
json
{
"id": "<class 'int'>",
"registeredAt": "<class 'datetime'>",
"name": "Jane"
}
Or a case where the value needs to be replaced using a condition e.g. file path string
```py import re
from syrupy.matchers import path_type
def testmatchesgeneratedstringvalue(snapshot, tmpfile):
matcher = pathvalue(
mapping={"file_path": r"\w+://(.*/)+dir/filename.txt"},
replacer=lambda _, match: match[0].replace(match[1], "
assert snapshot(matcher=matcher) == tmp_file
```
The generated snapshot:
json
{
"name": "Temp Files",
"file_path": "scheme://<tmp-file-path>/dir/filename.txt"
}
Ignoring File Extensions (e.g. DVC Integration)
If using a tool such as DVC or other tool where you need to ignore files by file extension, you can update your pytest.ini like so:
ini
[pytest]
addopts = --snapshot-ignore-file-extensions dvc
A comma separated list is supported, like so:
ini
[pytest]
addopts = --snapshot-ignore-file-extensions dvc,tmp,zip
Extending Syrupy
- Custom defaults
- Custom snapshot directory 1
- Custom snapshot directory 2
- Custom snapshot name
- Custom object snapshots
- Custom comparator
- JPEG image extension
- Built-in image extensions
Inline Snapshots
Syrupy does not support inline snapshots. For inline snapshots, we recommend checking out the inline-snapshot library.
IDE Integrations
PyCharm
The PyCharm IDE comes with a built-in tool for visualizing differences between expected and actual results in a test. To properly render Syrupy snapshots in the PyCharm diff viewer, we need to apply a patch to the diff viewer library. To do this, use the --snapshot-patch-pycharm-diff flag, e.g.:
In your pytest.ini:
ini
[pytest]
addopts = --snapshot-patch-pycharm-diff
See #675 for the original issue.
Known Limitations
pytest-xdistsupport only partially exists. There is no issue when it comes to reads however when you attempt to runpytest --snapshot-update, if running with more than 1 process, the ability to detect unused snapshots is disabled. See #535 for more information.
We welcome contributions to patch these known limitations.
Uninstalling
python
pip uninstall syrupy
If you have decided not to use Syrupy for your project after giving us a try, we'd love to get your feedback. Please create a GitHub issue if applicable.
Contributing
Feel free to open a PR or GitHub issue. Contributions welcome!
To develop locally, clone this repository and run . script/bootstrap to install test dependencies. You can then use invoke --list to see available commands.
See contributing guide
Contributors
This section is automatically generated via tagging the all-contributors bot in a PR:
text
@all-contributors please add <username> for <contribution type>
License
Syrupy is licensed under MIT.
Owner
- Name: Syrupy
- Login: syrupy-project
- Kind: organization
- Repositories: 1
- Profile: https://github.com/syrupy-project
GitHub Events
Total
- Create event: 61
- Release event: 6
- Issues event: 35
- Watch event: 139
- Delete event: 67
- Issue comment event: 218
- Push event: 542
- Pull request review comment event: 18
- Pull request event: 157
- Pull request review event: 481
- Fork event: 6
Last Year
- Create event: 61
- Release event: 6
- Issues event: 35
- Watch event: 139
- Delete event: 67
- Issue comment event: 218
- Push event: 542
- Pull request review comment event: 18
- Pull request event: 157
- Pull request review event: 481
- Fork event: 6
Committers
Last synced: over 1 year ago
Top Committers
| Name | Commits | |
|---|---|---|
| dependabot-preview[bot] | 2****] | 197 |
| Noah | n****r@t****m | 118 |
| Emmanuel Ogbizi | i****b@g****m | 101 |
| renovate[bot] | 2****] | 94 |
| semantic-release-bot | s****t@m****t | 91 |
| Noah | n****u@g****m | 55 |
| allcontributors[bot] | 4****] | 31 |
| Top Hat Open Source Bot | 7****t | 29 |
| dependabot[bot] | 4****] | 6 |
| Marc Cataford | m****d@t****m | 3 |
| Huon Wilson | h****n@e****o | 3 |
| Jimmy Jia | t****n@g****m | 2 |
| Magnus Heskestad Waage | 5****e | 1 |
| ManiacDC | M****C | 1 |
| Tolga Eren | 7****n | 1 |
| darrenburns | d****s | 1 |
| dtczest | 9****t | 1 |
| syrupy-bot | 6****t | 1 |
| Atharva Arya | 5****1 | 1 |
| Allan Chain | 3****n | 1 |
| Huon Wilson | w****n@g****m | 1 |
| Joakim Nordling | j****g@g****m | 1 |
| Elizabeth Culbertson | 3****b | 1 |
| Eddie Darling | 5****e | 1 |
| John Kurkowski | j****i@g****m | 1 |
| Adam Lazzarato | a****o@g****m | 1 |
| Artur Balabanov | a****7@g****m | 1 |
| Dmitry Dygalo | d****o@g****m | 1 |
| Umar Ahmed | u****8@g****m | 1 |
| Tommaso A | me@t****m | 1 |
| and 4 more... | ||
Committer Domains (Top 20 + Academic)
Issues and Pull Requests
Last synced: 6 months ago
All Time
- Total issues: 39
- Total pull requests: 110
- Average time to close issues: about 1 year
- Average time to close pull requests: 16 days
- Total issue authors: 34
- Total pull request authors: 13
- Average comments per issue: 1.95
- Average comments per pull request: 0.83
- Merged pull requests: 80
- Bot issues: 1
- Bot pull requests: 66
Past Year
- Issues: 19
- Pull requests: 91
- Average time to close issues: 8 days
- Average time to close pull requests: 5 days
- Issue authors: 18
- Pull request authors: 11
- Average comments per issue: 0.58
- Average comments per pull request: 0.84
- Merged pull requests: 66
- Bot issues: 1
- Bot pull requests: 54
Top Authors
Issue Authors
- noahnu (5)
- epenet (2)
- tylerlaprade (1)
- guidopetri (1)
- StephanMeijer (1)
- jcbhmr (1)
- gwww (1)
- Kakadus (1)
- renovate[bot] (1)
- KaeganCasey (1)
- vhive-nir-lederfein (1)
- sparrowt (1)
- JerryLui (1)
- pickfire (1)
- RobertCraigie (1)
Pull Request Authors
- renovate[bot] (60)
- noahnu (26)
- epenet (9)
- allcontributors[bot] (6)
- kloczek (1)
- AllanChain (1)
- samylaumonier (1)
- paul-ollis (1)
- sparrowt (1)
- joostlek (1)
- UltimateLobster (1)
- rahuliyer95 (1)
- huonw (1)
Top Labels
Issue Labels
Pull Request Labels
Packages
- Total packages: 7
-
Total downloads:
- pypi 3,658,885 last-month
- Total docker downloads: 755,284,678
-
Total dependent packages: 46
(may contain duplicates) -
Total dependent repositories: 1,070
(may contain duplicates) - Total versions: 143
- Total maintainers: 2
pypi.org: syrupy
Pytest Snapshot Test Utility
- Homepage: https://github.com/syrupy-project/syrupy
- Documentation: https://syrupy.readthedocs.io/
- License: Apache-2.0
-
Latest release: 4.9.1
published 11 months ago
Rankings
Maintainers (1)
alpine-edge: py3-syrupy-pyc
Precompiled Python bytecode for py3-syrupy
- Homepage: https://github.com/syrupy-project/syrupy
- License: Apache-2.0
-
Latest release: 4.9.1-r0
published 11 months ago
Rankings
Maintainers (1)
alpine-edge: py3-syrupy
Pytest Snapshot Test Utility
- Homepage: https://github.com/syrupy-project/syrupy
- License: Apache-2.0
-
Latest release: 4.9.1-r0
published 11 months ago
Rankings
Maintainers (1)
alpine-v3.22: py3-syrupy-pyc
Precompiled Python bytecode for py3-syrupy
- Homepage: https://github.com/syrupy-project/syrupy
- License: Apache-2.0
-
Latest release: 4.9.1-r0
published 11 months ago
Rankings
Maintainers (1)
alpine-v3.21: py3-syrupy-pyc
Precompiled Python bytecode for py3-syrupy
- Homepage: https://github.com/syrupy-project/syrupy
- License: Apache
-
Latest release: 4.8.0-r0
published about 1 year ago
Rankings
Maintainers (1)
alpine-v3.21: py3-syrupy
Pytest Snapshot Test Utility
- Homepage: https://github.com/syrupy-project/syrupy
- License: Apache
-
Latest release: 4.8.0-r0
published about 1 year ago
Rankings
Maintainers (1)
alpine-v3.22: py3-syrupy
Pytest Snapshot Test Utility
- Homepage: https://github.com/syrupy-project/syrupy
- License: Apache-2.0
-
Latest release: 4.9.1-r0
published 11 months ago
Rankings
Maintainers (1)
Dependencies
- black 22.6.0 develop
- bleach 5.0.1 develop
- certifi 2022.6.15 develop
- cffi 1.15.1 develop
- charset-normalizer 2.1.0 develop
- click 8.1.3 develop
- codecov 2.1.12 develop
- commonmark 0.9.1 develop
- configparser 5.2.0 develop
- coverage 6.4.3 develop
- cryptography 37.0.4 develop
- debugpy 1.6.2 develop
- docutils 0.19 develop
- flake8 3.9.2 develop
- flake8-bugbear 21.11.29 develop
- flake8-builtins 1.5.3 develop
- flake8-comprehensions 3.10.0 develop
- flake8-i18n 0.1.0 develop
- idna 3.3 develop
- invoke 1.7.1 develop
- isort 5.10.1 develop
- jeepney 0.8.0 develop
- keyring 23.8.2 develop
- mccabe 0.6.1 develop
- mypy 0.960 develop
- mypy-extensions 0.4.3 develop
- pathspec 0.9.0 develop
- pkginfo 1.8.3 develop
- platformdirs 2.5.2 develop
- py-cpuinfo 8.0.0 develop
- py-githooks 1.1.1 develop
- pycodestyle 2.7.0 develop
- pycparser 2.21 develop
- pyflakes 2.3.1 develop
- pygments 2.12.0 develop
- pytest-benchmark 3.4.1 develop
- pywin32-ctypes 0.2.0 develop
- readme-renderer 36.0 develop
- requests 2.28.1 develop
- requests-toolbelt 0.9.1 develop
- rfc3986 2.0.0 develop
- rich 12.5.1 develop
- secretstorage 3.3.2 develop
- semver 2.13.0 develop
- setuptools 64.0.0 develop
- setuptools-scm 7.0.5 develop
- six 1.16.0 develop
- twine 4.0.1 develop
- typed-ast 1.5.4 develop
- urllib3 1.26.11 develop
- webencodings 0.5.1 develop
- atomicwrites 1.4.1
- attrs 22.1.0
- colorama 0.4.5
- colored 1.4.3
- importlib-metadata 4.12.0
- iniconfig 1.1.1
- packaging 21.3
- pluggy 1.0.0
- py 1.11.0
- pyparsing 3.0.9
- pytest 7.1.2
- tomli 2.0.1
- typing-extensions 4.3.0
- zipp 3.8.1
- colored >=1.3.92,<2.0.0
- pytest >=5.1.0,<8.0.0
- python >=3.7,<4
- actions/setup-python v4.4.0 composite
- snok/install-poetry v1.3.3 composite
- ./.github/actions/setup-env * composite
- actions/checkout v3.1.0 composite
- benchmark-action/github-action-benchmark v1 composite
- ./.github/actions/setup-env * composite
- actions/checkout v3.1.0 composite
- benchmark-action/github-action-benchmark v1 composite
- cycjimmy/semantic-release-action v3.2.0 composite
- ./.github/actions/setup-env * composite
- actions/checkout v3.1.0 composite
- cycjimmy/semantic-release-action v3.2.0 composite
- mcr.microsoft.com/vscode/devcontainers/python 0-${VARIANT} build