Skip to content

Commit

Permalink
feat(tools): add parse_raw_as util (#1813)
Browse files Browse the repository at this point in the history
closes #1812
  • Loading branch information
PrettyWood committed Oct 9, 2020
1 parent 87aeab3 commit 75859a9
Show file tree
Hide file tree
Showing 5 changed files with 35 additions and 6 deletions.
1 change: 1 addition & 0 deletions changes/1812-PrettyWood.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
add `parse_raw_as` utility function
4 changes: 2 additions & 2 deletions docs/usage/models.md
Original file line number Diff line number Diff line change
Expand Up @@ -533,8 +533,8 @@ _(This script is complete, it should run "as is")_

This function is capable of parsing data into any of the types pydantic can handle as fields of a `BaseModel`.

Pydantic also includes a similar standalone function called `parse_file_as`,
which is analogous to `BaseModel.parse_file`.
Pydantic also includes two similar standalone functions called `parse_file_as` and `parse_raw_as`,
which are analogous to `BaseModel.parse_file` and `BaseModel.parse_raw`.

## Data Conversion

Expand Down
1 change: 1 addition & 0 deletions pydantic/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@
# tools
'parse_file_as',
'parse_obj_as',
'parse_raw_as',
# types
'NoneStr',
'NoneBytes',
Expand Down
23 changes: 20 additions & 3 deletions pydantic/tools.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@
from pathlib import Path
from typing import Any, Callable, Optional, Type, TypeVar, Union

from pydantic.parse import Protocol, load_file

from .parse import Protocol, load_file, load_str_bytes
from .types import StrBytes
from .typing import display_as_type

__all__ = ('parse_file_as', 'parse_obj_as')
__all__ = ('parse_file_as', 'parse_obj_as', 'parse_raw_as')

NameFactory = Union[str, Callable[[Type[Any]], str]]

Expand Down Expand Up @@ -55,3 +55,20 @@ def parse_file_as(
json_loads=json_loads,
)
return parse_obj_as(type_, obj, type_name=type_name)


def parse_raw_as(
type_: Type[T],
b: StrBytes,
*,
content_type: str = None,
encoding: str = 'utf8',
proto: Protocol = None,
allow_pickle: bool = False,
json_loads: Callable[[str], Any] = json.loads,
type_name: Optional[NameFactory] = None,
) -> T:
obj = load_str_bytes(
b, proto=proto, content_type=content_type, encoding=encoding, allow_pickle=allow_pickle, json_loads=json_loads,
)
return parse_obj_as(type_, obj, type_name=type_name)
12 changes: 11 additions & 1 deletion tests/test_tools.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

from pydantic import BaseModel, ValidationError
from pydantic.dataclasses import dataclass
from pydantic.tools import parse_file_as, parse_obj_as
from pydantic.tools import parse_file_as, parse_obj_as, parse_raw_as


@pytest.mark.parametrize('obj,type_,parsed', [('1', int, 1), (['1'], List[int], [1])])
Expand Down Expand Up @@ -88,3 +88,13 @@ def custom_json_loads(*args, **kwargs):
p = tmp_path / 'test_json_loads.json'
p.write_text('{"1": "2"}')
assert parse_file_as(Dict[int, int], p, json_loads=custom_json_loads) == {1: 99}


def test_raw_as():
class Item(BaseModel):
id: int
name: str

item_data = '[{"id": 1, "name": "My Item"}]'
items = parse_raw_as(List[Item], item_data)
assert items == [Item(id=1, name='My Item')]

0 comments on commit 75859a9

Please sign in to comment.