-
-
Notifications
You must be signed in to change notification settings - Fork 11
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
docs: documentation for register_repr
- Loading branch information
Showing
5 changed files
with
206 additions
and
103 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,106 @@ | ||
|
||
## Code generation | ||
|
||
You can use almost any python datatype and also complex values like `datatime.date`, because `repr()` is used to convert the values to source code. | ||
The default `__repr__()` behaviour can be overwritten with [register_repr](register_repr.md). | ||
It might be necessary to import the right modules to match the `repr()` output. | ||
|
||
=== "original code" | ||
<!-- inline-snapshot: outcome-passed=1 outcome-errors=1 --> | ||
```python | ||
from inline_snapshot import snapshot | ||
import datetime | ||
|
||
|
||
def something(): | ||
return { | ||
"name": "hello", | ||
"one number": 5, | ||
"numbers": list(range(10)), | ||
"sets": {1, 2, 15}, | ||
"datetime": datetime.date(1, 2, 22), | ||
"complex stuff": 5j + 3, | ||
"bytes": b"fglecg\n\x16", | ||
} | ||
|
||
|
||
def test_something(): | ||
assert something() == snapshot() | ||
``` | ||
=== "--inline-snapshot=create" | ||
<!-- inline-snapshot: create outcome-passed=1 --> | ||
```python | ||
from inline_snapshot import snapshot | ||
import datetime | ||
|
||
|
||
def something(): | ||
return { | ||
"name": "hello", | ||
"one number": 5, | ||
"numbers": list(range(10)), | ||
"sets": {1, 2, 15}, | ||
"datetime": datetime.date(1, 2, 22), | ||
"complex stuff": 5j + 3, | ||
"bytes": b"fglecg\n\x16", | ||
} | ||
|
||
|
||
def test_something(): | ||
assert something() == snapshot( | ||
{ | ||
"name": "hello", | ||
"one number": 5, | ||
"numbers": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9], | ||
"sets": {1, 2, 15}, | ||
"datetime": datetime.date(1, 2, 22), | ||
"complex stuff": (3 + 5j), | ||
"bytes": b"fglecg\n\x16", | ||
} | ||
) | ||
``` | ||
|
||
The code is generated in the following way: | ||
|
||
1. The value is copied with `value = copy.deepcopy(value)` | ||
2. The code is generated with `repr(value)` (which can be [customized](register_repr.md)) | ||
3. Strings which contain newlines are converted to triple quoted strings. | ||
|
||
!!! note | ||
Missing newlines at start or end are escaped (since 0.4.0). | ||
|
||
=== "original code" | ||
<!-- inline-snapshot: outcome-passed=1 --> | ||
``` python | ||
def test_something(): | ||
assert "first line\nsecond line" == snapshot( | ||
"""first line | ||
second line""" | ||
) | ||
``` | ||
|
||
=== "--inline-snapshot=update" | ||
<!-- inline-snapshot: update outcome-passed=1 --> | ||
``` python | ||
def test_something(): | ||
assert "first line\nsecond line" == snapshot( | ||
"""\ | ||
first line | ||
second line\ | ||
""" | ||
) | ||
``` | ||
|
||
|
||
4. The code is formatted with black. | ||
|
||
|
||
5. The whole file is formatted with black if it was formatted before. | ||
|
||
!!! note | ||
The black formatting of the whole file could not work for the following reasons: | ||
|
||
1. black is configured with cli arguments and not in a configuration file.<br> | ||
**Solution:** configure black in a [configuration file](https://black.readthedocs.io/en/stable/usage_and_configuration/the_basics.html#configuration-via-a-file) | ||
2. inline-snapshot uses a different black version.<br> | ||
**Solution:** specify which black version inline-snapshot should use by adding black with a specific version to your dependencies. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,89 @@ | ||
|
||
|
||
|
||
`repr()` can be used to convert a python object into a source code representation of the object, but this does not work for every type. | ||
Here are some examples: | ||
```pycon | ||
>>> repr(int) | ||
"<class 'int'>" | ||
|
||
>>> from enum import Enum | ||
>>> E = Enum("E", ["a", "b"]) | ||
>>> repr(E.a) | ||
'<E.a: 1>' | ||
``` | ||
|
||
`register_repr` can be used to overwrite the default `repr()` behaviour. | ||
|
||
The implementation for `Enum` looks like this: | ||
|
||
```python exec="1" result="python" | ||
print('--8<-- "inline_snapshot/_code_repr.py:Enum"') | ||
``` | ||
|
||
This implementation is then used by inline-snapshot if `repr()` is called during the code generation, but not in normal code. | ||
|
||
<!-- inline-snapshot: create fix this outcome-passed=1 --> | ||
```python | ||
from enum import Enum | ||
|
||
|
||
def test_enum(): | ||
E = Enum("E", ["a", "b"]) | ||
|
||
assert repr(E.a) == "<E.a: 1>" | ||
assert E.a == snapshot(E.a) | ||
``` | ||
|
||
inline-snapshot comes with a special implementation for the following types: | ||
```python exec="1" | ||
from inline_snapshot._code_repr import code_repr_dispatch, code_repr | ||
|
||
for k in sorted( | ||
f"{k.__module__}.{k.__qualname__}" | ||
for k in code_repr_dispatch.registry.keys() | ||
): | ||
print(f"- `{k}`") | ||
``` | ||
|
||
Container types like `dict` or `dataclass` need a special implementation because it is necessary that the implementation uses `repr()` for the child elements. | ||
|
||
```python exec="1" result="python" | ||
print('--8<-- "inline_snapshot/_code_repr.py:list"') | ||
``` | ||
|
||
!!! note | ||
using `#!python f"{obj!r}"` or `#!c PyObject_Repr()` will not work, because inline-snapshot replaces `#!python builtins.repr` during the code generation. | ||
|
||
You can also use `repr()` inside `__repr__()`, if you want to make your own type compatible with inline-snapshot. | ||
|
||
<!-- inline-snapshot: create fix this outcome-passed=1 --> | ||
```python | ||
from enum import Enum | ||
|
||
|
||
class Pair: | ||
def __init__(self, a, b): | ||
self.a = a | ||
self.b = b | ||
|
||
def __repr__(self): | ||
# this would not work | ||
# return f"Pair({self.a!r}, {self.b!r})" | ||
|
||
# you have to use repr() | ||
return f"Pair({repr(self.a)}, {repr(self.b)})" | ||
|
||
def __eq__(self, other): | ||
if not isinstance(other, Pair): | ||
return NotImplemented | ||
return self.a == other.a and self.b == other.b | ||
|
||
|
||
def test_enum(): | ||
E = Enum("E", ["a", "b"]) | ||
|
||
# the special repr implementation is used recursive here | ||
# to convert every Enum to the correct representation | ||
assert Pair(E.a, [E.b]) == snapshot(Pair(E.a, [E.b])) | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters