Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add parse_as_type function #934

Merged
merged 12 commits into from Nov 25, 2019
Merged

Conversation

dmontagu
Copy link
Collaborator

@dmontagu dmontagu commented Oct 25, 2019

Change Summary

Adds just the parse_as_type function from #812, along with some documentation.

The documentation may need some work; @samuelcolvin if you give me some direction on what you'd like I'd be happy to modify it. I also think it may make sense to flesh it out a little more
and/or place it on a separate "tools" page once the dump_as_type functionality is implemented.

Related issue number

Addresses minor parts of #811, but to close that issue the dump_as_type functionality will be more important.

Given the lengthy back and forth on #812 I figured it might make more sense to just start fresh and break the pull request into smaller chunks.

Checklist

  • Unit tests for the changes exist
  • Tests pass on CI and coverage remains at 100%
  • Documentation reflects the changes where applicable
  • changes/<pull request or issue id>-<github username>.md file added describing change
    (see changes/README.md for details)

@codecov
Copy link

codecov bot commented Oct 25, 2019

Codecov Report

Merging #934 into master will not change coverage.
The diff coverage is 100%.

@@          Coverage Diff          @@
##           master   #934   +/-   ##
=====================================
  Coverage     100%   100%           
=====================================
  Files          19     20    +1     
  Lines        3293   3317   +24     
  Branches      651    653    +2     
=====================================
+ Hits         3293   3317   +24
Impacted Files Coverage Δ
pydantic/tools.py 100% <100%> (ø)

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 62bc930...315395b. Read the comment docs.

@aldanor
Copy link

aldanor commented Oct 27, 2019

This doesn't seem to work with dataclasses, is it supposed to?

@dmontagu
Copy link
Collaborator Author

dmontagu commented Oct 27, 2019

It should work if and only if you could put dataclasses as fields on a pydantic model.

I don't know whether @samuelcolvin would want to support that or not.

docs/usage/types.md Outdated Show resolved Hide resolved
pydantic/tools.py Outdated Show resolved Hide resolved
pydantic/tools.py Outdated Show resolved Hide resolved
pydantic/tools.py Outdated Show resolved Hide resolved
docs/usage/types.md Outdated Show resolved Hide resolved
pydantic/tools.py Outdated Show resolved Hide resolved
pydantic/tools.py Outdated Show resolved Hide resolved
from pydantic.main import create_model

type_name = getattr(type_, '__name__', str(type_))
return create_model(f'ParsingModel[{type_name}] (for {source})', obj=(type_, ...))
Copy link
Collaborator

@samuelcolvin samuelcolvin Nov 1, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not not sure about obj I think it could be confusing, I think we should use custom root types, e.g. __root__.

That might involve fixing #908 but I think that's a good idea anyway.

@ahirner
Copy link
Contributor

ahirner commented Nov 11, 2019

Is this a partial solution for #481 and what is missing?

@dmontagu
Copy link
Collaborator Author

dmontagu commented Nov 11, 2019

Is this a partial solution for #481 and what is missing?

This is orthogonal to the points raised in that issue, but I think it would be nice if it could support pydantic dataclasses too. I'm not sure how I'd make that happen though. I think if you added the functionality discussed in that issue, it would probably make it easier to have the parse_as_type function handle pydantic dataclasses.

Edit: Actually, it's not quite orthogonal, but it goes beyond what is discussed in that issue -- it supports parsing any type parseable by pydantic, not just models / dataclasses.

@ahirner
Copy link
Contributor

ahirner commented Nov 11, 2019

i like the tests, especially test_parse_as_type_preserves_subclasses and think it would be no problem to add functionality to achieve the same with dataclasses.
so correct me if I'm wrong: parse_as_type(obj, dataclass_or_model_type) == parse_obj(dataclass_or_model_type, obj) ?

edit: clarified input to mean types

@dmontagu
Copy link
Collaborator Author

dmontagu commented Nov 11, 2019

so correct me if I'm wrong: parse_as_type(obj, dataclass_or_model_type) == parse_obj(dataclass_or_model_type, obj) ?

Yeah, I ordered arguments based on what seemed intuitive to me from the function name parse_as_type -> parse obj as type type_), but I am happy to reverse if preferable. The other order would be more consistent with typing.cast, so maybe that's better.

@dmontagu
Copy link
Collaborator Author

dmontagu commented Nov 11, 2019

Just waiting on #958 to replace obj with __root__.

pydantic/tools.py Outdated Show resolved Hide resolved
@dmontagu
Copy link
Collaborator Author

dmontagu commented Nov 11, 2019

@ahirner Actually, to my surprise, it looks like this works out of the box with dataclasses. (I added a test.)

This will also handle the parse_file function.

I might hold off on implementing the to_json() function because we'll want to add dump_as_type from #811, and that may affect the best way to implement the to_json function. On the other hand, there should be a to_json function that doesn't depend on the type you are dumping, so maybe it's fine to add now.

pydantic/tools.py Outdated Show resolved Hide resolved
Copy link
Collaborator

@samuelcolvin samuelcolvin left a comment

otherwise looks good.

pydantic/tools.py Outdated Show resolved Hide resolved
pydantic/tools.py Outdated Show resolved Hide resolved
tests/test_tools.py Outdated Show resolved Hide resolved
pydantic/tools.py Show resolved Hide resolved
Copy link
Collaborator

@samuelcolvin samuelcolvin left a comment

otherwise LGTM.

pydantic/tools.py Show resolved Hide resolved
tests/test_tools.py Outdated Show resolved Hide resolved
@samuelcolvin
Copy link
Collaborator

samuelcolvin commented Nov 25, 2019

I'm still not sure about parse_obj as a name, I understand why you chose it but:

  1. It's not really that similar to BaseModel.parse_obj()
  2. If you're new to pydantic it's less understandable than parse_as_typeor whatever

I guess I'd prefer parse_as_type() and parse_file_as_type(). (Or maybe better parse_object_as() and parse_file_as()). Thoughts?

@dmontagu
Copy link
Collaborator Author

dmontagu commented Nov 25, 2019

I'm fine with that; it seemed similar to me since it is basically like the unbound version of the BaseModel.parse_obj classmethod (that doesn't need to have a BaseModel passed as the first argument). But I have no qualms with using different names.

I'd be in favor of parse_object_as and parse_file_as. I can change it to that if you confirm that's what you want. (If you want to think about it a little longer that's fine too.)

@samuelcolvin
Copy link
Collaborator

samuelcolvin commented Nov 25, 2019

Sorry to be indecisive. Let's go with parse_object_as and parse_file_as.

@dmontagu
Copy link
Collaborator Author

dmontagu commented Nov 25, 2019

@samuelcolvin I did the renames and added some docs; assuming you have no issues with the docs, I think this is just waiting now on changing obj to __root__, which requires #958.

(To be clear, I'm fine with this whether we use __root__ or obj though; I don't know if there is a performance implication to using a custom root model for this, but I'm guessing not?.)

@samuelcolvin samuelcolvin merged commit 6564bbb into pydantic:master Nov 25, 2019
11 checks passed
Bobronium pushed a commit to Bobronium/pydantic that referenced this issue Nov 28, 2019
* Add parse_as_type function

* Add changes

* Incorporate feedback

* Add naming tests

* Fix double quotes

* Fix docs example

* Reorder parameters; add dataclass and mapping tests

* Rename parse_as_type to parse_obj, and add parse_file

* Incorporate feedback

* Incorporate feedback

* use custom root types
andreshndz pushed a commit to cuenca-mx/pydantic that referenced this issue Jan 17, 2020
* Add parse_as_type function

* Add changes

* Incorporate feedback

* Add naming tests

* Fix double quotes

* Fix docs example

* Reorder parameters; add dataclass and mapping tests

* Rename parse_as_type to parse_obj, and add parse_file

* Incorporate feedback

* Incorporate feedback

* use custom root types
samuelcolvin added a commit that referenced this issue Feb 27, 2020
* Refactor ._iter() method:
Moved all keys-related stuff (include, exclude, etc.) to ._iter()
Removed redundant iteration through default values
Almost all arguments checks moved out of loops, so checks happen once
Fast yield from .__dict__ on plain .iter() (x10 boost)
Removed redundant set(dict.keys()) in ._calculate_keys()

* Moved back from nested generator checks to checks, optimized copy a bit

* Bump pytest-mock from 1.12.0 to 1.12.1 (#1018)

Bumps [pytest-mock](https://github.com/pytest-dev/pytest-mock) from 1.12.0 to 1.12.1.
- [Release notes](https://github.com/pytest-dev/pytest-mock/releases)
- [Changelog](https://github.com/pytest-dev/pytest-mock/blob/master/CHANGELOG.rst)
- [Commits](pytest-dev/pytest-mock@v1.12.0...v1.12.1)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

* __str__ and __repr__ inheritance for models, fix #1022 (#1023)

* add testimonials section to docs with reference to python bytes podcast episode (#1025)

* add testimonials section with reference to python bytes podcast episode

* added description to changes directory

* Bump twine from 3.0.0 to 3.1.0 (#1029)

Bumps [twine](https://github.com/pypa/twine) from 3.0.0 to 3.1.0.
- [Release notes](https://github.com/pypa/twine/releases)
- [Changelog](https://github.com/pypa/twine/blob/master/docs/changelog.rst)
- [Commits](pypa/twine@3.0.0...3.1.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

* Support typing.Literal in python 3.8 (#1027)

* Support typing.Literal in python 3.8

* Improve import pattern for Literal

* Update references to  in docs

* Try to get build to pass

* Add support for mapping types as custom root (#958)

* Add support for mapping types as custom root

* Incorporate feedback

* Add changes

* Incorporate feedback

* Add docs and tests

* Fix linting issue

* Incorporate more feedback

* Add more specific match

* Add parse_as_type function (#934)

* Add parse_as_type function

* Add changes

* Incorporate feedback

* Add naming tests

* Fix double quotes

* Fix docs example

* Reorder parameters; add dataclass and mapping tests

* Rename parse_as_type to parse_obj, and add parse_file

* Incorporate feedback

* Incorporate feedback

* use custom root types

* Add better support for validator reuse (#941)

* Add better support for validator reuse

* Clean up classmethod unpacking

* Add changes

* Fix coverage check

* Make 3.8 compatible

* Update changes/940-dmontagu.md

Co-Authored-By: Samuel Colvin <s@muelcolvin.com>

* Make allow_reuse discoverable by adding to error message

* switch _check_validator_name to _prepare_validator

* Add changes file

* Delete unrelated files

* Add check that k in fields before using alias

Co-Authored-By: Samuel Colvin <samcolvin@gmail.com>

* Remove redundant call to __iter__

Co-Authored-By: Samuel Colvin <samcolvin@gmail.com>

* Use typing.AbstractSet

* Update pydantic/main.py

Co-Authored-By: Samuel Colvin <samcolvin@gmail.com>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
Co-authored-by: Samuel Colvin <samcolvin@gmail.com>
Co-authored-by: Colin Sullivan <csullivan@brandwatch.com>
Co-authored-by: David Montague <35119617+dmontagu@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants