Repository: samuelcolvin/pydantic
Pull request #3555 (2021-12-20 21:01:30)

build(deps): bump mkdocs-material from 8.1.1 to 8.1.3
Bumps [mkdocs-material](https://github.com/squidfunk/mkdocs-material) from 8.1.1 to 8.1.3.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a href="https://github.com/squidfunk/mkdocs-material/releases">mkdocs-material's releases</a>.</em></p>
<blockquote>
<h2>mkdocs-material-8.1.3</h2>
<ul>
<li>Added animation to active content tab indicator</li>
<li>Fixed <a href="https://github-redirect.dependabot.com/squidfunk/mkdocs-material/issues/3360">#3360</a>: Highlighted lines add blank lines in copied text</li>
<li>Fixed usage of subsequent index files when using section index pages</li>
</ul>
<h2>mkdocs-material-8.1.2</h2>
<ul>
<li>Switched CSS sources to logical properties</li>
<li>Added transformation of logical properties to <code>ltr</code>/<code>rtl</code> equivalents</li>
<li>Fixed spacing for admonitions inside lists (8.1.1 regression)</li>
</ul>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a href="https://github.com/squidfunk/mkdocs-material/blob/master/CHANGELOG">mkdocs-material's changelog</a>.</em></p>
<blockquote>
<p>mkdocs-material-8.1.3 (2012-12-19)</p>
<ul>
<li>Added animation to active content tab indicator</li>
<li>Fixed <a href="https://github-redirect.dependabot.com/squidfunk/mkdocs-material/issues/3360">#3360</a>: Highlighted lines add blank lines in copied text</li>
<li>Fixed usage of subsequent index files when using section index pages</li>
</ul>
<p>mkdocs-material-8.1.2+insiders-4.5.0 (2021-12-16)</p>
<ul>
<li>Added support for navigation icons</li>
</ul>
<p>mkdocs-material-8.1.2 (2012-12-15)</p>
<ul>
<li>Switched CSS sources to logical properties</li>
<li>Added transformation of logical properties to ltr/rtl equivalents</li>
<li>Fixed spacing for admonitions inside lists (8.1.1 regression)</li>
</ul>
<p>mkdocs-material-8.1.1 (2012-12-13)</p>
<ul>
<li>Added support for #only-light and #only-dark image hash fragments</li>
<li>Fixed copy-to-clipboard adding blank lines when using line anchors</li>
<li>Fixed code annotation directionality for right-to-left languages</li>
<li>Fixed header title positioning for right-to-left languages</li>
<li>Fixed admonition borders for right-to-left languages (8.0.0 regression)</li>
<li>Fixed footer navigation link positioning (8.0.0 regression)</li>
<li>Fixed footer navigation title breaking out of container when too long</li>
<li>Fixed shrinking arrow in navigation title when too long</li>
<li>Fixed <a href="https://github-redirect.dependabot.com/squidfunk/mkdocs-material/issues/3343">#3343</a>: Filtered stopwords appear as missing search terms</li>
<li>Fixed <a href="https://github-redirect.dependabot.com/squidfunk/mkdocs-material/issues/3346">#3346</a>: Site unusable due to usage of :not() (Firefox 78 ESR)</li>
</ul>
<p>mkdocs-material-8.1.0+insiders-4.4.0 (2021-12-10)</p>
<ul>
<li>Added support for code annotation anchor links (deep linking)</li>
<li>Added new code annotation syntax modifier to strip comment</li>
<li>Updated German translations for cookie consent</li>
</ul>
<p>mkdocs-material-8.1.0 (2012-12-10)</p>
<ul>
<li>Added basic support for code block line anchors</li>
<li>Switched code annotation markers to + signs to improve usability</li>
<li>Switched main site title to bold font</li>
<li>Improved admonition icon positioning to align when font-size is increased</li>
<li>Improved and simplified footnotes CSS</li>
<li>Improved and simplified code annotation positioning</li>
<li>Fixed syntax error in Russian translations</li>
</ul>
<p>mkdocs-material-8.0.5 (2012-12-04)</p>
<ul>
<li>Fixed <a href="https://github-redirect.dependabot.com/squidfunk/mkdocs-material/issues/3302">#3302</a>: Footer refactoring induced ellipsis in some browsers</li>
<li>Fixed <a href="https://github-redirect.dependabot.com/squidfunk/mkdocs-material/issues/3313">#3313</a>: Details always rendered closed on load (8.0.4 regression)</li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a href="https://github.com/squidfunk/mkdocs-material/commit/a3590cb9301f128eb862a5088ee481fe28a2bbda"><code>a3590cb</code></a> Prepare 8.1.3 release</li>
<li><a href="https://github.com/squidfunk/mkdocs-material/commit/a7ab13fe980d660bd79bd3f4ed49cba24327cba4"><code>a7ab13f</code></a> Fixed linter errors</li>
<li><a href="https://github.com/squidfunk/mkdocs-material/commit/be0a36d1b023359582c2db8834b2aa8e3fd99e58"><code>be0a36d</code></a> Fixed highlighted lines adding blank lines when copying</li>
<li><a href="https://github.com/squidfunk/mkdocs-material/commit/368cad0955d92a98deae021e0d5831d6c310b3cc"><code>368cad0</code></a> Documentation</li>
<li><a href="https://github.com/squidfunk/mkdocs-material/commit/1f725cb38808ebba25bea4427415f1ed302af798"><code>1f725cb</code></a> Simplified reduced motion implementation for content tabs</li>
<li><a href="https://github.com/squidfunk/mkdocs-material/commit/f3926bf444a29310be0d14b1311b3dd832b1c310"><code>f3926bf</code></a> Fixed filtering of subsequent index.md files when using section index pages</li>
<li><a href="https://github.com/squidfunk/mkdocs-material/commit/a32760bdee651c4865e61102076fca9fe742ced3"><code>a32760b</code></a> Fixed tab indicator animation for right-to-left languages</li>
<li><a href="https://github.com/squidfunk/mkdocs-material/commit/4b2a97a51d3191ae3b93048ac46fefe97e3c535f"><code>4b2a97a</code></a> Added animation to content tabs</li>
<li><a href="https://github.com/squidfunk/mkdocs-material/commit/dffcba47fb006783ea2cf322c1ca65eed02e2c3d"><code>dffcba4</code></a> Updated Piri Piri funding goal</li>
<li><a href="https://github.com/squidfunk/mkdocs-material/commit/8787449ddd31abfd35402ef695f02e3ed61a59a7"><code>8787449</code></a> Switched :where back to :is</li>
<li>Additional commits viewable in <a href="https://github.com/squidfunk/mkdocs-material/compare/8.1.1...8.1.3">compare view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=mkdocs-material&package-manager=pip&previous-version=8.1.1&new-version=8.1.3)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
- `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)


</details>


Patch:
diff --git a/docs/examples/schema_ad_hoc.py b/docs/examples/schema_ad_hoc.py
index 6e93f913d..10862e162 100644
--- a/docs/examples/schema_ad_hoc.py
+++ b/docs/examples/schema_ad_hoc.py
@@ -2,7 +2,7 @@ from typing import Literal, Union
 
 from typing_extensions import Annotated
 
-from pydantic import BaseModel, Field, schema_json
+from pydantic import BaseModel, Field, schema_json_of
 
 
 class Cat(BaseModel):
@@ -17,4 +17,4 @@ class Dog(BaseModel):
 
 Pet = Annotated[Union[Cat, Dog], Field(discriminator='pet_type')]
 
-print(schema_json(Pet, title='The Pet Schema', indent=2))
+print(schema_json_of(Pet, title='The Pet Schema', indent=2))
diff --git a/docs/requirements.txt b/docs/requirements.txt
index 2bc1b7dc1..0b935ad26 100644
--- a/docs/requirements.txt
+++ b/docs/requirements.txt
@@ -6,7 +6,7 @@ markdown-include==0.6.0
 mdx-truly-sane-lists==1.2
 mkdocs==1.2.3
 mkdocs-exclude==1.0.2
-mkdocs-material==8.1.1
+mkdocs-material==8.1.3
 sqlalchemy
 orjson
 ujson
diff --git a/docs/usage/schema.md b/docs/usage/schema.md
index 9928b2782..458014a41 100644
--- a/docs/usage/schema.md
+++ b/docs/usage/schema.md
@@ -39,7 +39,7 @@ will be replaced with the model naming using `str.format()`.
 
 ## Getting schema of a specified type
 
-_Pydantic_ includes two standalone utility functions `schema` and `schema_json` that can be used to
+_Pydantic_ includes two standalone utility functions `schema_of` and `schema_json_of` that can be used to
 apply the schema generation logic used for _pydantic_ models in a more ad-hoc way.
 These functions behave similarly to `BaseModel.schema` and `BaseModel.schema_json`,
 but work with arbitrary pydantic-compatible types.
diff --git a/pydantic/__init__.py b/pydantic/__init__.py
index 0443acef6..982ea4755 100644
--- a/pydantic/__init__.py
+++ b/pydantic/__init__.py
@@ -67,8 +67,8 @@ __all__ = [
     'parse_file_as',
     'parse_obj_as',
     'parse_raw_as',
-    'schema',
-    'schema_json',
+    'schema_of',
+    'schema_json_of',
     # types
     'NoneStr',
     'NoneBytes',
diff --git a/pydantic/fields.py b/pydantic/fields.py
index ff7b962f7..44a3aa10b 100644
--- a/pydantic/fields.py
+++ b/pydantic/fields.py
@@ -50,6 +50,7 @@ from .utils import (
     ValueItems,
     get_discriminator_alias_and_values,
     get_unique_discriminator_alias,
+    lenient_isinstance,
     lenient_issubclass,
     sequence_like,
     smart_deepcopy,
@@ -1048,7 +1049,7 @@ class ModelField(Representation):
                             return v, None
                     except TypeError:
                         # compound type
-                        if isinstance(v, get_origin(field.outer_type_)):
+                        if lenient_isinstance(v, get_origin(field.outer_type_)):
                             value, error = field.validate(v, values, loc=loc, cls=cls)
                             if not error:
                                 return value, None
diff --git a/pydantic/tools.py b/pydantic/tools.py
index f1d651cd4..9cdb4538e 100644
--- a/pydantic/tools.py
+++ b/pydantic/tools.py
@@ -7,7 +7,7 @@ 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', 'parse_raw_as', 'schema', 'schema_json')
+__all__ = ('parse_file_as', 'parse_obj_as', 'parse_raw_as', 'schema_of', 'schema_json_of')
 
 NameFactory = Union[str, Callable[[Type[Any]], str]]
 
@@ -82,11 +82,11 @@ def parse_raw_as(
     return parse_obj_as(type_, obj, type_name=type_name)
 
 
-def schema(type_: Any, *, title: Optional[NameFactory] = None, **schema_kwargs: Any) -> 'DictStrAny':
+def schema_of(type_: Any, *, title: Optional[NameFactory] = None, **schema_kwargs: Any) -> 'DictStrAny':
     """Generate a JSON schema (as dict) for the passed model or dynamically generated one"""
     return _get_parsing_type(type_, type_name=title).schema(**schema_kwargs)
 
 
-def schema_json(type_: Any, *, title: Optional[NameFactory] = None, **schema_json_kwargs: Any) -> str:
+def schema_json_of(type_: Any, *, title: Optional[NameFactory] = None, **schema_json_kwargs: Any) -> str:
     """Generate a JSON schema (as JSON) for the passed model or dynamically generated one"""
     return _get_parsing_type(type_, type_name=title).schema_json(**schema_json_kwargs)
diff --git a/pydantic/utils.py b/pydantic/utils.py
index ec94f76c7..d4ca69395 100644
--- a/pydantic/utils.py
+++ b/pydantic/utils.py
@@ -53,6 +53,7 @@ __all__ = (
     'import_string',
     'sequence_like',
     'validate_field_name',
+    'lenient_isinstance',
     'lenient_issubclass',
     'in_ipython',
     'deep_update',
@@ -163,6 +164,13 @@ def validate_field_name(bases: List[Type['BaseModel']], field_name: str) -> None
             )
 
 
+def lenient_isinstance(o: Any, class_or_tuple: Union[Type[Any], Tuple[Type[Any], ...]]) -> bool:
+    try:
+        return isinstance(o, class_or_tuple)
+    except TypeError:
+        return False
+
+
 def lenient_issubclass(cls: Any, class_or_tuple: Union[Type[Any], Tuple[Type[Any], ...]]) -> bool:
     try:
         return isinstance(cls, type) and issubclass(cls, class_or_tuple)


Test patch:
diff --git a/tests/test_tools.py b/tests/test_tools.py
index 97784d552..689b32d4c 100644
--- a/tests/test_tools.py
+++ b/tests/test_tools.py
@@ -5,7 +5,7 @@ import pytest
 
 from pydantic import BaseModel, ValidationError
 from pydantic.dataclasses import dataclass
-from pydantic.tools import parse_file_as, parse_obj_as, parse_raw_as, schema, schema_json
+from pydantic.tools import parse_file_as, parse_obj_as, parse_raw_as, schema_json_of, schema_of
 
 
 @pytest.mark.parametrize('obj,type_,parsed', [('1', int, 1), (['1'], List[int], [1])])
@@ -101,11 +101,11 @@ def test_raw_as():
 
 
 def test_schema():
-    assert schema(Union[int, str], title='IntOrStr') == {
+    assert schema_of(Union[int, str], title='IntOrStr') == {
         'title': 'IntOrStr',
         'anyOf': [{'type': 'integer'}, {'type': 'string'}],
     }
-    assert schema_json(Union[int, str], title='IntOrStr', indent=2) == (
+    assert schema_json_of(Union[int, str], title='IntOrStr', indent=2) == (
         '{\n'
         '  "title": "IntOrStr",\n'
         '  "anyOf": [\n'
diff --git a/tests/test_types.py b/tests/test_types.py
index 2a3161316..bbf4c23b1 100644
--- a/tests/test_types.py
+++ b/tests/test_types.py
@@ -27,7 +27,7 @@ from typing import (
 from uuid import UUID
 
 import pytest
-from typing_extensions import Literal
+from typing_extensions import Literal, TypedDict
 
 from pydantic import (
     UUID1,
@@ -3120,6 +3120,22 @@ def test_smart_union_compouned_types_edge_case():
     assert Model(x=[1, '2']).x == ['1', '2']
 
 
+def test_smart_union_typeddict():
+    class Dict1(TypedDict):
+        foo: str
+
+    class Dict2(TypedDict):
+        bar: str
+
+    class M(BaseModel):
+        d: Union[Dict2, Dict1]
+
+        class Config:
+            smart_union = True
+
+    assert M(d=dict(foo='baz')).d == {'foo': 'baz'}
+
+
 @pytest.mark.parametrize(
     'value,result',
     (