71
71
import com .oracle .graal .python .nodes .ErrorMessages ;
72
72
import com .oracle .graal .python .nodes .PNodeWithContext ;
73
73
import com .oracle .graal .python .nodes .PRaiseNode ;
74
+ import com .oracle .graal .python .nodes .attributes .ReadAttributeFromDynamicObjectNode ;
74
75
import com .oracle .graal .python .nodes .function .PythonBuiltinBaseNode ;
75
76
import com .oracle .graal .python .nodes .function .PythonBuiltinNode ;
77
+ import com .oracle .graal .python .nodes .function .builtins .PythonBinaryBuiltinNode ;
76
78
import com .oracle .graal .python .nodes .function .builtins .PythonBinaryClinicBuiltinNode ;
79
+ import com .oracle .graal .python .nodes .function .builtins .PythonTernaryClinicBuiltinNode ;
77
80
import com .oracle .graal .python .nodes .function .builtins .PythonUnaryBuiltinNode ;
78
81
import com .oracle .graal .python .nodes .function .builtins .PythonUnaryClinicBuiltinNode ;
79
82
import com .oracle .graal .python .nodes .function .builtins .clinic .ArgumentClinicProvider ;
105
108
public final class TimeModuleBuiltins extends PythonBuiltins {
106
109
private static final int DELAY_NANOS = 10 ;
107
110
private static final String CTIME_FORMAT = "%s %s %2d %02d:%02d:%02d %d" ;
111
+ private static final ZoneId GMT = ZoneId .of ("GMT" );
108
112
113
+ private static final HiddenKey CURRENT_ZONE_ID = new HiddenKey ("currentZoneID" );
109
114
private static final HiddenKey TIME_SLEPT = new HiddenKey ("timeSlept" );
110
115
111
116
private static final StructSequence .BuiltinTypeDescriptor STRUCT_TIME_DESC = new StructSequence .BuiltinTypeDescriptor (
@@ -147,7 +152,11 @@ protected List<? extends NodeFactory<? extends PythonBuiltinBaseNode>> getNodeFa
147
152
@ Override
148
153
public void initialize (Python3Core core ) {
149
154
super .initialize (core );
150
- TimeZone defaultTimeZone = TimeZone .getTimeZone (core .getContext ().getEnv ().getTimeZone ());
155
+ // Should we read TZ env variable?
156
+ ZoneId defaultZoneId = core .getContext ().getEnv ().getTimeZone ();
157
+ core .lookupBuiltinModule ("time" ).setAttribute (CURRENT_ZONE_ID , defaultZoneId );
158
+
159
+ TimeZone defaultTimeZone = TimeZone .getTimeZone (defaultZoneId );
151
160
String noDaylightSavingZone = defaultTimeZone .getDisplayName (false , TimeZone .SHORT );
152
161
String daylightSavingZone = defaultTimeZone .getDisplayName (true , TimeZone .SHORT );
153
162
@@ -182,10 +191,9 @@ public static double timeSeconds() {
182
191
private static final int TM_ISDST = 8 ; /* daylight saving time */
183
192
184
193
@ TruffleBoundary
185
- private static Object [] getTimeStruct (PythonContext context , long seconds , boolean local ) {
194
+ private static Object [] getTimeStruct (ZoneId zone , long seconds ) {
186
195
Object [] timeStruct = new Object [11 ];
187
196
Instant instant = Instant .ofEpochSecond (seconds );
188
- ZoneId zone = (local ) ? context .getEnv ().getTimeZone () : ZoneId .of ("GMT" );
189
197
ZonedDateTime zonedDateTime = LocalDateTime .ofInstant (instant , zone ).atZone (zone );
190
198
timeStruct [TM_YEAR ] = zonedDateTime .getYear ();
191
199
timeStruct [TM_MON ] = zonedDateTime .getMonth ().ordinal () + 1 ; /* Want January == 1 */
@@ -204,10 +212,9 @@ private static Object[] getTimeStruct(PythonContext context, long seconds, boole
204
212
}
205
213
206
214
@ TruffleBoundary
207
- private static int [] getIntLocalTimeStruct (PythonContext context , long seconds ) {
215
+ private static int [] getIntLocalTimeStruct (ZoneId zone , long seconds ) {
208
216
int [] timeStruct = new int [9 ];
209
217
Instant instant = Instant .ofEpochSecond (seconds );
210
- ZoneId zone = context .getEnv ().getTimeZone ();
211
218
ZonedDateTime zonedDateTime = LocalDateTime .ofInstant (instant , zone ).atZone (zone );
212
219
timeStruct [TM_YEAR ] = zonedDateTime .getYear ();
213
220
timeStruct [TM_MON ] = zonedDateTime .getMonth ().ordinal () + 1 ; /* Want January == 1 */
@@ -285,20 +292,22 @@ public abstract static class PythonGMTimeNode extends PythonBuiltinNode {
285
292
@ Specialization
286
293
public PTuple gmtime (VirtualFrame frame , Object seconds ,
287
294
@ Cached ToLongTime toLongTime ) {
288
- return factory ().createStructSeq (STRUCT_TIME_DESC , getTimeStruct (PythonContext . get ( this ) , toLongTime .execute (frame , seconds ), false ));
295
+ return factory ().createStructSeq (STRUCT_TIME_DESC , getTimeStruct (GMT , toLongTime .execute (frame , seconds )));
289
296
}
290
297
}
291
298
292
299
// time.localtime([seconds])
293
- @ Builtin (name = "localtime" , maxNumOfPositionalArgs = 1 )
300
+ @ Builtin (name = "localtime" , maxNumOfPositionalArgs = 2 , declaresExplicitSelf = true )
294
301
@ GenerateNodeFactory
295
302
@ TypeSystemReference (PythonArithmeticTypes .class )
296
- public abstract static class PythonLocalTimeNode extends PythonBuiltinNode {
303
+ public abstract static class PythonLocalTimeNode extends PythonBinaryBuiltinNode {
297
304
298
305
@ Specialization
299
- public PTuple localtime (VirtualFrame frame , Object seconds ,
306
+ public PTuple localtime (VirtualFrame frame , PythonModule module , Object seconds ,
307
+ @ Cached ReadAttributeFromDynamicObjectNode readZoneId ,
300
308
@ Cached ToLongTime toLongTime ) {
301
- return factory ().createStructSeq (STRUCT_TIME_DESC , getTimeStruct (PythonContext .get (this ), toLongTime .execute (frame , seconds ), true ));
309
+ ZoneId zoneId = (ZoneId ) readZoneId .execute (module , CURRENT_ZONE_ID );
310
+ return factory ().createStructSeq (STRUCT_TIME_DESC , getTimeStruct (zoneId , toLongTime .execute (frame , seconds )));
302
311
}
303
312
}
304
313
@@ -551,10 +560,10 @@ public static SleepNode create() {
551
560
}
552
561
553
562
// time.strftime(format[, t])
554
- @ Builtin (name = "strftime" , minNumOfPositionalArgs = 1 , parameterNames = {"format" , "time" })
563
+ @ Builtin (name = "strftime" , minNumOfPositionalArgs = 2 , declaresExplicitSelf = true , parameterNames = {"$self" , "format" , "time" })
555
564
@ ArgumentClinic (name = "format" , conversion = ArgumentClinic .ClinicConversion .String )
556
565
@ GenerateNodeFactory
557
- public abstract static class StrfTimeNode extends PythonBinaryClinicBuiltinNode {
566
+ public abstract static class StrfTimeNode extends PythonTernaryClinicBuiltinNode {
558
567
@ Override
559
568
protected ArgumentClinicProvider getArgumentClinic () {
560
569
return StrfTimeNodeClinicProviderGen .INSTANCE ;
@@ -873,15 +882,17 @@ private static String format(String format, int[] date) {
873
882
}
874
883
875
884
@ Specialization
876
- public String formatTime (String format , @ SuppressWarnings ("unused" ) PNone time ) {
885
+ public String formatTime (PythonModule module , String format , @ SuppressWarnings ("unused" ) PNone time ,
886
+ @ Cached ReadAttributeFromDynamicObjectNode readZoneId ) {
877
887
if (format .indexOf (0 ) > -1 ) {
878
888
throw raise (PythonBuiltinClassType .ValueError , ErrorMessages .EMBEDDED_NULL_CHARACTER );
879
889
}
880
- return format (format , getIntLocalTimeStruct (PythonContext .get (this ), (long ) timeSeconds ()));
890
+ ZoneId zoneId = (ZoneId ) readZoneId .execute (module , CURRENT_ZONE_ID );
891
+ return format (format , getIntLocalTimeStruct (zoneId , (long ) timeSeconds ()));
881
892
}
882
893
883
894
@ Specialization
884
- public String formatTime (VirtualFrame frame , String format , PTuple time ,
895
+ public String formatTime (VirtualFrame frame , @ SuppressWarnings ( "unused" ) PythonModule module , String format , PTuple time ,
885
896
@ Cached SequenceStorageNodes .GetInternalObjectArrayNode getArray ,
886
897
@ Cached SequenceStorageNodes .LenNode lenNode ,
887
898
@ Cached PyNumberAsSizeNode asSizeNode ) {
@@ -893,53 +904,57 @@ public String formatTime(VirtualFrame frame, String format, PTuple time,
893
904
}
894
905
895
906
@ Specialization
896
- public String formatTime (@ SuppressWarnings ("unused" ) String format , @ SuppressWarnings ("unused" ) Object time ) {
907
+ @ SuppressWarnings ("unused" )
908
+ public String formatTime (PythonModule module , String format , Object time ) {
897
909
throw raise (PythonBuiltinClassType .TypeError , ErrorMessages .TUPLE_OR_STRUCT_TIME_ARG_REQUIRED );
898
910
}
899
911
}
900
912
901
- @ Builtin (name = "mktime" , minNumOfPositionalArgs = 1 , doc = "mktime(tuple) -> floating point number\n \n " +
913
+ @ Builtin (name = "mktime" , minNumOfPositionalArgs = 2 , declaresExplicitSelf = true , doc = "mktime(tuple) -> floating point number\n \n " +
902
914
"Convert a time tuple in local time to seconds since the Epoch.\n " +
903
915
"Note that mktime(gmtime(0)) will not generally return zero for most\n " +
904
916
"time zones; instead the returned value will either be equal to that\n " +
905
917
"of the timezone or altzone attributes on the time module." )
906
918
@ GenerateNodeFactory
907
- abstract static class MkTimeNode extends PythonUnaryBuiltinNode {
919
+ abstract static class MkTimeNode extends PythonBinaryBuiltinNode {
908
920
private static final int ELEMENT_COUNT = 9 ;
909
921
910
922
@ Specialization
911
923
@ ExplodeLoop
912
- double mktime (VirtualFrame frame , PTuple tuple ,
924
+ double mktime (VirtualFrame frame , PythonModule module , PTuple tuple ,
913
925
@ Cached PyNumberAsSizeNode asSizeNode ,
914
- @ Cached GetObjectArrayNode getObjectArrayNode ) {
926
+ @ Cached GetObjectArrayNode getObjectArrayNode ,
927
+ @ Cached ReadAttributeFromDynamicObjectNode readZoneId ) {
915
928
Object [] items = getObjectArrayNode .execute (tuple );
916
- if (items .length != 9 ) {
917
- throw raise (PythonBuiltinClassType .TypeError , ErrorMessages .FUNC_TAKES_EXACTLY_D_ARGS , 9 , items .length );
929
+ if (items .length != ELEMENT_COUNT ) {
930
+ throw raise (PythonBuiltinClassType .TypeError , ErrorMessages .FUNC_TAKES_EXACTLY_D_ARGS , ELEMENT_COUNT , items .length );
918
931
}
919
- int [] integers = new int [9 ];
932
+ int [] integers = new int [ELEMENT_COUNT ];
920
933
for (int i = 0 ; i < ELEMENT_COUNT ; i ++) {
921
934
integers [i ] = asSizeNode .executeExact (frame , items [i ]);
922
935
}
923
- return op (getContext (), integers );
936
+ ZoneId zoneId = (ZoneId ) readZoneId .execute (module , CURRENT_ZONE_ID );
937
+ return op (zoneId , integers );
924
938
}
925
939
926
940
@ TruffleBoundary
927
- private static long op (PythonContext context , int [] integers ) {
941
+ private static long op (ZoneId timeZone , int [] integers ) {
928
942
LocalDateTime localtime = LocalDateTime .of (integers [0 ], integers [1 ], integers [2 ], integers [3 ], integers [4 ], integers [5 ]);
929
- ZoneId timeZone = context .getEnv ().getTimeZone ();
930
943
return localtime .toEpochSecond (timeZone .getRules ().getOffset (localtime ));
931
944
}
932
945
}
933
946
934
947
// time.ctime([secs])
935
- @ Builtin (name = "ctime" , maxNumOfPositionalArgs = 1 )
948
+ @ Builtin (name = "ctime" , maxNumOfPositionalArgs = 2 , declaresExplicitSelf = true )
936
949
@ GenerateNodeFactory
937
- public abstract static class CTimeNode extends PythonBuiltinNode {
950
+ public abstract static class CTimeNode extends PythonBinaryBuiltinNode {
938
951
939
952
@ Specialization
940
- public String localtime (VirtualFrame frame , Object seconds ,
953
+ public static String localtime (VirtualFrame frame , PythonModule module , Object seconds ,
954
+ @ Cached ReadAttributeFromDynamicObjectNode readZoneId ,
941
955
@ Cached ToLongTime toLongTime ) {
942
- return format (getIntLocalTimeStruct (PythonContext .get (this ), toLongTime .execute (frame , seconds )));
956
+ ZoneId zoneId = (ZoneId ) readZoneId .execute (module , CURRENT_ZONE_ID );
957
+ return format (getIntLocalTimeStruct (zoneId , toLongTime .execute (frame , seconds )));
943
958
}
944
959
945
960
protected static String format (int [] tm ) {
@@ -948,9 +963,9 @@ protected static String format(int[] tm) {
948
963
}
949
964
950
965
// time.asctime([t])
951
- @ Builtin (name = "asctime" , maxNumOfPositionalArgs = 1 )
966
+ @ Builtin (name = "asctime" , maxNumOfPositionalArgs = 2 , declaresExplicitSelf = true )
952
967
@ GenerateNodeFactory
953
- public abstract static class ASCTimeNode extends PythonBuiltinNode {
968
+ public abstract static class ASCTimeNode extends PythonBinaryBuiltinNode {
954
969
955
970
static final String [] WDAY_NAME = new String []{
956
971
"Mon" , "Tue" , "Wed" , "Thu" , "Fri" , "Sat" , "Sun"
@@ -961,20 +976,23 @@ public abstract static class ASCTimeNode extends PythonBuiltinNode {
961
976
};
962
977
963
978
@ Specialization
964
- public String localtime (@ SuppressWarnings ("unused" ) PNone time ) {
965
- return format (getIntLocalTimeStruct (PythonContext .get (this ), (long ) timeSeconds ()));
979
+ public static String localtime (PythonModule module , @ SuppressWarnings ("unused" ) PNone time ,
980
+ @ Cached ReadAttributeFromDynamicObjectNode readZoneId ) {
981
+ ZoneId zoneId = (ZoneId ) readZoneId .execute (module , CURRENT_ZONE_ID );
982
+ return format (getIntLocalTimeStruct (zoneId , (long ) timeSeconds ()));
966
983
}
967
984
968
985
@ Specialization
969
- public String localtime (VirtualFrame frame , PTuple time ,
986
+ public String localtime (VirtualFrame frame , @ SuppressWarnings ( "unused" ) PythonModule module , PTuple time ,
970
987
@ Cached SequenceStorageNodes .GetInternalObjectArrayNode getArray ,
971
988
@ Cached SequenceStorageNodes .LenNode lenNode ,
972
989
@ Cached PyNumberAsSizeNode asSizeNode ) {
973
990
return format (StrfTimeNode .checkStructtime (frame , time , getArray , lenNode , asSizeNode , getRaiseNode ()));
974
991
}
975
992
976
993
@ Fallback
977
- public Object localtime (@ SuppressWarnings ("unused" ) Object time ) {
994
+ @ SuppressWarnings ("unused" )
995
+ public Object localtime (Object module , Object time ) {
978
996
throw raise (TypeError , ErrorMessages .TUPLE_OR_STRUCT_TIME_ARG_REQUIRED );
979
997
}
980
998
0 commit comments