hydra-python 0.17.2 → 0.17.3
raw patch · 6 files changed
+98/−97 lines, 6 filesdep ~hydra-kernelPVP ok
version bump matches the API change (PVP)
Dependency ranges changed: hydra-kernel
API changes (from Hackage documentation)
Files
- hydra-python.cabal +2/−2
- src/main/haskell/Hydra/Python/Coder.hs +32/−31
- src/main/haskell/Hydra/Python/Names.hs +5/−5
- src/main/haskell/Hydra/Python/Serde.hs +37/−37
- src/main/haskell/Hydra/Python/Testing.hs +18/−18
- src/main/haskell/Hydra/Python/Utils.hs +4/−4
hydra-python.cabal view
@@ -5,7 +5,7 @@ -- see: https://github.com/sol/hpack name: hydra-python-version: 0.17.2+version: 0.17.3 synopsis: Hydra's Python coder: emit Python source from Hydra modules description: Hydra is an implementation of the LambdaGraph data model, which takes advantage of an isomorphism between labeled hypergraphs and typed lambda calculus: in Hydra, "graphs are programs, and programs are graphs". Python support for Hydra category: Data@@ -47,6 +47,6 @@ build-depends: base >=4.19.0 && <4.22 , containers >=0.6.7 && <0.8- , hydra-kernel ==0.17.2+ , hydra-kernel ==0.17.3 , scientific >=0.3.7 && <0.4 default-language: Haskell2010
src/main/haskell/Hydra/Python/Coder.hs view
@@ -32,6 +32,7 @@ import qualified Hydra.Overlay.Haskell.Lib.Maps as Maps import qualified Hydra.Overlay.Haskell.Lib.Math as Math import qualified Hydra.Overlay.Haskell.Lib.Optionals as Optionals+import qualified Hydra.Overlay.Haskell.Lib.Ordering as Ordering import qualified Hydra.Overlay.Haskell.Lib.Pairs as Pairs import qualified Hydra.Overlay.Haskell.Lib.Sets as Sets import qualified Hydra.Overlay.Haskell.Lib.Strings as Strings@@ -79,7 +80,7 @@ builderSetterName env fname = let base = Syntax.unName (PythonNames.encodeFieldName env fname)- in (Logic.ifElse (Logic.or (Equality.equal base "build") (Logic.or (Equality.equal base "builder") (Equality.equal base "self"))) (Strings.cat2 base "_") base)+ in (Logic.ifElse (Logic.or (Equality.equal base "build") (Logic.or (Equality.equal base "builder") (Equality.equal base "self"))) (Strings.concat2 base "_") base) -- | Encode a single case (Field) into a CaseBlock for a match statement caseBlockToExpr :: t0 -> PythonEnvironment.PythonEnvironment -> Core.Name -> [Core.FieldType] -> Bool -> (PythonEnvironment.PythonEnvironment -> Core.Term -> Either t1 [Syntax.Statement]) -> Core.CaseAlternative -> Either t1 Syntax.CaseBlock@@ -177,11 +178,11 @@ deconflictVariantName :: Bool -> PythonEnvironment.PythonEnvironment -> Core.Name -> Core.Name -> Graph.Graph -> Syntax.Name deconflictVariantName isQualified env unionName fname g = - let candidateHydraName = Core.Name (Strings.cat2 (Core.unName unionName) (Formatting.capitalize (Core.unName fname)))+ let candidateHydraName = Core.Name (Strings.concat2 (Core.unName unionName) (Formatting.capitalize (Core.unName fname))) termCollision = Maps.member candidateHydraName (Graph.graphBoundTerms g) typeCollision = Maps.member candidateHydraName (Graph.graphSchemaTypes g) collision = Logic.or termCollision typeCollision- in (Logic.ifElse collision (Syntax.Name (Strings.cat2 (Syntax.unName (PythonNames.variantName isQualified env unionName fname)) "_")) (PythonNames.variantName isQualified env unionName fname))+ in (Logic.ifElse collision (Syntax.Name (Strings.concat2 (Syntax.unName (PythonNames.variantName isQualified env unionName fname)) "_")) (PythonNames.variantName isQualified env unionName fname)) -- | Rewrite case statements to avoid variable name collisions deduplicateCaseVariables :: [Core.CaseAlternative] -> [Core.CaseAlternative]@@ -200,7 +201,7 @@ body = Core.lambdaBody v0 in (Optionals.cases (Maps.lookup v countByName) (Maps.insert v 1 countByName, (Lists.cons field done)) (\count -> let count2 = Math.add count 1- v2 = Core.Name (Strings.cat2 (Core.unName v) (Literals.showInt32 count2))+ v2 = Core.Name (Strings.concat2 (Core.unName v) (Literals.showInt32 count2)) newBody = Reduction.alphaConvert v v2 body newLam = Core.Lambda {@@ -325,7 +326,7 @@ fun = Pairs.first gathered args = Pairs.second gathered knownArity = termArityWithPrimitives g fun- arity = Math.max knownArity (Lists.length args)+ arity = Ordering.max knownArity (Lists.length args) in (Eithers.bind (Eithers.mapList (\t -> encodeTermInline cx env False t) args) (\pargs -> let hargs = Lists.take arity pargs rargs = Lists.drop arity pargs@@ -340,7 +341,7 @@ encodeApplicationInner :: Typing.InferenceContext -> PythonEnvironment.PythonEnvironment -> Core.Term -> [Syntax.Expression] -> [Syntax.Expression] -> Either Errors.Error (Syntax.Expression, [Syntax.Expression]) encodeApplicationInner cx env fun hargs rargs = - let firstArg = Optionals.fromOptional (Utils.pyNameToPyExpression (Syntax.Name "")) (Lists.maybeHead hargs)+ let firstArg = Optionals.withDefault (Utils.pyNameToPyExpression (Syntax.Name "")) (Lists.head hargs) restArgs = Lists.drop 1 hargs withRest = \e -> Logic.ifElse (Lists.null restArgs) e (Utils.functionCall (Utils.pyExpressionToPyPrimary e) restArgs) defaultCase =@@ -362,7 +363,7 @@ inlineVars = PythonEnvironment.pythonEnvironmentInlineVariables env in (Optionals.cases (Maps.lookup v0 (Graph.graphPrimitives g)) (Optionals.cases (Lexical.lookupBinding g v0) (Eithers.bind (encodeVariable cx env v0 hargs) (\expr -> Right (expr, rargs))) (\el -> Optionals.cases (Core.bindingTypeScheme el) (Eithers.bind (encodeVariable cx env v0 hargs) (\expr -> Right (expr, rargs))) (\ts -> let elArity = Arity.typeSchemeArity ts- consumeCount = Math.min elArity (Lists.length allArgs)+ consumeCount = Ordering.min elArity (Lists.length allArgs) consumedArgs = Lists.take consumeCount allArgs remainingArgs = Lists.drop consumeCount allArgs in (Logic.ifElse (Lists.null consumedArgs) (Eithers.bind (encodeVariable cx env v0 []) (\expr -> Right (expr, rargs))) (Logic.ifElse (Sets.member v0 inlineVars) (Right (@@ -418,7 +419,7 @@ mcsa = isCaseStatementApplication innerBody in (Optionals.cases mcsa ( let mcs = extractCaseElimination term1- in (Optionals.cases mcs (Eithers.bind (encodeTermMultiline cx env term1) (\stmts -> Optionals.cases (Lists.maybeHead stmts) (Left (Errors.ErrorOther (Errors.OtherError "encodeTermMultiline returned no statements"))) (\x -> Right x))) (\cs ->+ in (Optionals.cases mcs (Eithers.bind (encodeTermMultiline cx env term1) (\stmts -> Optionals.cases (Lists.head stmts) (Left (Errors.ErrorOther (Errors.OtherError "encodeTermMultiline returned no statements"))) (\x -> Right x))) (\cs -> let tname = Core.caseStatementTypeName cs dflt = Core.caseStatementDefault cs cases_ = Core.caseStatementCases cs@@ -462,7 +463,7 @@ Syntax.functionDefinitionDecorators = Nothing, Syntax.functionDefinitionRaw = funcDefRaw})))))))))))) (\csa -> Logic.ifElse (Lists.null lambdaParams) ( let mcs = extractCaseElimination term1- in (Optionals.cases mcs (Eithers.bind (encodeTermMultiline cx env term1) (\stmts -> Optionals.cases (Lists.maybeHead stmts) (Left (Errors.ErrorOther (Errors.OtherError "encodeTermMultiline returned no statements"))) (\x -> Right x))) (\cs ->+ in (Optionals.cases mcs (Eithers.bind (encodeTermMultiline cx env term1) (\stmts -> Optionals.cases (Lists.head stmts) (Left (Errors.ErrorOther (Errors.OtherError "encodeTermMultiline returned no statements"))) (\x -> Right x))) (\cs -> let tname = Core.caseStatementTypeName cs dflt = Core.caseStatementDefault cs cases_ = Core.caseStatementCases cs@@ -513,8 +514,8 @@ in (Eithers.bind (Resolution.requireUnionType cx (pythonEnvironmentGetGraph env) tname) (\rt -> let isEnum = Predicates.isEnumRowType rt isFull = isCasesFull rt cases_- capturedVarNames = Optionals.fromOptional [] (Lists.maybeInit lambdaParams)- matchLambdaParam = Optionals.fromOptional (Core.Name "") (Lists.maybeLast lambdaParams)+ capturedVarNames = Optionals.withDefault [] (Lists.init lambdaParams)+ matchLambdaParam = Optionals.withDefault (Core.Name "") (Lists.last lambdaParams) capturedParams = Lists.map (\n -> Syntax.ParamNoDefault { Syntax.paramNoDefaultParam = Syntax.Param {@@ -588,7 +589,7 @@ -- | Encode the default (wildcard) case block for a match statement encodeDefaultCaseBlock :: (t0 -> Either t1 Syntax.Expression) -> Bool -> Maybe t0 -> Core.Name -> Either t1 [Syntax.CaseBlock] encodeDefaultCaseBlock termToExpr isFull mdflt tname =- Eithers.bind (Optionals.cases mdflt (Right (Logic.ifElse isFull (Utils.raiseAssertionError "Unreachable: all variants handled") (Utils.raiseTypeError (Strings.cat2 "Unsupported " (Names.localNameOf tname))))) (\d -> Eithers.bind (termToExpr d) (\pyexpr -> Right (Utils.returnSingle pyexpr)))) (\stmt ->+ Eithers.bind (Optionals.cases mdflt (Right (Logic.ifElse isFull (Utils.raiseAssertionError "Unreachable: all variants handled") (Utils.raiseTypeError (Strings.concat2 "Unsupported " (Names.localNameOf tname))))) (\d -> Eithers.bind (termToExpr d) (\pyexpr -> Right (Utils.returnSingle pyexpr)))) (\stmt -> let patterns = Utils.pyClosedPatternToPyPatterns Syntax.ClosedPatternWildcard body = Utils.indentedBlock Nothing [ [@@ -1117,7 +1118,7 @@ args = Pairs.first gathered body = Pairs.second gathered in (Logic.ifElse (Equality.equal (Lists.length args) 1) (- let arg = Optionals.fromOptional Core.TermUnit (Lists.maybeHead args)+ let arg = Optionals.withDefault Core.TermUnit (Lists.head args) in case (Strip.deannotateAndDetypeTerm body) of Core.TermCases v0 -> let tname = Core.caseStatementTypeName v0@@ -1163,7 +1164,7 @@ args2 = Pairs.first gathered2 body2 = Pairs.second gathered2 in (Logic.ifElse (Equality.equal (Lists.length args2) 1) (- let arg = Optionals.fromOptional Core.TermUnit (Lists.maybeHead args2)+ let arg = Optionals.withDefault Core.TermUnit (Lists.head args2) in case (Strip.deannotateAndDetypeTerm body2) of Core.TermCases v0 -> let tname = Core.caseStatementTypeName v0@@ -1188,7 +1189,7 @@ encodeType :: PythonEnvironment.PythonEnvironment -> Core.Type -> Either t0 Syntax.Expression encodeType env typ = - let dflt = Right (Utils.doubleQuotedString (Strings.cat2 "type = " (PrintCore.type_ (Strip.deannotateType typ))))+ let dflt = Right (Utils.doubleQuotedString (Strings.concat2 "type = " (PrintCore.type_ (Strip.deannotateType typ)))) in case (Strip.deannotateType typ) of Core.TypeApplication v0 -> encodeApplicationType env v0 Core.TypeFunction v0 -> encodeFunctionType env v0@@ -1392,7 +1393,7 @@ let primArity = Arity.primitiveArity prim in (Logic.ifElse (Equality.equal primArity (Lists.length args)) (Right asFunctionCall) ( let numRemaining = Math.sub primArity (Lists.length args)- remainingParams = Lists.map (\i -> Syntax.Name (Strings.cat2 "x" (Literals.showInt32 i))) (Math.range 1 numRemaining)+ remainingParams = Lists.map (\i -> Syntax.Name (Strings.concat2 "x" (Literals.showInt32 i))) (Math.range 1 numRemaining) remainingExprs = Lists.map (\n -> Syntax.ExpressionSimple (Syntax.Disjunction [ Syntax.Conjunction [@@ -1418,7 +1419,7 @@ allArgs = Lists.concat2 args remainingExprs fullCall = Utils.functionCall (Utils.pyNameToPyPrimary (PythonNames.encodeName True Util.CaseConventionLowerSnake env name)) allArgs- in (Right (makeUncurriedLambda remainingParams fullCall))))))) (Optionals.cases mTyp (Logic.ifElse (Sets.member name tcLambdaVars) (Right asVariable) (Logic.ifElse (Sets.member name inlineVars) (Right (lazyDotGet asVariable)) (Optionals.cases (Lexical.lookupPrimitive g name) (Optionals.cases (Lexical.lookupBinding g name) (Optionals.cases (Maps.lookup name tcMetadata) (Left (Errors.ErrorOther (Errors.OtherError (Strings.cat2 "Unknown variable: " (Core.unName name))))) (\_ -> Right asFunctionCall)) (\el ->+ in (Right (makeUncurriedLambda remainingParams fullCall))))))) (Optionals.cases mTyp (Logic.ifElse (Sets.member name tcLambdaVars) (Right asVariable) (Logic.ifElse (Sets.member name inlineVars) (Right (lazyDotGet asVariable)) (Optionals.cases (Lexical.lookupPrimitive g name) (Optionals.cases (Lexical.lookupBinding g name) (Optionals.cases (Maps.lookup name tcMetadata) (Left (Errors.ErrorOther (Errors.OtherError (Strings.concat2 "Unknown variable: " (Core.unName name))))) (\_ -> Right asFunctionCall)) (\el -> let elTrivial1 = Predicates.isTrivialTerm (Core.bindingTerm el) in (Optionals.cases (Core.bindingTypeScheme el) (Right asVariable) (\ts -> Logic.ifElse (Logic.and (Logic.and (Equality.equal (Arity.typeSchemeArity ts) 0) (Predicates.isComplexBinding tc el)) (Logic.not elTrivial1)) (Right asFunctionCall) ( let asFunctionRef =@@ -1763,7 +1764,7 @@ args = Pairs.first gathered body = Pairs.second gathered in (Logic.ifElse (Logic.not (Equality.equal (Lists.length args) 1)) Nothing (- let arg = Optionals.fromOptional Core.TermUnit (Lists.maybeHead args)+ let arg = Optionals.withDefault Core.TermUnit (Lists.head args) in case (Strip.deannotateAndDetypeTerm body) of Core.TermCases v0 -> Just (Core.caseStatementTypeName v0, (Core.caseStatementDefault v0, (Core.caseStatementCases v0, arg))) _ -> Nothing))@@ -1774,7 +1775,7 @@ let numCases = Lists.length cases_ numFields = Lists.length rowType- in (Logic.not (Equality.lt numCases numFields))+ in (Logic.not (Ordering.lt numCases numFields)) -- | Check whether a list of definitions contains any type definitions isTypeModuleCheck :: [Packaging.Definition] -> Bool@@ -1792,7 +1793,7 @@ isVariantUnitType rowType fieldName = let mfield = Lists.find (\ft -> Equality.equal (Core.fieldTypeName ft) fieldName) rowType- in (Optionals.fromOptional False (Optionals.map (\ft -> Predicates.isUnitType (Strip.deannotateType (Core.fieldTypeType ft))) mfield))+ in (Optionals.withDefault False (Optionals.map (\ft -> Predicates.isUnitType (Strip.deannotateType (Core.fieldTypeType ft))) mfield)) -- | Wrap an expression in a .get() method call (for Lazy unwrap at use sites) lazyDotGet :: Syntax.Expression -> Syntax.Expression@@ -1841,7 +1842,7 @@ makeSimpleLambda :: Int -> Syntax.Expression -> Syntax.Expression makeSimpleLambda arity lhs = - let args = Lists.map (\i -> Syntax.Name (Strings.cat2 "x" (Literals.showInt32 i))) (Math.range 1 arity)+ let args = Lists.map (\i -> Syntax.Name (Strings.concat2 "x" (Literals.showInt32 i))) (Math.range 1 arity) in (Logic.ifElse (Equality.equal arity 0) lhs (Syntax.ExpressionLambda (Syntax.Lambda { Syntax.lambdaParams = Syntax.LambdaParameters { Syntax.lambdaParametersSlashNoDefault = Nothing,@@ -1957,9 +1958,9 @@ (condImportSymbol "TypeVar" (PythonEnvironment.pythonModuleMetadataUsesTypeVar meta)), (condImportSymbol "cast" (PythonEnvironment.pythonModuleMetadataUsesCast meta))])] simplified =- Optionals.cat (Lists.map (\p ->+ Optionals.givens (Lists.map (\p -> let modName = Pairs.first p- symbols = Optionals.cat (Pairs.second p)+ symbols = Optionals.givens (Pairs.second p) in (Logic.ifElse (Lists.null symbols) Nothing (Just (modName, symbols)))) pairs) in (Lists.map (\p -> standardImportStatement (Pairs.first p) (Pairs.second p)) simplified) @@ -2008,7 +2009,7 @@ recordBuilderClass :: PythonEnvironment.PythonEnvironment -> Core.Name -> [Core.FieldType] -> Maybe Syntax.Args -> Either t0 [Syntax.Statement] recordBuilderClass env name rowType recordArgs = Eithers.bind (Eithers.mapList (\ft -> Eithers.map (\pyType -> Utils.pyAssignmentToPyStatement (Syntax.AssignmentTyped (Syntax.TypedAssignment {- Syntax.typedAssignmentLhs = (Syntax.SingleTargetName (Syntax.Name (Strings.cat2 "_" (Syntax.unName (PythonNames.encodeFieldName env (Core.fieldTypeName ft)))))),+ Syntax.typedAssignmentLhs = (Syntax.SingleTargetName (Syntax.Name (Strings.concat2 "_" (Syntax.unName (PythonNames.encodeFieldName env (Core.fieldTypeName ft)))))), Syntax.typedAssignmentType = pyType, Syntax.typedAssignmentRhs = (Just (Syntax.AnnotatedRhsStar [ Syntax.StarExpressionSimple (Utils.pyNameToPyExpression Utils.pyNone)]))}))) (encodeType env (Core.fieldTypeType ft))) rowType) (\builderFields ->@@ -2017,7 +2018,7 @@ buildKwargs = Lists.map (\ft -> Syntax.KwargOrStarredKwarg (Syntax.Kwarg { Syntax.kwargName = (Syntax.Name (Syntax.unName (PythonNames.encodeFieldName env (Core.fieldTypeName ft)))),- Syntax.kwargValue = (Utils.projectFromExpression (Utils.pyNameToPyExpression (Syntax.Name "self")) (Syntax.Name (Strings.cat2 "_" (Syntax.unName (PythonNames.encodeFieldName env (Core.fieldTypeName ft))))))})) rowType+ Syntax.kwargValue = (Utils.projectFromExpression (Utils.pyNameToPyExpression (Syntax.Name "self")) (Syntax.Name (Strings.concat2 "_" (Syntax.unName (PythonNames.encodeFieldName env (Core.fieldTypeName ft))))))})) rowType ctorCall = Utils.pyPrimaryToPyExpression (Utils.primaryWithRhs (Utils.pyNameToPyPrimary pyName) (Syntax.PrimaryRhsCall (Syntax.Args { Syntax.argsPositional = [],@@ -2060,7 +2061,7 @@ Syntax.classDefinitionTypeParams = [], Syntax.classDefinitionArguments = recordArgs, Syntax.classDefinitionBody = builderBody})- qualifiedBuilderName = Syntax.Name (Strings.cat2 (Syntax.unName pyName) ".Builder")+ qualifiedBuilderName = Syntax.Name (Strings.concat2 (Syntax.unName pyName) ".Builder") builderCall = Utils.functionCall (Utils.pyNameToPyPrimary qualifiedBuilderName) [] factoryMethod = Syntax.StatementCompound (Syntax.CompoundStatementFunction (Syntax.FunctionDefinition {@@ -2090,7 +2091,7 @@ let fname = Core.fieldTypeName fieldType setterName = builderSetterName env fname paramName = Syntax.Name setterName- storageName = Strings.cat2 "_" (Syntax.unName (PythonNames.encodeFieldName env (Core.fieldTypeName fieldType)))+ storageName = Strings.concat2 "_" (Syntax.unName (PythonNames.encodeFieldName env (Core.fieldTypeName fieldType))) kwarg = Syntax.KwargOrStarredKwarg (Syntax.Kwarg { Syntax.kwargName = (Syntax.Name storageName),@@ -2132,7 +2133,7 @@ let fname = Core.fieldTypeName fieldType snake = Syntax.unName (PythonNames.encodeFieldName env fname)- methodName = Strings.cat2 "with_" snake+ methodName = Strings.concat2 "with_" snake kwargKey = Syntax.Name snake paramSnake = Logic.ifElse (Equality.equal snake "self") "_self" snake paramName = Syntax.Name paramSnake@@ -2815,7 +2816,7 @@ termArityWithPrimitives :: Graph.Graph -> Core.Term -> Int termArityWithPrimitives graph term = case (Strip.deannotateAndDetypeTerm term) of- Core.TermApplication v0 -> Math.max 0 (Math.sub (termArityWithPrimitives graph (Core.applicationFunction v0)) 1)+ Core.TermApplication v0 -> Ordering.max 0 (Math.sub (termArityWithPrimitives graph (Core.applicationFunction v0)) 1) Core.TermLambda v0 -> Math.add 1 (termArityWithPrimitives graph (Core.lambdaBody v0)) Core.TermProject _ -> 1 Core.TermUnwrap _ -> 1@@ -2877,7 +2878,7 @@ -- | Create args for variant (Node[type], Generic[tparams]) variantArgs :: Syntax.Expression -> [Core.Name] -> Syntax.Args variantArgs ptype tparams =- Utils.pyExpressionsToPyArgs (Optionals.cat [+ Utils.pyExpressionsToPyArgs (Optionals.givens [ Just (Utils.pyPrimaryToPyExpression (Utils.primaryWithExpressionSlices (Syntax.PrimarySimple (Syntax.AtomName (Syntax.Name "Node"))) [ ptype])), (genericArg tparams)])@@ -2902,7 +2903,7 @@ withDefinitions env defs body = let bindings =- Optionals.cat (Lists.map (\def_ -> case def_ of+ Optionals.givens (Lists.map (\def_ -> case def_ of Packaging.DefinitionTerm v0 -> Just (Core.Binding { Core.bindingName = (Packaging.termDefinitionName v0), Core.bindingTerm = (Packaging.termDefinitionBody v0),
src/main/haskell/Hydra/Python/Names.hs view
@@ -47,7 +47,7 @@ -- | Generate a constant name for a field definition encodeConstantForFieldName :: t0 -> t1 -> Core.Name -> Syntax.Name encodeConstantForFieldName env tname fname =- Syntax.Name (Formatting.convertCase Util.CaseConventionCamel Util.CaseConventionUpperSnake (Strings.intercalate "_" (Strings.splitOn "-" (Core.unName fname))))+ Syntax.Name (Formatting.convertCase Util.CaseConventionCamel Util.CaseConventionUpperSnake (Strings.join "_" (Strings.splitOn "-" (Core.unName fname)))) -- | Generate a constant name for a type definition encodeConstantForTypeName :: t0 -> t1 -> Syntax.Name@@ -74,7 +74,7 @@ local = Util.qualifiedNameLocal qualName pyLocal = sanitizePythonName (Formatting.convertCase Util.CaseConventionCamel conv local) pyNs = \nsVal -> encodeNamespaceStringWithOverrides nsVal- in (Logic.ifElse isQualified (Optionals.cases (Maps.lookup name boundVars) (Logic.ifElse (Equality.equal mns (Just focusNs)) (Syntax.Name (Logic.ifElse useFutureAnnotations pyLocal (Serde.escapePythonString True pyLocal))) (Optionals.cases mns (Syntax.Name pyLocal) (\nsVal -> Syntax.Name (Strings.cat2 (pyNs nsVal) (Strings.cat2 "." pyLocal))))) (\n -> n)) (Syntax.Name pyLocal))+ in (Logic.ifElse isQualified (Optionals.cases (Maps.lookup name boundVars) (Logic.ifElse (Equality.equal mns (Just focusNs)) (Syntax.Name (Logic.ifElse useFutureAnnotations pyLocal (Serde.escapePythonString True pyLocal))) (Optionals.cases mns (Syntax.Name pyLocal) (\nsVal -> Syntax.Name (Strings.concat2 (pyNs nsVal) (Strings.concat2 "." pyLocal))))) (\n -> n)) (Syntax.Name pyLocal)) -- | Encode a name as a fully qualified Python name encodeNameQualified :: Environment.PythonEnvironment -> Core.Name -> Syntax.Name@@ -88,7 +88,7 @@ mns = Util.qualifiedNameModuleName qualName local = Util.qualifiedNameLocal qualName pyNs = \nsVal -> encodeNamespaceStringWithOverrides nsVal- in (Optionals.cases (Maps.lookup name boundVars) (Logic.ifElse (Equality.equal mns (Just focusNs)) (Syntax.Name (Logic.ifElse useFutureAnnotations local (Serde.escapePythonString True local))) (Optionals.cases mns (Syntax.Name (sanitizePythonName local)) (\nsVal -> Syntax.Name (Strings.cat2 (pyNs nsVal) (Strings.cat2 "." (sanitizePythonName local)))))) (\n -> n))+ in (Optionals.cases (Maps.lookup name boundVars) (Logic.ifElse (Equality.equal mns (Just focusNs)) (Syntax.Name (Logic.ifElse useFutureAnnotations local (Serde.escapePythonString True local))) (Optionals.cases mns (Syntax.Name (sanitizePythonName local)) (\nsVal -> Syntax.Name (Strings.concat2 (pyNs nsVal) (Strings.concat2 "." (sanitizePythonName local)))))) (\n -> n)) -- | Encode a namespace as a Python dotted name encodeNamespace :: Packaging.ModuleName -> Syntax.DottedName@@ -98,7 +98,7 @@ -- | Convert a ModuleName to its Python dotted import string, routing overlay modules to hydra.overlay.python.* encodeNamespaceStringWithOverrides :: Packaging.ModuleName -> String encodeNamespaceStringWithOverrides nsVal =- Optionals.fromOptional (Strings.intercalate "." (Lists.map (Formatting.convertCase Util.CaseConventionCamel Util.CaseConventionLowerSnake) (Strings.splitOn "." (Packaging.unModuleName nsVal)))) (Maps.lookup nsVal overlayPythonModuleAliases)+ Optionals.withDefault (Strings.join "." (Lists.map (Formatting.convertCase Util.CaseConventionCamel Util.CaseConventionLowerSnake) (Strings.splitOn "." (Packaging.unModuleName nsVal)))) (Maps.lookup nsVal overlayPythonModuleAliases) -- | Encode a namespace as a Python dotted name, routing overlay modules to their hydra.overlay.python.* paths encodeNamespaceWithOverrides :: Packaging.ModuleName -> Syntax.DottedName@@ -191,4 +191,4 @@ -- | Generate a variant name from type name and field name variantName :: Bool -> Environment.PythonEnvironment -> Core.Name -> Core.Name -> Syntax.Name variantName isQualified env tname fname =- encodeName isQualified Util.CaseConventionPascal env (Core.Name (Strings.cat2 (Core.unName tname) (Formatting.capitalize (Core.unName fname))))+ encodeName isQualified Util.CaseConventionPascal env (Core.Name (Strings.concat2 (Core.unName tname) (Formatting.capitalize (Core.unName fname))))
src/main/haskell/Hydra/Python/Serde.hs view
@@ -139,7 +139,7 @@ let lhs = Syntax.bitwiseAndLhs band rhs = Syntax.bitwiseAndRhs band- in (Serialization.spaceSep (Optionals.cat [+ in (Serialization.spaceSep (Optionals.givens [ Optionals.map (\l -> Serialization.spaceSep [ bitwiseAndToExpr l, (Serialization.cst "&")]) lhs,@@ -151,7 +151,7 @@ let lhs = Syntax.bitwiseOrLhs bor rhs = Syntax.bitwiseOrRhs bor- in (Serialization.spaceSep (Optionals.cat [+ in (Serialization.spaceSep (Optionals.givens [ Optionals.map (\l -> Serialization.spaceSep [ bitwiseOrToExpr l, (Serialization.cst "|")]) lhs,@@ -163,7 +163,7 @@ let lhs = Syntax.bitwiseXorLhs bxor rhs = Syntax.bitwiseXorRhs bxor- in (Serialization.spaceSep (Optionals.cat [+ in (Serialization.spaceSep (Optionals.givens [ Optionals.map (\l -> Serialization.spaceSep [ bitwiseXorToExpr l, (Serialization.cst "^")]) lhs,@@ -189,7 +189,7 @@ body = Syntax.caseBlockBody cb in (Serialization.newlineSep [ Serialization.noSep [- Serialization.spaceSep (Optionals.cat [+ Serialization.spaceSep (Optionals.givens [ Just (Serialization.cst "case"), (Just (patternsToExpr patterns)), (Optionals.map guardToExpr guard)]),@@ -209,9 +209,9 @@ Serialization.cst "(", (argsToExpr a), (Serialization.cst ")")]) args- in (Serialization.newlineSep (Optionals.cat [+ in (Serialization.newlineSep (Optionals.givens [ Optionals.map decoratorsToExpr decs,- (Just (Serialization.noSep (Optionals.cat [+ (Just (Serialization.noSep (Optionals.givens [ Just (Serialization.spaceSep [ Serialization.cst "class", (nameToExpr name)]),@@ -226,7 +226,7 @@ let noa = Syntax.classPatternNameOrAttribute cp pos = Syntax.classPatternPositionalPatterns cp kw = Syntax.classPatternKeywordPatterns cp- in (Serialization.noSep (Optionals.cat [+ in (Serialization.noSep (Optionals.givens [ Just (nameOrAttributeToExpr noa), (Just (Serialization.cst "(")), (Optionals.map positionalPatternsToExpr pos),@@ -331,7 +331,7 @@ let name = Syntax.dottedAsNameName dan alias = Syntax.dottedAsNameAs dan- in (Serialization.spaceSep (Optionals.cat [+ in (Serialization.spaceSep (Optionals.givens [ Just (dottedNameToExpr name), (Optionals.map (\a -> Serialization.spaceSep [ Serialization.cst "as",@@ -339,7 +339,7 @@ -- | Serialize a dotted name (e.g., module.submodule) dottedNameToExpr :: Syntax.DottedName -> Ast.Expr-dottedNameToExpr dn = Serialization.cst (Strings.intercalate "." (Lists.map (\n -> Syntax.unName n) (Syntax.unDottedName dn)))+dottedNameToExpr dn = Serialization.cst (Strings.join "." (Lists.map (\n -> Syntax.unName n) (Syntax.unDottedName dn))) -- | Serialize a double-starred key-value pair doubleStarredKvpairToExpr :: Syntax.DoubleStarredKvpair -> Ast.Expr@@ -354,7 +354,7 @@ escapePythonString :: Bool -> String -> String escapePythonString doubleQuoted s = - let replace = \old -> \new -> \str -> Strings.intercalate new (Strings.splitOn old str)+ let replace = \old -> \new -> \str -> Strings.join new (Strings.splitOn old str) s1 = replace "\\" "\\\\" s s2 = replace "\NUL" "\\x00" s1 s3 = replace "\n" "\\n" s2@@ -362,7 +362,7 @@ s5 = replace "\r" "\\r" s4 escaped = Logic.ifElse doubleQuoted (replace "\"" "\\\"" s5) (replace "'" "\\'" s5) quote = Logic.ifElse doubleQuoted "\"" "'"- in (Strings.cat2 quote (Strings.cat2 escaped quote))+ in (Strings.concat2 quote (Strings.concat2 escaped quote)) -- | Serialize a Python expression expressionToExpr :: Syntax.Expression -> Ast.Expr@@ -407,10 +407,10 @@ (expressionToExpr t)]) retType in (Serialization.newlineSep [ Serialization.noSep [- Serialization.spaceSep (Optionals.cat [+ Serialization.spaceSep (Optionals.givens [ asyncKw, (Just (Serialization.cst "def")),- (Just (Serialization.noSep (Optionals.cat [+ (Just (Serialization.noSep (Optionals.givens [ Just (nameToExpr name), tparamPart, (Just (Serialization.cst "(")),@@ -426,7 +426,7 @@ let decs = Syntax.functionDefinitionDecorators fd raw = Syntax.functionDefinitionRaw fd- in (Serialization.newlineSep (Optionals.cat [+ in (Serialization.newlineSep (Optionals.givens [ Optionals.map decoratorsToExpr decs, (Just (functionDefRawToExpr raw))])) @@ -474,7 +474,7 @@ name = Syntax.importFromDottedName if_ targets = Syntax.importFromTargets if_ lhs =- Serialization.noSep (Optionals.cat (Lists.concat [+ Serialization.noSep (Optionals.givens (Lists.concat [ Lists.map (\p -> Just (relativeImportPrefixToExpr p)) prefixes, [ Optionals.map dottedNameToExpr name]]))@@ -641,7 +641,7 @@ numberToExpr num = case num of Syntax.NumberFloat v0 -> Serialization.cst (pythonFloatLiteralText (Literals.showFloat64 v0))- Syntax.NumberImaginary v0 -> Serialization.cst (Strings.cat2 (pythonFloatLiteralText (Literals.showFloat64 v0)) "j")+ Syntax.NumberImaginary v0 -> Serialization.cst (Strings.concat2 (pythonFloatLiteralText (Literals.showFloat64 v0)) "j") Syntax.NumberInteger v0 -> Serialization.cst (Literals.showBigint v0) -- | Serialize an or pattern@@ -666,7 +666,7 @@ let name = Syntax.paramName p ann = Syntax.paramAnnotation p- in (Serialization.noSep (Optionals.cat [+ in (Serialization.noSep (Optionals.givens [ Just (nameToExpr name), (Optionals.map annotationToExpr ann)])) @@ -715,7 +715,7 @@ let lhs = Syntax.powerLhs p rhs = Syntax.powerRhs p- in (Serialization.spaceSep (Optionals.cat [+ in (Serialization.spaceSep (Optionals.givens [ Just (awaitPrimaryToExpr lhs), (Optionals.map (\r -> Serialization.spaceSep [ Serialization.cst "**",@@ -760,13 +760,13 @@ pythonDocEntityRef ref = case ref of Packaging.EntityReferenceDefinition v0 -> case v0 of- Packaging.DefinitionReferencePrimitive v1 -> Strings.cat2 ":func:`" (Strings.cat2 (Names.localNameOf v1) "`")- Packaging.DefinitionReferenceTerm v1 -> Strings.cat2 ":func:`" (Strings.cat2 (Names.localNameOf v1) "`")- Packaging.DefinitionReferenceType v1 -> Strings.cat2 ":class:`" (Strings.cat2 (Names.localNameOf v1) "`")- Packaging.EntityReferenceModule v0 -> Strings.cat2 "" (Packaging.unModuleName v0)- Packaging.EntityReferencePackage v0 -> Strings.cat2 "" (Packaging.unPackageName v0)- Packaging.EntityReferenceTermExpr v0 -> Strings.cat2 "``" (Strings.cat2 v0 "``")- Packaging.EntityReferenceTypeExpr v0 -> Strings.cat2 "``" (Strings.cat2 v0 "``")+ Packaging.DefinitionReferencePrimitive v1 -> Strings.concat2 ":func:`" (Strings.concat2 (Names.localNameOf v1) "`")+ Packaging.DefinitionReferenceTerm v1 -> Strings.concat2 ":func:`" (Strings.concat2 (Names.localNameOf v1) "`")+ Packaging.DefinitionReferenceType v1 -> Strings.concat2 ":class:`" (Strings.concat2 (Names.localNameOf v1) "`")+ Packaging.EntityReferenceModule v0 -> Strings.concat2 "" (Packaging.unModuleName v0)+ Packaging.EntityReferencePackage v0 -> Strings.concat2 "" (Packaging.unPackageName v0)+ Packaging.EntityReferenceTermExpr v0 -> Strings.concat2 "``" (Strings.concat2 v0 "``")+ Packaging.EntityReferenceTypeExpr v0 -> Strings.concat2 "``" (Strings.concat2 v0 "``") pythonFloatLiteralText :: String -> String pythonFloatLiteralText s =@@ -778,7 +778,7 @@ let expr = Syntax.raiseExpressionExpression re from_ = Syntax.raiseExpressionFrom re- in (Serialization.spaceSep (Optionals.cat [+ in (Serialization.spaceSep (Optionals.givens [ Just (expressionToExpr expr), (Optionals.map (\f -> Serialization.spaceSep [ Serialization.cst "from",@@ -787,7 +787,7 @@ -- | Serialize a raise statement raiseStatementToExpr :: Syntax.RaiseStatement -> Ast.Expr raiseStatementToExpr rs =- Serialization.spaceSep (Optionals.cat [+ Serialization.spaceSep (Optionals.givens [ Just (Serialization.cst "raise"), (Optionals.map raiseExpressionToExpr (Syntax.unRaiseStatement rs))]) @@ -933,14 +933,14 @@ prefix = Optionals.cases (Syntax.stringPrefix s) "" stringPrefixToText style = Syntax.stringQuoteStyle s in case style of- Syntax.QuoteStyleSingle -> Serialization.cst (Strings.cat2 prefix (escapePythonString False content))- Syntax.QuoteStyleDouble -> Serialization.cst (Strings.cat2 prefix (escapePythonString True content))+ Syntax.QuoteStyleSingle -> Serialization.cst (Strings.concat2 prefix (escapePythonString False content))+ Syntax.QuoteStyleDouble -> Serialization.cst (Strings.concat2 prefix (escapePythonString True content)) Syntax.QuoteStyleTripleSingle -> Serialization.noSep [- Serialization.cst (Strings.cat2 prefix "'''"),+ Serialization.cst (Strings.concat2 prefix "'''"), (Serialization.cst content), (Serialization.cst "'''")] Syntax.QuoteStyleTripleDouble -> Serialization.noSep [- Serialization.cst (Strings.cat2 prefix "\"\"\""),+ Serialization.cst (Strings.concat2 prefix "\"\"\""), (Serialization.cst content), (Serialization.cst "\"\"\"")] @@ -991,16 +991,16 @@ -- | Convert a doc string to Python comment format. Empty source lines emit `#` (no trailing space) so blank comment lines don't carry trailing whitespace into the generated file. toPythonComments :: String -> String toPythonComments doc_ =- Logic.ifElse (Equality.equal doc_ "") "" (Strings.intercalate "\n" (Lists.map (\line -> Logic.ifElse (Equality.equal line "") "#" (Strings.cat2 "# " line)) (Strings.lines (Docs.renderDocStringWith pythonDocEntityRef doc_))))+ Logic.ifElse (Equality.equal doc_ "") "" (Strings.join "\n" (Lists.map (\line -> Logic.ifElse (Equality.equal line "") "#" (Strings.concat2 "# " line)) (Strings.lines (Docs.renderDocStringWith pythonDocEntityRef doc_)))) -- | Serialize a Python tuple tupleToExpr :: Syntax.Tuple -> Ast.Expr tupleToExpr t = let es = Syntax.unTuple t- in (Optionals.fromOptional (Serialization.parenListAdaptive (Lists.map starNamedExpressionToExpr es)) (Optionals.map (\firstEs -> Logic.ifElse (Equality.equal (Lists.length es) 1) (Serialization.parens (Serialization.noSep [+ in (Optionals.withDefault (Serialization.parenListAdaptive (Lists.map starNamedExpressionToExpr es)) (Optionals.map (\firstEs -> Logic.ifElse (Equality.equal (Lists.length es) 1) (Serialization.parens (Serialization.noSep [ starNamedExpressionToExpr firstEs,- (Serialization.cst ",")])) (Serialization.parenListAdaptive (Lists.map starNamedExpressionToExpr es))) (Lists.maybeHead es)))+ (Serialization.cst ",")])) (Serialization.parenListAdaptive (Lists.map starNamedExpressionToExpr es))) (Lists.head es))) -- | Serialize a type alias typeAliasToExpr :: Syntax.TypeAlias -> Ast.Expr@@ -1010,7 +1010,7 @@ tparams = Syntax.typeAliasTypeParams ta expr = Syntax.typeAliasExpression ta alias =- Serialization.noSep (Optionals.cat [+ Serialization.noSep (Optionals.givens [ Just (nameToExpr name), (Logic.ifElse (Lists.null tparams) Nothing (Just (Serialization.bracketList Serialization.inlineStyle (Lists.map typeParameterToExpr tparams))))]) in (Serialization.spaceSep [@@ -1034,7 +1034,7 @@ let lhs = Syntax.typedAssignmentLhs ta typ = Syntax.typedAssignmentType ta rhs = Syntax.typedAssignmentRhs ta- in (Serialization.spaceSep (Optionals.cat [+ in (Serialization.spaceSep (Optionals.givens [ Just (Serialization.noSep [ singleTargetToExpr lhs, (Serialization.cst ":")]),@@ -1063,7 +1063,7 @@ let cond = Syntax.whileStatementCondition ws body = Syntax.whileStatementBody ws else_ = Syntax.whileStatementElse ws- in (Serialization.newlineSep (Optionals.cat [+ in (Serialization.newlineSep (Optionals.givens [ Just (Serialization.newlineSep [ Serialization.spaceSep [ Serialization.cst "while",
src/main/haskell/Hydra/Python/Testing.hs view
@@ -49,12 +49,12 @@ let groupName_ = Testing.testGroupName testGroup header =- Strings.cat [- Strings.cat2 "# " Constants.warningAutoGeneratedFile,+ Strings.concat [+ Strings.concat2 "# " Constants.warningAutoGeneratedFile, "\n",- (Strings.cat2 "# " groupName_),+ (Strings.concat2 "# " groupName_), "\n\n"]- in (Strings.cat [+ in (Strings.concat [ header, testBody, "\n"])@@ -62,7 +62,7 @@ -- | Format a test name for Python (snake_case with test_ prefix) formatPythonTestName :: String -> String formatPythonTestName name =- Strings.cat2 "test_" (Strings.fromList (Lists.map (\c -> Logic.ifElse (Chars.isAlphaNum c) (Chars.toLower c) 95) (Strings.toList name)))+ Strings.concat2 "test_" (Strings.fromList (Lists.map (\c -> Logic.ifElse (Chars.isAlphaNum c) (Chars.toLower c) 95) (Strings.toList name))) -- | Generate a single pytest test case from a test case with metadata generatePythonTestCase :: [String] -> Testing.TestCaseWithMetadata -> Either t0 [String]@@ -74,15 +74,15 @@ Testing.TestCaseUniversal v0 -> let actual_ = Testing.universalTestCaseActual v0 () expected_ = Testing.universalTestCaseExpected v0 ()- fullName = Logic.ifElse (Lists.null groupPath) name_ (Strings.intercalate "__" (Lists.concat2 groupPath [+ fullName = Logic.ifElse (Lists.null groupPath) name_ (Strings.join "__" (Lists.concat2 groupPath [ name_])) formattedName = formatPythonTestName fullName in (Right [- Strings.cat [+ Strings.concat [ "def ", formattedName, "():"],- (Strings.cat [+ (Strings.concat [ " assert (", actual_, ") == (",@@ -101,15 +101,15 @@ subgroups = Testing.testGroupSubgroups testGroup in (Eithers.bind (Eithers.mapList (\tc -> generatePythonTestCase groupPath tc) cases_) (\testCaseLines -> Eithers.bind (Eithers.mapList (\subgroup -> let groupName = Testing.testGroupName subgroup- header = Strings.cat2 "# " groupName- in (Eithers.map (\content -> Strings.cat [+ header = Strings.concat2 "# " groupName+ in (Eithers.map (\content -> Strings.concat [ header, "\n\n", content]) (generatePythonTestGroupHierarchy (Lists.concat2 groupPath [ groupName]) subgroup))) subgroups) (\subgroupBlocks ->- let testCasesStr = Strings.intercalate "\n\n" (Lists.concat testCaseLines)- subgroupsStr = Strings.intercalate "\n\n" subgroupBlocks- in (Right (Strings.cat [+ let testCasesStr = Strings.join "\n\n" (Lists.concat testCaseLines)+ subgroupsStr = Strings.join "\n\n" subgroupBlocks+ in (Right (Strings.concat [ testCasesStr, (Logic.ifElse (Logic.or (Equality.equal testCasesStr "") (Equality.equal subgroupsStr "")) "" "\n\n"), subgroupsStr])))))@@ -121,15 +121,15 @@ let testModuleContent = buildPythonTestModule testModule testGroup testBody ns_ = Packaging.moduleName testModule parts = Strings.splitOn "." (Packaging.unModuleName ns_)- dirParts = Optionals.fromOptional [] (Lists.maybeInit parts)+ dirParts = Optionals.withDefault [] (Lists.init parts) fileName =- Strings.cat [+ Strings.concat [ "test_",- (Optionals.fromOptional "" (Lists.maybeLast parts)),+ (Optionals.withDefault "" (Lists.last parts)), ".py"] filePath =- Strings.cat [- Strings.intercalate "/" dirParts,+ Strings.concat [+ Strings.join "/" dirParts, "/", fileName] in (filePath, testModuleContent)) (generatePythonTestGroupHierarchy [] testGroup)
src/main/haskell/Hydra/Python/Utils.hs view
@@ -108,7 +108,7 @@ decodePyConjunctionToPyPrimary c = let inversions = Syntax.unConjunction c- in (Logic.ifElse (Equality.equal (Lists.length inversions) 1) (Optionals.bind (Lists.maybeHead inversions) (\i -> decodePyInversionToPyPrimary i)) Nothing)+ in (Logic.ifElse (Equality.equal (Lists.length inversions) 1) (Optionals.bind (Lists.head inversions) (\i -> decodePyInversionToPyPrimary i)) Nothing) -- | Decode an Expression to a Primary if possible decodePyExpressionToPyPrimary :: Syntax.Expression -> Maybe Syntax.Primary@@ -116,7 +116,7 @@ case e of Syntax.ExpressionSimple v0 -> let conjunctions = Syntax.unDisjunction v0- in (Logic.ifElse (Equality.equal (Lists.length conjunctions) 1) (Optionals.bind (Lists.maybeHead conjunctions) (\c2 -> decodePyConjunctionToPyPrimary c2)) Nothing)+ in (Logic.ifElse (Equality.equal (Lists.length conjunctions) 1) (Optionals.bind (Lists.head conjunctions) (\c2 -> decodePyConjunctionToPyPrimary c2)) Nothing) _ -> Nothing -- | Decode an Inversion to a Primary if possible@@ -228,7 +228,7 @@ -- | Create a Primary with expression slices primaryWithExpressionSlices :: Syntax.Primary -> [Syntax.Expression] -> Syntax.Primary primaryWithExpressionSlices prim exprs =- Optionals.fromOptional prim (Optionals.map (\p -> primaryWithSlices prim (pyExpressionToPySlice (Pairs.first p)) (Lists.map (\e -> Syntax.SliceOrStarredExpressionSlice (pyExpressionToPySlice e)) (Pairs.second p))) (Lists.uncons exprs))+ Optionals.withDefault prim (Optionals.map (\p -> primaryWithSlices prim (pyExpressionToPySlice (Pairs.first p)) (Lists.map (\e -> Syntax.SliceOrStarredExpressionSlice (pyExpressionToPySlice e)) (Pairs.second p))) (Lists.uncons exprs)) -- | Combine a Primary with a PrimaryRhs primaryWithRhs :: Syntax.Primary -> Syntax.PrimaryRhs -> Syntax.Primary@@ -558,7 +558,7 @@ unionTypeClassStatements310 name mcomment tyexpr extraStmts = let nameStr = Syntax.unName name- metaName = Syntax.Name (Strings.cat2 (Strings.cat2 "_" nameStr) "Meta")+ metaName = Syntax.Name (Strings.concat2 (Strings.concat2 "_" nameStr) "Meta") docString = Serialization.printExpr (Serde.expressionToExpr tyexpr) returnObject = pySimpleStatementToPyStatement (Syntax.SimpleStatementReturn (Syntax.ReturnStatement [