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

Fix missing import typing on Python 2 #117

Merged
merged 3 commits into from
Mar 14, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 12 additions & 12 deletions src/Nirum/Targets/Python.hs
Original file line number Diff line number Diff line change
Expand Up @@ -181,8 +181,9 @@ insertLocalImport module' object = ST.modify insert'
insert' c@CodeGenContext { localImports = li } =
c { localImports = M.insertWith S.union module' [object] li }

insertTypingImport :: CodeGen ()
insertTypingImport = do

importTypingForPython3 :: CodeGen ()
importTypingForPython3 = do
pyVer <- getPythonVersion
case pyVer of
Python2 -> return ()
Expand Down Expand Up @@ -261,11 +262,12 @@ quote s = [qq|'{s}'|]

typeReprCompiler :: CodeGen (Code -> Code)
typeReprCompiler = do
insertTypingImport
ver <- getPythonVersion
return $ case ver of
Python2 -> \ t -> [qq|($t.__module__ + '.' + $t.__name__)|]
Python3 -> \ t -> [qq|typing._type_repr($t)|]
case ver of
Python2 -> return $ \ t -> [qq|($t.__module__ + '.' + $t.__name__)|]
Python3 -> do
insertStandardImport "typing"
return $ \ t -> [qq|typing._type_repr($t)|]

type ParameterName = Code
type ParameterType = Code
Expand Down Expand Up @@ -315,7 +317,6 @@ compileUnionTag source parentname typename' fields = do
(map fieldName $ toList fields)
",\n "
parentClass = toClassName' parentname
insertTypingImport
insertThirdPartyImports [ ("nirum.validate", ["validate_union_type"])
, ("nirum.constructs", ["name_dict_type"])
]
Expand Down Expand Up @@ -401,11 +402,11 @@ compileTypeExpression Source { sourceModule = boundModule } (TypeIdentifier i) =
compileTypeExpression source (MapModifier k v) = do
kExpr <- compileTypeExpression source k
vExpr <- compileTypeExpression source v
insertTypingImport
insertStandardImport "typing"
return [qq|typing.Mapping[$kExpr, $vExpr]|]
compileTypeExpression source modifier = do
expr <- compileTypeExpression source typeExpr
insertTypingImport
insertStandardImport "typing"
return [qq|typing.$className[$expr]|]
where
typeExpr :: TypeExpression
Expand All @@ -431,7 +432,6 @@ compileTypeDeclaration src TypeDeclaration { typename = typename'
, type' = UnboxedType itype } = do
let className = toClassName' typename'
itypeExpr <- compileTypeExpression src itype
insertTypingImport
insertThirdPartyImports [ ("nirum.validate", ["validate_boxed_type"])
, ("nirum.serialize", ["serialize_boxed_type"])
, ("nirum.deserialize", ["deserialize_boxed_type"])
Expand Down Expand Up @@ -524,7 +524,7 @@ compileTypeDeclaration src TypeDeclaration { typename = typename'
(map fieldName $ toList fields)
",\n "
hashText = toIndentedCodes (\ n -> [qq|self.{n}|]) fieldNames ", "
insertTypingImport
importTypingForPython3
insertThirdPartyImports [ ("nirum.validate", ["validate_record_type"])
, ("nirum.serialize", ["serialize_record_type"])
, ("nirum.deserialize", ["deserialize_record_type"])
Expand Down Expand Up @@ -586,7 +586,7 @@ compileTypeDeclaration src TypeDeclaration { typename = typename'
fieldCodes' = T.intercalate "\n\n" fieldCodes
enumMembers = toIndentedCodes
(\ (t, b) -> [qq|$t = '{b}'|]) enumMembers' "\n "
insertTypingImport
importTypingForPython3
insertEnumImport
insertThirdPartyImports [ ("nirum.serialize", ["serialize_union_type"])
, ("nirum.deserialize", ["deserialize_union_type"])
Expand Down
4 changes: 3 additions & 1 deletion test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
set -e

stack build
stack exec -- nirum -o nirum_fixture -t python test/nirum_fixture
python_outdir="nirum_fixture"
stack exec -- nirum -o "$python_outdir" -t python test/nirum_fixture
echo "*" > "$python_outdir/.gitignore"

tox --skip-missing-interpreters
37 changes: 15 additions & 22 deletions test/Nirum/Targets/PythonSpec.hs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import Data.Maybe (fromJust)

import qualified Data.Map.Strict as M
import qualified Data.SemVer as SV
import Data.Set (Set, union)
import System.FilePath ((</>))
import Test.Hspec.Meta
import Text.Email.Validate (emailAddress)
Expand Down Expand Up @@ -45,7 +44,6 @@ import qualified Nirum.Package.ModuleSet as MS
import Nirum.PackageSpec (createPackage)
import qualified Nirum.Targets.Python as PY
import Nirum.Targets.Python ( Source (Source)
, Code
, CodeGen
, CodeGenContext ( localImports
, standardImports
Expand Down Expand Up @@ -121,13 +119,8 @@ makeDummySource' pathPrefix m =
makeDummySource :: Module -> Source
makeDummySource = makeDummySource' []

versions :: [(PythonVersion, Set Code)]
versions = [ (Python2, [])
, (Python3, ["typing"])
]

spec :: Spec
spec = parallel $ forM_ versions $ \ (ver, typing) -> do
spec = parallel $ forM_ ([Python2, Python3] :: [PythonVersion]) $ \ ver -> do
let empty' = PY.empty ver
-- run' :: CodeGen a -> (Either CompileError a, CodeGenContext)
run' c = runCodeGen c empty'
Expand Down Expand Up @@ -168,7 +161,7 @@ spec = parallel $ forM_ versions $ \ (ver, typing) -> do
localImports ctx2 `shouldBe` []
compileError codeGen2 `shouldBe` Nothing

specify "compilePrimitiveType" $ do
specify [qq|compilePrimitiveType ($ver)|] $ do
code (compilePrimitiveType Bool) `shouldBe` "bool"
code (compilePrimitiveType Bigint) `shouldBe` "int"
let (decimalCode, decimalContext) = run' (compilePrimitiveType Decimal)
Expand Down Expand Up @@ -201,7 +194,7 @@ spec = parallel $ forM_ versions $ \ (ver, typing) -> do
Python2 -> "unicode"
Python3 -> "str"

describe "compileTypeExpression" $ do
describe [qq|compileTypeExpression ($ver)|] $ do
let s = makeDummySource $ Module [] Nothing
specify "TypeIdentifier" $ do
let (c, ctx) = run' $
Expand All @@ -212,29 +205,29 @@ spec = parallel $ forM_ versions $ \ (ver, typing) -> do
specify "OptionModifier" $ do
let (c', ctx') = run' $
compileTypeExpression s (OptionModifier "int32")
standardImports ctx' `shouldBe` typing
standardImports ctx' `shouldBe` ["typing"]
localImports ctx' `shouldBe` []
c' `shouldBe` Right "typing.Optional[int]"
specify "SetModifier" $ do
let (c'', ctx'') = run' $
compileTypeExpression s (SetModifier "int32")
standardImports ctx'' `shouldBe` typing
standardImports ctx'' `shouldBe` ["typing"]
localImports ctx'' `shouldBe` []
c'' `shouldBe` Right "typing.AbstractSet[int]"
specify "ListModifier" $ do
let (c''', ctx''') = run' $
compileTypeExpression s (ListModifier "int32")
standardImports ctx''' `shouldBe` typing
standardImports ctx''' `shouldBe` ["typing"]
localImports ctx''' `shouldBe` []
c''' `shouldBe` Right "typing.Sequence[int]"
specify "MapModifier" $ do
let (c'''', ctx'''') = run' $
compileTypeExpression s (MapModifier "uuid" "int32")
standardImports ctx'''' `shouldBe` union ["uuid"] typing
standardImports ctx'''' `shouldBe` ["typing", "uuid"]
localImports ctx'''' `shouldBe` []
c'''' `shouldBe` Right "typing.Mapping[uuid.UUID, int]"

describe "toClassName" $ do
describe [qq|toClassName ($ver)|] $ do
it "transform the facial name of the argument into PascalCase" $ do
toClassName "test" `shouldBe` "Test"
toClassName "hello-world" `shouldBe` "HelloWorld"
Expand All @@ -243,7 +236,7 @@ spec = parallel $ forM_ versions $ \ (ver, typing) -> do
toClassName "false" `shouldBe` "False_"
toClassName "none" `shouldBe` "None_"

describe "toAttributeName" $ do
describe [qq|toAttributeName ($ver)|] $ do
it "transform the facial name of the argument into snake_case" $ do
toAttributeName "test" `shouldBe` "test"
toAttributeName "hello-world" `shouldBe` "hello_world"
Expand All @@ -252,7 +245,7 @@ spec = parallel $ forM_ versions $ \ (ver, typing) -> do
toAttributeName "lambda" `shouldBe` "lambda_"
toAttributeName "nonlocal" `shouldBe` "nonlocal_"

describe "toNamePair" $ do
describe [qq|toNamePair ($ver)|] $ do
it "transforms the name to a Python code string of facial/behind pair" $
do toNamePair "text" `shouldBe` "('text', 'text')"
toNamePair (Name "test" "hello") `shouldBe` "('test', 'hello')"
Expand All @@ -266,7 +259,7 @@ spec = parallel $ forM_ versions $ \ (ver, typing) -> do
toNamePair (Name "abc" "lambda") `shouldBe` "('abc', 'lambda')"
toNamePair (Name "lambda" "abc") `shouldBe` "('lambda_', 'abc')"

specify "stringLiteral" $ do
specify [qq|stringLiteral ($ver)|] $ do
stringLiteral "asdf" `shouldBe` [q|"asdf"|]
stringLiteral [q|Say 'hello world'|]
`shouldBe` [q|"Say 'hello world'"|]
Expand All @@ -275,7 +268,7 @@ spec = parallel $ forM_ versions $ \ (ver, typing) -> do
stringLiteral "Say '\xc548\xb155'"
`shouldBe` [q|u"Say '\uc548\ub155'"|]

describe "compilePackage" $ do
describe [qq|compilePackage ($ver)|] $ do
it "returns a Map of file paths and their contents to generate" $ do
let (Source pkg _) = makeDummySource $ Module [] Nothing
files = compilePackage pkg
Expand Down Expand Up @@ -307,7 +300,7 @@ spec = parallel $ forM_ versions $ \ (ver, typing) -> do
]
M.keysSet files `shouldBe` directoryStructure

describe "InstallRequires" $ do
describe [qq|InstallRequires ($ver)|] $ do
let req = InstallRequires [] []
req2 = req { dependencies = ["six"] }
req3 = req { optionalDependencies = [((3, 4), ["enum34"])] }
Expand Down Expand Up @@ -350,9 +343,9 @@ spec = parallel $ forM_ versions $ \ (ver, typing) -> do
(3, 4) "ipaddress"
(req4 `unionInstallRequires` req5) `shouldBe` req6
(req5 `unionInstallRequires` req4) `shouldBe` req6
specify "toImportPath" $
specify [qq|toImportPath ($ver)|] $
PY.toImportPath ["foo", "bar"] `shouldBe` "foo.bar"
describe "Add ancestors of packages" $ do
describe [qq|add ancestors of packages ($ver)|] $ do
let (Source pkg _) = makeDummySource $ Module [] Nothing
modulePaths = MS.keysSet $ modules pkg
specify "toImportPaths" $
Expand Down
5 changes: 5 additions & 0 deletions test/nirum_fixture/fixture/foo.nrm
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,11 @@ record line (
bigint length,
);

record import-typing (
// see also: https://github.com/spoqa/nirum/issues/93
bigint? an-optional-field,
);

union mixed-name = western-name ( text first-name
, text middle-name
, text last-name
Expand Down