Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
Rolf van Kleef
serializer_utils
Commits
6e7391cb
Commit
6e7391cb
authored
Nov 01, 2018
by
Rolf van Kleef
Browse files
Feature completeness
parent
5ec2e899
Changes
3
Expand all
Hide whitespace changes
Inline
Side-by-side
LICENSE.txt
0 → 100644
View file @
6e7391cb
This diff is collapsed.
Click to expand it.
serializer_utils/deserializer.py
View file @
6e7391cb
from
typing
import
Optional
from
typing
import
Optional
,
Union
from
typeguard
import
check_type
...
...
@@ -86,7 +86,7 @@ class Deserializable(metaclass=BaseMeta):
return
fields
def
deserializ
e
(
t
,
d
,
try_all
=
False
):
def
get_
deserializ
ation_class
(
t
,
d
,
try_all
=
False
):
for
sc
in
t
.
__subclasses__
():
if
hasattr
(
sc
,
'_discriminators'
):
for
discriminator
in
sc
.
_discriminators
:
...
...
@@ -94,17 +94,42 @@ def deserialize(t, d, try_all=False):
break
else
:
try
:
return
deserializ
e
(
sc
,
d
)
return
get_
deserializ
ation_class
(
sc
,
t
,
try_all
)
except
TypeError
as
e
:
if
not
try_all
:
raise
e
return
t
if
hasattr
(
t
,
'_abstract'
)
and
t
.
_abstract
:
raise
TypeError
(
'Cannot deserialize into {}: is abstract.'
.
format
(
t
.
__name__
))
instance
=
t
()
for
k
,
rule
in
t
.
get_attrs
().
items
():
v
=
rule
.
validate
(
k
,
d
[
k
]
if
k
in
d
else
None
)
setattr
(
instance
,
k
,
v
)
def
deserialize
(
rule
:
Rule
,
data
,
try_all
=
False
,
key
=
None
):
# In case of primitive types, attempt to assign.
try
:
return
rule
.
validate
(
key
,
data
)
except
TypeError
:
pass
return
instance
if
type
(
rule
.
type
)
is
type
(
Union
):
for
arg
in
rule
.
type
.
__args__
:
try
:
return
deserialize
(
Rule
(
arg
),
data
,
try_all
,
key
)
except
TypeError
:
pass
raise
TypeError
(
'{} did not match any of {}.'
.
format
(
type
(
data
),
rule
.
type
.
__args__
))
if
issubclass
(
rule
.
type
,
Deserializable
):
if
not
isinstance
(
data
,
dict
):
raise
TypeError
(
'Cannot deserialize non-dict into class.'
)
cls
=
get_deserialization_class
(
rule
.
type
,
data
,
try_all
)
if
hasattr
(
cls
,
'_abstract'
)
and
cls
.
_abstract
:
raise
TypeError
(
'Cannot deserialize into {}: is abstract.'
.
format
(
cls
.
__name__
))
instance
=
cls
()
for
k
,
r
in
cls
.
get_attrs
().
items
():
v
=
deserialize
(
r
,
data
[
k
]
if
k
in
data
else
r
.
default
,
try_all
,
key
=
k
)
setattr
(
instance
,
k
,
v
)
return
instance
raise
TypeError
(
'Unable to find a deserialization candidate for {} in {}.'
.
format
(
data
,
rule
))
\ No newline at end of file
test.py
View file @
6e7391cb
from
time
import
sleep
from
typing
import
Optional
from
serializer_utils.deserializer
import
Deserializable
from
serializer_utils.deserializer
import
Deserializable
,
Rule
from
serializer_utils.annotations
import
abstract
,
discriminate
...
...
@@ -32,16 +32,34 @@ class RefundLine(ReceiptLine):
return
'RefundLine(super={})'
.
format
(
super
(
RefundLine
,
self
).
__repr__
())
class
Test
(
Deserializable
):
tf
:
Optional
[
ReceiptLine
]
def
__repr__
(
self
):
return
'Test(tf={})'
.
format
(
self
.
tf
.
__repr__
())
if
__name__
==
'__main__'
:
import
sys
import
traceback
from
serializer_utils.deserializer
import
deserialize
try
:
print
(
deserialize
(
ReceiptLine
,
{
'type'
:
'transaction'
,
'name'
:
'asdf'
,
'article_id'
:
5
,
'amount'
:
5
}))
print
(
deserialize
(
ReceiptLine
,
{
'type'
:
'refund'
,
'name'
:
'asdf'
,
'pk'
:
5
}))
print
(
deserialize
(
ReceiptLine
,
{
'type'
:
'other'
,
'name'
:
'asdf'
}))
except
TypeError
as
err
:
sleep
(
0.05
)
print
(
traceback
.
format_exc
(),
file
=
sys
.
stderr
)
def
print_result
(
function
,
*
args
,
**
kwargs
):
try
:
print
(
function
(
*
args
,
**
kwargs
))
except
:
sleep
(
0.05
)
print
(
traceback
.
format_exc
(),
file
=
sys
.
stderr
)
fns
=
[
[
Rule
(
ReceiptLine
),
{
'type'
:
'transaction'
,
'name'
:
'asdf'
,
'article_id'
:
5
,
'amount'
:
5
}],
[
Rule
(
ReceiptLine
),
{
'type'
:
'refund'
,
'name'
:
'asdf'
,
'pk'
:
5
}],
[
Rule
(
ReceiptLine
),
{
'type'
:
'other'
,
'name'
:
'asdf'
}],
[
Rule
(
ReceiptLine
),
{
'type'
:
'transaction'
}],
[
Rule
(
ReceiptLine
),
{
'type'
:
'transaction'
,
'name'
:
'asdf'
,
'pk'
:
'no'
}],
[
Rule
(
Test
),
{
'tf'
:
{
'type'
:
'refund'
,
'name'
:
'asdf'
,
'pk'
:
5
}}]
]
[
print_result
(
deserialize
,
*
entry
)
for
entry
in
fns
]
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment