-
Notifications
You must be signed in to change notification settings - Fork 326
Expand file tree
/
Copy pathPython.AST.fs
More file actions
1513 lines (1334 loc) · 44.8 KB
/
Copy pathPython.AST.fs
File metadata and controls
1513 lines (1334 loc) · 44.8 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
// Python AST based on https://docs.python.org/3/library/ast.html. Currently uses records instead of tagged unions to
// better match with the Python AST docs.
namespace rec Fable.Transforms.Python.AST
// fsharplint:disable MemberNames InterfaceNames
open Fable.AST
open Fable.Transforms.Python.AST
/// Pattern types for Python 3.10+ match statements (PEP 634)
/// https://docs.python.org/3/library/ast.html#match-statements
type Pattern =
/// A match literal or constant pattern, e.g. `case 1:` or `case "hello":`
| MatchValue of value: Expression
/// A match singleton pattern, e.g. `case True:`, `case False:`, or `case None:`
| MatchSingleton of value: Literal
/// A match sequence pattern, e.g. `case [x, y, z]:`
| MatchSequence of patterns: Pattern list
/// A match mapping pattern, e.g. `case {"key": value}:`
| MatchMapping of keys: Expression list * patterns: Pattern list * rest: Identifier option
/// A match class pattern, e.g. `case Point(x=0, y=0):`
| MatchClass of cls: Expression * patterns: Pattern list * kwdAttrs: Identifier list * kwdPatterns: Pattern list
/// A match star pattern (capture rest), e.g. `case [first, *rest]:`
| MatchStar of name: Identifier option
/// A match as pattern (capture with optional pattern), e.g. `case _ as x:` or `case x:`
| MatchAs of pattern: Pattern option * name: Identifier option
/// A match or pattern, e.g. `case 1 | 2 | 3:`
| MatchOr of patterns: Pattern list
/// A single case in a match statement
type MatchCase =
{
Pattern: Pattern
Guard: Expression option
Body: Statement list
}
/// A match statement (Python 3.10+, PEP 634)
/// ```py
/// match subject:
/// case pattern1:
/// ...
/// case pattern2 if guard:
/// ...
/// ```
type Match =
{
Subject: Expression
Cases: MatchCase list
Loc: SourceLocation option
}
/// Type parameters introduced in Python 3.12 (PEP 695)
type TypeParam =
| TypeVar of TypeVarParam
| ParamSpec of ParamSpecParam
| TypeVarTuple of TypeVarTupleParam
/// TypeVar type parameter with optional bound and default value
type TypeVarParam =
{
Name: Identifier
Bound: Expression option
DefaultValue: Expression option
Loc: SourceLocation option
}
/// ParamSpec type parameter for parameter specifications
type ParamSpecParam =
{
Name: Identifier
DefaultValue: Expression option
Loc: SourceLocation option
}
/// TypeVarTuple type parameter for variable-length tuple types
type TypeVarTupleParam =
{
Name: Identifier
DefaultValue: Expression option
Loc: SourceLocation option
}
/// Type alias statement introduced in Python 3.12 (PEP 695)
type TypeAlias =
{
Name: Expression
TypeParams: TypeParam list
Value: Expression
Loc: SourceLocation option
}
/// https://docs.python.org/3/library/ast.html#expressions
type Expression =
| Attribute of Attribute
| Subscript of Subscript
| BoolOp of BoolOp
| BinOp of BinOp
| Await of Expression
/// A yield from expression. Because these are expressions, they must be wrapped in a Expr node if the value sent
/// back is not used.
| YieldFrom of Expression option
/// A yield expression. Because these are expressions, they must be wrapped in a Expr node if the value sent back is
/// not used.
| Yield of Expression option
| Emit of Emit
| IfExp of IfExp
| UnaryOp of UnaryOp
| FormattedValue of FormattedValue
/// A constant value. The value attribute of the Constant literal contains the Python object it represents. The
/// values represented can be simple types such as a number, string or None, but also immutable container types
/// (tuples and frozensets) if all of their elements are constant.
| Constant of value: Literal * loc: SourceLocation option
| Call of Call
| Compare of Compare
| Lambda of Lambda
| NamedExpr of NamedExpr
/// A variable name. id holds the name as a string, and ctx is one of the following types.
| Name of Name
| Dict of Dict
| Tuple of Tuple
| Starred of value: Expression * ctx: ExpressionContext
| List of elts: Expression list * ctx: ExpressionContext
| Slice of lower: Expression option * upper: Expression option * step: Expression option
type Literal =
| FloatLiteral of float
| IntLiteral of obj
| BoolLiteral of bool
| BytesLiteral of byte array
| StringLiteral of string
| NoneLiteral
| TupleLiteral of Literal list
| FrozensetLiteral of Literal list
[<Struct>]
type Operator =
| Add
| Sub
| Mult
| Div
| FloorDiv
| Mod
| Pow
| LShift
| RShift
| BitOr
| BitXor
| BitAnd
| MatMult
[<Struct>]
type BoolOperator =
| And
| Or
[<Struct>]
type ComparisonOperator =
| Eq
| NotEq
| Lt
| LtE
| Gt
| GtE
| Is
| IsNot
| In
| NotIn
[<Struct>]
type UnaryOperator =
| Invert
| Not
| UAdd
| USub
[<Struct>]
type ExpressionContext =
| Load
| Del
| Store
[<Struct>]
type Identifier =
| Identifier of name: string
member this.Name =
let (Identifier name) = this
name
/// https://docs.python.org/3/library/ast.html#statements
type Statement =
| Pass
| Break
| Continue
| If of If
| For of For
| Try of Try
| Expr of Expr
| With of With
| Match of Match
| While of While
| Raise of Raise
| Import of Import
| Assert of Assert
| Assign of Assign
| Return of Return
| Global of Global
| NonLocal of NonLocal
| ClassDef of ClassDef
| AsyncFor of AsyncFor
| AnnAssign of AnnAssign
| TypeAlias of TypeAlias
| ImportFrom of ImportFrom
| FunctionDef of FunctionDef
| AsyncFunctionDef of AsyncFunctionDef
type Module =
{
Body: Statement list
Comment: string option
}
/// Both parameters are raw strings of the names. asname can be None if the regular name is to be used.
///
/// ```py
/// >>> print(ast.dump(ast.parse('from ..foo.bar import a as b, c'), indent=4))
/// Module(
/// body=[
/// ImportFrom(
/// module='foo.bar',
/// names=[
/// alias(name='a', asname='b'),
/// alias(name='c')],
/// level=2)],
/// type_ignores=[])
/// ```
type Alias =
{
Name: Identifier
AsName: Identifier option
}
/// A single except clause. type is the exception type it will match, typically a Name node (or None for a catch-all
/// except: clause). name is a raw string for the name to hold the exception, or None if the clause doesn't have as foo.
/// body is a list of nodes.
type ExceptHandler =
{
Type: Expression option
Name: Identifier option
Body: Statement list
Loc: SourceLocation option
}
/// try blocks. All attributes are list of nodes to execute, except for handlers, which is a list of ExceptHandler
/// nodes.
type Try =
{
Body: Statement list
Handlers: ExceptHandler list
OrElse: Statement list
FinalBody: Statement list
Loc: SourceLocation option
}
/// A single context manager in a with block. context_expr is the context manager, often a Call node. optional_vars is a
/// Name, Tuple or List for the as foo part, or None if that isn't used.
type WithItem =
{
ContextExpr: Expression
OptionalVars: Expression option
}
/// A with block. items is a list of withitem nodes representing the context managers, and body is the indented block
/// inside the context.
type With =
{
Items: WithItem list
Body: Statement list
TypeComment: string option
}
/// A single argument in a list. arg is a raw string of the argument name, annotation is its annotation, such as a Str
/// or Name node.
///
/// - type_comment is an optional string with the type annotation as a comment
type Arg =
{
Lineno: int
ColOffset: int
EndLineno: int option
EndColOffset: int option
Arg: Identifier
Annotation: Expression option
TypeComment: string option
}
type Keyword =
{
Lineno: int
ColOffset: int
EndLineno: int option
EndColOffset: int option
Arg: Identifier
Value: Expression
}
/// The arguments for a function.
///
/// - posonlyargs, args and kwonlyargs are lists of arg nodes.
/// - vararg and kwarg are single arg nodes, referring to the *args, **kwargs parameters.
/// - kwDefaults is a list of default values for keyword-only arguments. If one is None, the corresponding argument is
/// required.
/// - defaults is a list of default values for arguments that can be passed positionally. If there are fewer defaults,
/// they correspond to the last n arguments.
type Arguments =
{
PosOnlyArgs: Arg list // https://www.python.org/dev/peps/pep-0570/
Args: Arg list
VarArg: Arg option
KwOnlyArgs: Arg list
KwDefaults: Expression list
KwArg: Arg option
Defaults: Expression list
}
//#region Statements
/// An assignment. targets is a list of nodes, and value is a single node.
///
/// Multiple nodes in targets represents assigning the same value to each. Unpacking is represented by putting a Tuple
/// or List within targets.
///
/// type_comment is an optional string with the type annotation as a comment.
/// https://docs.python.org/3/library/ast.html#ast.Assign
type Assign =
{
Targets: Expression list
Value: Expression
TypeComment: string option
}
/// An assignment with a type annotation. target is a single node and can be a Name, a Attribute or a Subscript.
/// annotation is the annotation, such as a Constant or Name node. value is a single optional node. simple is a
/// boolean integer set to True for a Name node in target that do not appear in between parenthesis and are hence
/// pure names and not expressions.
/// https://docs.python.org/3/library/ast.html#ast.AnnAssign
type AnnAssign =
{
Target: Expression
Value: Expression option
Annotation: Expression
Simple: bool
}
/// When an expression, such as a function call, appears as a statement by itself with its return value not used or
/// stored, it is wrapped in this container. value holds one of the other nodes in this section, a Constant, a Name, a
/// Lambda, a Yield or YieldFrom node.
type Expr = { Value: Expression }
/// A for loop. target holds the variable(s) the loop assigns to, as a single Name, Tuple or List node. iter holds the
/// item to be looped over, again as a single node. body and orelse contain lists of nodes to execute. Those in orelse
/// are executed if the loop finishes normally, rather than via a break statement.
///
/// type_comment is an optional string with the type annotation as a comment.
type For =
{
Target: Expression
Iterator: Expression
Body: Statement list
Else: Statement list
TypeComment: string option
}
type AsyncFor =
{
Target: Expression
Iterator: Expression
Body: Statement list
Else: Statement list
TypeComment: string option
}
/// A while loop. test holds the condition, such as a Compare node.
type While =
{
Test: Expression
Body: Statement list
Else: Statement list
Loc: SourceLocation option
}
/// A class definition.
///
/// - name is a raw string for the class name
/// - bases is a list of nodes for explicitly specified base classes.
/// - keywords is a list of keyword nodes, principally for 'metaclass'. Other keywords will be passed to the metaclass,
/// as per PEP-3115.
/// - starargs and kwargs are each a single node, as in a function call. starargs will be expanded to join the list of
/// base classes, and kwargs will be passed to the metaclass.
/// - body is a list of nodes representing the code within the class definition.
/// - decorator_list is a list of nodes, as in FunctionDef.
///
/// ```py
/// >>> print(ast.dump(ast.parse("""\
/// ... @decorator1
/// ... @decorator2
/// ... class Foo(base1, base2, metaclass=meta):
/// ... pass
/// ... """), indent=4))
/// Module(
/// body=[
/// ClassDef(
/// name='Foo',
/// bases=[
/// Name(id='base1', ctx=Load()),
/// Name(id='base2', ctx=Load())],
/// keywords=[
/// keyword(
/// arg='metaclass',
/// value=Name(id='meta', ctx=Load()))],
/// body=[
/// Pass()],
/// decorator_list=[
/// Name(id='decorator1', ctx=Load()),
/// Name(id='decorator2', ctx=Load())])],
/// type_ignores=[])
///```
type ClassDef =
{
Name: Identifier
Bases: Expression list
Keywords: Keyword list
Body: Statement list
DecoratorList: Expression list
TypeParams: TypeParam list
Loc: SourceLocation option
}
/// An if statement. test holds a single node, such as a Compare node. body and orelse each hold a list of nodes.
///
/// elif clauses don't have a special representation in the AST, but rather appear as extra If nodes within the orelse
/// section of the previous one.
///
/// ```py
/// >>> print(ast.dump(ast.parse("""
/// ... if x:
/// ... ...
/// ... elif y:
/// ... ...
/// ... else:
/// ... ...
/// ... """), indent=4))
/// Module(
/// body=[
/// If(
/// test=Name(id='x', ctx=Load()),
/// body=[
/// Expr(
/// value=Constant(value=Ellipsis))],
/// orelse=[
/// If(
/// test=Name(id='y', ctx=Load()),
/// body=[
/// Expr(
/// value=Constant(value=Ellipsis))],
/// orelse=[
/// Expr(
/// value=Constant(value=Ellipsis))])])],
/// type_ignores=[])
/// ```
type If =
{
Test: Expression
Body: Statement list
Else: Statement list
Loc: SourceLocation option
}
/// A raise statement. exc is the exception object to be raised, normally a Call or Name, or None for a standalone
/// raise. cause is the optional part for y in raise x from y.
///
/// ```py
/// >>> print(ast.dump(ast.parse('raise x from y'), indent=4))
/// Module(
/// body=[
/// Raise(
/// exc=Name(id='x', ctx=Load()),
/// cause=Name(id='y', ctx=Load()))],
/// type_ignores=[])
/// ```
type Raise =
{
Exception: Expression
Cause: Expression option
}
static member Create(exc, ?cause) : Statement =
{
Exception = exc
Cause = cause
}
|> Raise
/// A function definition.
///
/// - name is a raw string of the function name.
/// - args is a arguments node.
/// - body is the list of nodes inside the function.
/// - decorator_list is the list of decorators to be applied, stored outermost first (i.e. the first in the list will be
/// applied last).
/// - returns is the return annotation.
/// - type_comment is an optional string with the type annotation as a comment.
type FunctionDef =
{
Name: Identifier
Args: Arguments
Body: Statement list
DecoratorList: Expression list
Returns: Expression option
TypeComment: string option
Comment: string option
TypeParams: TypeParam list
}
/// global and nonlocal statements. names is a list of raw strings.
///
/// ```py
/// >>> print(ast.dump(ast.parse('global x,y,z'), indent=4))
/// Module(
/// body=[
/// Global(
/// names=[
/// 'x',
/// 'y',
/// 'z'])],
/// type_ignores=[])
///
/// ```
type Global =
{
Names: Identifier list
}
static member Create(names) = { Names = names }
/// global and nonlocal statements. names is a list of raw strings.
///
/// ```py
/// >>> print(ast.dump(ast.parse('nonlocal x,y,z'), indent=4))
/// Module(
/// body=[
/// Nonlocal(
/// names=[
/// 'x',
/// 'y',
/// 'z'])],
/// type_ignores=[])
/// `````
type NonLocal =
{
Names: Identifier list
}
static member Create(names) = { Names = names }
/// An async function definition.
///
/// - name is a raw string of the function name.
/// - args is a arguments node.
/// - body is the list of nodes inside the function.
/// - decorator_list is the list of decorators to be applied, stored outermost first (i.e. the first in the list will be
/// applied last).
/// - returns is the return annotation.
/// - type_comment is an optional string with the type annotation as a comment.
type AsyncFunctionDef =
{
Name: Identifier
Args: Arguments
Body: Statement list
DecoratorList: Expression list
Returns: Expression option
TypeComment: string option
Comment: string option
TypeParams: TypeParam list
}
static member Create(name, args, body, decoratorList, ?returns, ?typeComment, ?comment, ?typeParams) =
{
Name = name
Args = args
Body = body
DecoratorList = decoratorList
Returns = returns
TypeComment = typeComment
Comment = comment
TypeParams = defaultArg typeParams []
}
/// An import statement. names is a list of alias nodes.
///
/// ```py
/// >>> print(ast.dump(ast.parse('import x,y,z'), indent=4))
/// Module(
/// body=[
/// Import(
/// names=[
/// alias(name='x'),
/// alias(name='y'),
/// alias(name='z')])],
/// type_ignores=[])
/// `````
type Import = { Names: Alias list }
/// An assertion. test holds the condition, such as a Compare node. msg holds the failure message.
type Assert =
{
Test: Expression
Msg: Expression option
}
/// Represents from x import y. module is a raw string of the 'from' name, without any leading dots, or None for
/// statements such as from . import foo. level is an integer holding the level of the relative import (0 means absolute
/// import).
///
/// ```py
/// >>> print(ast.dump(ast.parse('from y import x,y,z'), indent=4))
/// Module(
/// body=[
/// ImportFrom(
/// module='y',
/// names=[
/// alias(name='x'),
/// alias(name='y'),
/// alias(name='z')],
/// level=0)],
/// type_ignores=[])
/// ```
type ImportFrom =
{
Module: Identifier option
Names: Alias list
Level: int option
}
/// A return statement.
///
/// ```py
/// >>> print(ast.dump(ast.parse('return 4'), indent=4))
/// Module(
/// body=[
/// Return(
/// value=Constant(value=4))],
/// type_ignores=[])
/// ```
type Return = { Value: Expression option }
//#endregion
//#region Expressions
/// Attribute access, e.g. d.keys. value is a node, typically a Name. attr is a bare string giving the name of the
/// attribute, and ctx is Load, Store or Del according to how the attribute is acted on.
///
/// ```py
/// >>> print(ast.dump(ast.parse('snake.colour', mode='eval'), indent=4))
/// Expression(
/// body=Attribute(
/// value=Name(id='snake', ctx=Load()),
/// attr='colour',
/// ctx=Load()))
/// ```
type Attribute =
{
Value: Expression
Attr: Identifier
Ctx: ExpressionContext
}
type NamedExpr =
{
Target: Expression
Value: Expression
Loc: SourceLocation option
}
/// A subscript, such as l[1]. value is the subscripted object (usually sequence or mapping). slice is an index, slice
/// or key. It can be a Tuple and contain a Slice. ctx is Load, Store or Del according to the action performed with the
/// subscript.
///
/// ```py
/// >>> print(ast.dump(ast.parse('l[1:2, 3]', mode='eval'), indent=4))
/// Expression(
/// body=Subscript(
/// value=Name(id='l', ctx=Load()),
/// slice=Tuple(
/// elts=[
/// Slice(
/// lower=Constant(value=1),
/// upper=Constant(value=2)),
/// Constant(value=3)],
/// ctx=Load()),
/// ctx=Load()))
/// ```
type Subscript =
{
Value: Expression
Slice: Expression
Ctx: ExpressionContext
}
type BinOp =
{
Left: Expression
Right: Expression
Operator: Operator
Loc: SourceLocation option
}
type BoolOp =
{
Values: Expression list
Operator: BoolOperator
Loc: SourceLocation option
}
/// A comparison of two or more values. left is the first value in the comparison, ops the list of operators, and
/// comparators the list of values after the first element in the comparison.
///
/// ```py
/// >>> print(ast.dump(ast.parse('1 <= a < 10', mode='eval'), indent=4))
/// Expression(
/// body=Compare(
/// left=Constant(value=1),
/// ops=[
/// LtE(),
/// Lt()],
/// comparators=[
/// Name(id='a', ctx=Load()),
/// Constant(value=10)]))
/// `````
type Compare =
{
Left: Expression
Comparators: Expression list
Ops: ComparisonOperator list
Loc: SourceLocation option
}
/// A unary operation. op is the operator, and operand any expression node.
type UnaryOp =
{
Op: UnaryOperator
Operand: Expression
Loc: SourceLocation option
}
/// Node representing a single formatting field in an f-string. If the string contains a single formatting field and
/// nothing else the node can be isolated otherwise it appears in JoinedStr.
///
/// - value is any expression node (such as a literal, a variable, or a function call).
/// - conversion is an integer:
/// - -1: no formatting
/// - 115: !s string formatting
/// - 114: !r repr formatting
/// - 97: !a ascii formatting
/// - format_spec is a JoinedStr node representing the formatting of the value, or None if no format was specified. Both
/// conversion and format_spec can be set at the same time.
type FormattedValue =
{
Value: Expression
Conversion: int option
FormatSpec: Expression option
}
/// A function call. func is the function, which will often be a Name or Attribute object. Of the arguments:
///
/// args holds a list of the arguments passed by position.
///
/// keywords holds a list of keyword objects representing arguments passed by keyword.
///
/// When creating a Call node, args and keywords are required, but they can be empty lists. starargs and kwargs are optional.
///
/// ```py
/// >>> print(ast.dump(ast.parse('func(a, b=c, *d, **e)', mode='eval'), indent=4))
/// Expression(
/// body=Call(
/// func=Name(id='func', ctx=Load()),
/// args=[
/// Name(id='a', ctx=Load()),
/// Starred(
/// value=Name(id='d', ctx=Load()),
/// ctx=Load())],
/// keywords=[
/// keyword(
/// arg='b',
/// value=Name(id='c', ctx=Load())),
/// keyword(
/// value=Name(id='e', ctx=Load()))]))
/// ```
type Call =
{
Func: Expression
Args: Expression list
Keywords: Keyword list
Loc: SourceLocation option
}
type Emit =
{
Value: string
Args: Expression list
Loc: SourceLocation option
}
/// An expression such as a if b else c. Each field holds a single node, so in the following example, all three are Name nodes.
///
/// ```py
/// >>> print(ast.dump(ast.parse('a if b else c', mode='eval'), indent=4))
/// Expression(
/// body=IfExp(
/// test=Name(id='b', ctx=Load()),
/// body=Name(id='a', ctx=Load()),
/// orelse=Name(id='c', ctx=Load())))
/// ```
type IfExp =
{
Test: Expression
Body: Expression
OrElse: Expression
Loc: SourceLocation option
}
/// lambda is a minimal function definition that can be used inside an expression. Unlike FunctionDef, body holds a
/// single node.
///
/// ```py
/// >>> print(ast.dump(ast.parse('lambda x,y: ...'), indent=4))
/// Module(
/// body=[
/// Expr(
/// value=Lambda(
/// args=arguments(
/// posonlyargs=[],
/// args=[
/// arg(arg='x'),
/// arg(arg='y')],
/// kwonlyargs=[],
/// kw_defaults=[],
/// defaults=[]),
/// body=Constant(value=Ellipsis)))],
/// type_ignores=[])
/// ```
type Lambda =
{
Args: Arguments
Body: Expression
}
/// A tuple. elts holds a list of nodes representing the elements. ctx is Store if the container is an assignment target
/// (i.e. (x,y)=something), and Load otherwise.
///
/// ```py
/// >>> print(ast.dump(ast.parse('(1, 2, 3)', mode='eval'), indent=4))
/// Expression(
/// body=Tuple(
/// elts=[
/// Constant(value=1),
/// Constant(value=2),
/// Constant(value=3)],
/// ctx=Load()))
///```
type Tuple =
{
Elements: Expression list
Loc: SourceLocation option
}
/// A list or tuple. elts holds a list of nodes representing the elements. ctx is Store if the container is an
/// assignment target (i.e. (x,y)=something), and Load otherwise.
///
/// ```python
/// >>> print(ast.dump(ast.parse('[1, 2, 3]', mode='eval'), indent=4))
/// Expression(
/// body=List(
/// elts=[
/// Constant(value=1),
/// Constant(value=2),
/// Constant(value=3)],
/// ctx=Load()))
///```
type List = { Elements: Expression list }
/// A set. elts holds a list of nodes representing the set's elements.
///
/// ```py
/// >>> print(ast.dump(ast.parse('{1, 2, 3}', mode='eval'), indent=4))
/// Expression(
/// body=Set(
/// elts=[
/// Constant(value=1),
/// Constant(value=2),
/// Constant(value=3)]))
/// ```
type Set = { Elements: Expression list }
/// A dictionary. keys and values hold lists of nodes representing the keys and the values respectively, in matching
/// order (what would be returned when calling dictionary.keys() and dictionary.values()).
///
/// When doing dictionary unpacking using dictionary literals the expression to be expanded goes in the values list,
/// with a None at the corresponding position in keys.
///
/// ```py
/// >>> print(ast.dump(ast.parse('{"a":1, **d}', mode='eval'), indent=4))
/// Expression(
/// body=Dict(
/// keys=[
/// Constant(value='a'),
/// None],
/// values=[
/// Constant(value=1),
/// Name(id='d', ctx=Load())]))
/// ```
type Dict =
{
Keys: Expression list
Values: Expression list
}
/// A variable name. id holds the name as a string, and ctx is one of the following types.
type Name =
{
Id: Identifier
Context: ExpressionContext
Loc: SourceLocation option
}
[<RequireQualifiedAccess>]
type AST =
| Expression of Expression
| Statement of Statement
| Operator of Operator
| BoolOperator of BoolOperator
| ComparisonOperator of ComparisonOperator
| UnaryOperator of UnaryOperator
| ExpressionContext of ExpressionContext
| Alias of Alias
| Module of Module
| Arguments of Arguments
| Keyword of Keyword
| Arg of Arg
| Identifier of Identifier
| WithItem of WithItem
[<AutoOpen>]
module PythonExtensions =
[<Literal>]
let Ellipsis = "..."
type Statement with
static member assert'(test, ?msg) : Statement =
{
Test = test
Msg = msg
}
|> Assert
static member break'() : Statement = Break
static member continue' ?loc : Statement = Continue
static member import(names) : Statement = Import { Names = names }
static member expr(value) : Statement = { Expr.Value = value } |> Expr
static member ellipsis: Statement = Statement.expr (Expression.ellipsis)
static member raise(value) : Statement =
{
Exception = value
Cause = None
}
|> Raise
static member try'(body, ?handlers, ?orElse, ?finalBody, ?loc) : Statement =
Try.try' (body, ?handlers = handlers, ?orElse = orElse, ?finalBody = finalBody, ?loc = loc)
|> Try
static member with'(items, ?body, ?typeComment) : Statement =
{
Items = items
Body = defaultArg body []
TypeComment = typeComment
}
|> With
static member classDef(name, ?bases, ?keywords, ?body, ?decoratorList, ?typeParams, ?loc) : Statement =
{
Name = name
Bases = defaultArg bases []
Keywords = defaultArg keywords []