Skip to content

Commit

Permalink
Release 3.11.1.1
Browse files Browse the repository at this point in the history
  • Loading branch information
avanov committed Oct 27, 2023
1 parent d8f92a8 commit 6819bef
Show file tree
Hide file tree
Showing 7 changed files with 37 additions and 6 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@
CHANGELOG
=========

3.11.1.1
========

* Fixed bug in Union of literals serialisation.


3.11.0.0
========

Expand Down
1 change: 1 addition & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ update:
python -m pip install -r $(PROJECT_ROOT)/requirements/minimal.txt
python -m pip install -r $(PROJECT_ROOT)/requirements/test.txt
python -m pip install -r $(PROJECT_ROOT)/requirements/extras/third_party.txt
python -m pip install -e $(PROJECT_ROOT)

test:
python -m pytest -s $(PROJECT_ROOT)/tests/
Expand Down
6 changes: 3 additions & 3 deletions docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,17 +43,17 @@

# General information about the project.
project = 'typeit'
copyright = '2019, Maxim Avanov'
copyright = '2023, Maxim Avanov'
author = 'Maxim Avanov'

# The version info for the project you're documenting, acts as replacement for
# |version| and |release|, also used in various other places throughout the
# built documents.
#
# The short X.Y version.
version = '3.9'
version = '3.11'
# The full version, including alpha/beta/rc tags.
release = '3.9.1.9'
release = '3.11.1.1'

# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ def requirements(at_path: Path):
# ----------------------------

setup(name='typeit',
version='3.11.0.1',
version='3.11.1.1',
description='typeit brings typed data into your project',
long_description=README,
classifiers=[
Expand Down
2 changes: 1 addition & 1 deletion tests/std_types/test_typing.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import collections
from enum import Enum
from typing import Mapping, Any, Union, Optional, Sequence, Dict, Type
from typing import Mapping, Any, Optional, Sequence, Dict, Type
from typing import NamedTuple

from pyrsistent.typing import PMap
Expand Down
14 changes: 13 additions & 1 deletion tests/unions/test_unions.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import json
from typing import NamedTuple, Union, Any, Dict, Optional, Mapping
from typing import NamedTuple, Union, Any, Dict, Optional, Mapping, Literal

import pytest
from inflection import camelize
Expand Down Expand Up @@ -120,6 +120,18 @@ class X(NamedTuple):
serialize_x(X(x="5"))


def test_union_literals():
Filter = Literal['All'] | Literal['all'] | None

class X(NamedTuple):
x: Filter

mk_x, serialize_x = typeit.TypeConstructor ^ X

x = X(x='all')
serialize_x(x)


# def test_nested_unions_openapi():
# overrides = {
# OperationParameter.in_: 'in',
Expand Down
12 changes: 12 additions & 0 deletions typeit/schema/types.py
Original file line number Diff line number Diff line change
Expand Up @@ -301,6 +301,13 @@ def __init__(
self.variant_schema_types: t.Set[meta.SchemaType] = {
x.typ for _, x in variant_nodes
}
# The literals collections are needed for a corner case where the union is constructed out of
# literal variants, each of which should be able to serialise into primitive values directly without further check.
# That is, if ``appstruct`` is a primitive type, and if the union has literal values and those values match the
# ``appstruct``, then appstruct is already in a proper serialised form.
self.variant_schema_literals: t.FrozenSet[t.Any] = frozenset().union(
*[x.variants for x in self.variant_schema_types if isinstance(x, Literal)]
)

def __repr__(self) -> str:
return f'Optional({self.variant_schema_types})' if len(self.variant_schema_types) == 1 else f'Union({self.variant_schema_types})'
Expand Down Expand Up @@ -358,6 +365,11 @@ def serialize(self, node, appstruct: t.Any):
struct_type = type(appstruct)

prim_schema_type = self.primitive_types.get(struct_type)

# special case for unions consisting of literals among other things
if prim_schema_type and appstruct in self.variant_schema_literals:
return appstruct

if prim_schema_type in self.variant_schema_types:
try:
return prim_schema_type.serialize(node, appstruct)
Expand Down

0 comments on commit 6819bef

Please sign in to comment.