Skip to content

Commit

Permalink
Represent int types using numbers.Integral on Py2
Browse files Browse the repository at this point in the history
  • Loading branch information
dahlia committed Mar 11, 2018
1 parent decd61b commit a38c3da
Show file tree
Hide file tree
Showing 4 changed files with 49 additions and 25 deletions.
15 changes: 11 additions & 4 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,14 @@ To be released.
classes. Nirum type names are qualified and their leading module paths
are also normalized (the same rule to `nirum.modules` applies here).

- The `uri` type became represented as [`basestring`][python-basestring]
instead of [`unicode`][python-unicode] in Python 2, since URI (unlike IRI)
- All integral types (`int32`, `int64`, and `bigint`) became represented
as [`numbers.Integral`][python2-numbers-integral] instead of
[`int`][python2-int].

There's no change to Python 3.

- The `uri` type became represented as [`basestring`][python2-basestring]
instead of [`unicode`][python2-unicode] in Python 2, since URI (unlike IRI)
is limited to a subset of ASCII character set.

There's no change to Python 3.
Expand All @@ -46,8 +52,9 @@ To be released.
[#220]: https://github.com/spoqa/nirum/issues/220
[#227]: https://github.com/spoqa/nirum/pull/227
[entry points]: https://setuptools.readthedocs.io/en/latest/pkg_resources.html#entry-points
[python-basestring]: https://docs.python.org/2/library/functions.html#basestring
[python-unicode]: https://docs.python.org/2/library/functions.html#unicode
[python2-numbers-integral]: https://docs.python.org/2/library/numbers.html#numbers.Integral
[python2-basestring]: https://docs.python.org/2/library/functions.html#basestring
[python2-unicode]: https://docs.python.org/2/library/functions.html#unicode


Version 0.3.1
Expand Down
17 changes: 17 additions & 0 deletions src/Nirum/Targets/Python.hs
Original file line number Diff line number Diff line change
Expand Up @@ -776,6 +776,23 @@ class #{className}(object):
field_type = field_types[name]
except KeyError:
continue
if (field_type.__module__ == 'numbers' and
field_type.__name__ == 'Integral'):
# FIXME: deserialize_meta() cannot determine the Nirum type
# from the given Python class, since there are 1:N relationships
# between Nirum types and Python classes. A Python class can
# have more than one corresponds and numbers.Integral is
# the case: bigint, int32, and int64 all corresponds to
# numbers.Integral (on Python 2).
# It's the essential reason why we should be free from
# deserialize_meta() and generate actual deserializer code
# for each field instead.
# See also: https://github.com/spoqa/nirum/issues/160
try:
args[name] = int(item)
except ValueError as e:
errors.add('%s: %s' % (attribute_name, e))
continue
try:
args[name] = deserialize_meta(field_type, item)
except ValueError as e:
Expand Down
12 changes: 6 additions & 6 deletions src/Nirum/Targets/Python/TypeExpression.hs
Original file line number Diff line number Diff line change
Expand Up @@ -56,15 +56,15 @@ compilePrimitiveType primitiveTypeIdentifier' = do
pyVer <- getPythonVersion
case (primitiveTypeIdentifier', pyVer) of
(Bool, _) -> builtins "bool"
(Bigint, _) -> builtins "int"
(Bigint, Python2) -> do
numbers <- importStandardLibrary "numbers"
return [qq|$numbers.Integral|]
(Bigint, Python3) -> builtins "int"
(Decimal, _) -> do
decimal <- importStandardLibrary "decimal"
return [qq|$decimal.Decimal|]
(Int32, _) -> builtins "int"
(Int64, Python2) -> do
numbers <- importStandardLibrary "numbers"
return [qq|$numbers.Integral|]
(Int64, Python3) -> builtins "int"
(Int32, _) -> compilePrimitiveType Bigint
(Int64, _) -> compilePrimitiveType Bigint
(Float32, _) -> builtins "float"
(Float64, _) -> builtins "float"
(Text, Python2) -> builtins "unicode"
Expand Down
30 changes: 15 additions & 15 deletions test/Nirum/Targets/Python/TypeExpressionSpec.hs
Original file line number Diff line number Diff line change
Expand Up @@ -29,17 +29,17 @@ spec = pythonVersionSpecs $ \ ver -> do

specify [qq|compilePrimitiveType ($ver)|] $ do
let (boolCode, boolContext) = run' $ compilePrimitiveType Bool
let intTypeCode = case ver of
Python2 -> "_numbers.Integral"
Python3 -> "__builtin__.int"
boolCode `shouldBe` Right "__builtin__.bool"
standardImports boolContext `shouldBe` [builtinsPair]
code (compilePrimitiveType Bigint) `shouldBe` "__builtin__.int"
code (compilePrimitiveType Bigint) `shouldBe` intTypeCode
let (decimalCode, decimalContext) = run' (compilePrimitiveType Decimal)
decimalCode `shouldBe` Right "_decimal.Decimal"
standardImports decimalContext `shouldBe` [("_decimal", "decimal")]
code (compilePrimitiveType Int32) `shouldBe` "__builtin__.int"
code (compilePrimitiveType Int64) `shouldBe`
case ver of
Python2 -> "_numbers.Integral"
Python3 -> "__builtin__.int"
code (compilePrimitiveType Int32) `shouldBe` intTypeCode
code (compilePrimitiveType Int64) `shouldBe` intTypeCode
code (compilePrimitiveType Float32) `shouldBe` "__builtin__.float"
code (compilePrimitiveType Float64) `shouldBe` "__builtin__.float"
code (compilePrimitiveType Text) `shouldBe`
Expand All @@ -66,10 +66,10 @@ spec = pythonVersionSpecs $ \ ver -> do
let Source { sourceModule = bm } = makeDummySource $ Module [] Nothing
specify "TypeIdentifier" $ do
let (c, ctx) = run' $
compileTypeExpression bm (Just $ TypeIdentifier "bigint")
compileTypeExpression bm (Just $ TypeIdentifier "binary")
standardImports ctx `shouldBe` [builtinsPair]
localImports ctx `shouldBe` []
c `shouldBe` Right "__builtin__.int"
c `shouldBe` Right "__builtin__.bytes"
specify "OptionModifier" $ do
let (c', ctx') = run' $
compileTypeExpression bm (Just $ OptionModifier "binary")
Expand All @@ -79,23 +79,23 @@ spec = pythonVersionSpecs $ \ ver -> do
c' `shouldBe` Right "_typing.Optional[__builtin__.bytes]"
specify "SetModifier" $ do
let (c'', ctx'') = run' $
compileTypeExpression bm (Just $ SetModifier "int32")
compileTypeExpression bm (Just $ SetModifier "float32")
standardImports ctx'' `shouldBe`
[builtinsPair, ("_typing", "typing")]
localImports ctx'' `shouldBe` []
c'' `shouldBe` Right "_typing.AbstractSet[__builtin__.int]"
c'' `shouldBe` Right "_typing.AbstractSet[__builtin__.float]"
specify "ListModifier" $ do
let (c''', ctx''') = run' $
compileTypeExpression bm (Just $ ListModifier "int32")
compileTypeExpression bm (Just $ ListModifier "float64")
standardImports ctx''' `shouldBe`
[builtinsPair, ("_typing", "typing")]
localImports ctx''' `shouldBe` []
c''' `shouldBe` Right "_typing.Sequence[__builtin__.int]"
c''' `shouldBe` Right "_typing.Sequence[__builtin__.float]"
specify "MapModifier" $ do
let (c'''', ctx'''') = run' $
compileTypeExpression bm (Just $ MapModifier "uuid" "int32")
let (c'''', ctx'''') = run' $ compileTypeExpression bm $
Just $ MapModifier "uuid" "binary"
standardImports ctx'''' `shouldBe`
[builtinsPair, ("_typing", "typing"), ("_uuid", "uuid")]
localImports ctx'''' `shouldBe` []
c'''' `shouldBe`
Right "_typing.Mapping[_uuid.UUID, __builtin__.int]"
Right "_typing.Mapping[_uuid.UUID, __builtin__.bytes]"

0 comments on commit a38c3da

Please sign in to comment.