1
1
import re
2
2
import subprocess
3
3
from _typeshed import Incomplete , Self
4
+ from builtins import range as _range
4
5
from collections import OrderedDict
5
- from collections .abc import Callable , Generator , Iterator
6
+ from collections .abc import Callable , Generator , Iterable , Iterator
7
+ from datetime import datetime
6
8
from logging import Logger
7
9
from types import TracebackType
8
10
from typing import Any
9
- from typing_extensions import SupportsIndex
11
+ from typing_extensions import SupportsIndex , TypeAlias
10
12
11
13
from cronlog import CronLog
12
14
15
+ _User : TypeAlias = str | bool | None
16
+
13
17
__pkgname__ : str
14
18
ITEMREX : re .Pattern [str ]
15
19
SPECREX : re .Pattern [str ]
@@ -28,18 +32,19 @@ CRON_COMMAND: str
28
32
SHELL : str
29
33
current_user : Callable [[], str | None ]
30
34
31
- def open_pipe (cmd : str , * args : str , ** flags ) -> subprocess .Popen [Any ]: ...
35
+ def open_pipe (cmd : str , * args : str , ** flags : str ) -> subprocess .Popen [Any ]: ...
32
36
33
37
class CronTab :
34
- lines : Incomplete
35
- crons : list [CronItem ]
38
+ lines : list [ str | CronItem ] | None
39
+ crons : list [CronItem ] | None
36
40
filen : str | None
37
- cron_command : Incomplete
38
- env : OrderedVariableList
41
+ cron_command : str
42
+ env : OrderedVariableList | None
39
43
root : bool
40
44
intab : str | None
45
+ tabfile : str | None
41
46
def __init__ (
42
- self , user : bool | str | None = ..., tab : str | None = ..., tabfile : str | None = ..., log : str | None = ...
47
+ self , user : _User = ..., tab : str | None = ..., tabfile : str | None = ..., log : CronLog | str | None = ...
43
48
) -> None : ...
44
49
def __enter__ (self : Self ) -> Self : ...
45
50
def __exit__ (
@@ -48,7 +53,7 @@ class CronTab:
48
53
@property
49
54
def log (self ) -> CronLog : ...
50
55
@property
51
- def user (self ) -> str | None : ...
56
+ def user (self ) -> _User : ...
52
57
@property
53
58
def user_opt (self ) -> dict [str , str ]: ...
54
59
def read (self , filename : str | None = ...) -> None : ...
@@ -59,11 +64,14 @@ class CronTab:
59
64
read : bool = ...,
60
65
before : str | re .Pattern [str ] | list [CronItem ] | tuple [CronItem , ...] | Generator [CronItem , Any , Any ] | None = ...,
61
66
) -> None : ...
62
- def write (self , filename : str | None = ..., user : bool | str | None = ..., errors : bool = ...) -> None : ...
67
+ def write (self , filename : str | None = ..., user : _User = ..., errors : bool = ...) -> None : ...
63
68
def write_to_user (self , user : bool | str = ...) -> None : ...
64
- def run_pending (self , ** kwargs ) -> Generator [Incomplete , None , None ]: ...
65
- def run_scheduler (self , timeout : int = ..., ** kwargs ) -> Generator [Incomplete , None , None ]: ...
66
- def render (self , errors : bool = ..., specials : bool = ...) -> str : ...
69
+ # Usually `kwargs` are just `now: datetime | None`, but technically this can
70
+ # work for `CronItem` subclasses, which might define other kwargs.
71
+ def run_pending (self , ** kwargs : Any ) -> Iterator [str ]: ...
72
+ # There are two known kwargs and others are unused:
73
+ def run_scheduler (self , timeout : int = ..., * , warp : object = ..., cadence : int = ..., ** kwargs : object ) -> Iterator [str ]: ...
74
+ def render (self , errors : bool = ..., specials : bool | None = ...) -> str : ...
67
75
def new (
68
76
self ,
69
77
command : str = ...,
@@ -72,97 +80,104 @@ class CronTab:
72
80
pre_comment : bool = ...,
73
81
before : str | re .Pattern [str ] | list [CronItem ] | tuple [CronItem , ...] | Generator [CronItem , Any , Any ] | None = ...,
74
82
) -> CronItem : ...
75
- def find_command (self , command : str | re .Pattern [str ]) -> Generator [CronItem , None , None ]: ...
76
- def find_comment (self , comment : str | re .Pattern [str ]) -> Generator [CronItem , None , None ]: ...
77
- def find_time (self , * args ) -> Generator [CronItem , None , None ]: ...
83
+ def find_command (self , command : str | re .Pattern [str ]) -> Iterator [CronItem ]: ...
84
+ def find_comment (self , comment : str | re .Pattern [str ]) -> Iterator [CronItem ]: ...
85
+ def find_time (self , * args : Any ) -> Iterator [CronItem ]: ...
78
86
@property
79
- def commands (self ) -> Generator [ Incomplete , None , None ]: ...
87
+ def commands (self ) -> Iterator [ str ]: ...
80
88
@property
81
- def comments (self ) -> Generator [Incomplete , None , None ]: ...
82
- def remove_all (self , * , command : str | re .Pattern [str ] = ..., comment : str | re .Pattern [str ] = ..., time = ...) -> int : ...
83
- def remove (self , * items : CronItem | list [CronItem ] | tuple [CronItem , ...] | Generator [CronItem , Any , Any ]) -> int : ...
89
+ def comments (self ) -> Iterator [str ]: ...
90
+ # You cannot actually pass `*args`, it will raise an exception,
91
+ # also known kwargs are added:
92
+ def remove_all (
93
+ self , * , command : str | re .Pattern [str ] = ..., comment : str | re .Pattern [str ] = ..., time : Any = ..., ** kwargs : object
94
+ ) -> int : ...
95
+ def remove (self , * items : CronItem | Iterable [CronItem ]) -> int : ...
84
96
def __iter__ (self ) -> Iterator [CronItem ]: ...
85
97
def __getitem__ (self , i : SupportsIndex ) -> CronItem : ...
86
98
def __len__ (self ) -> int : ...
87
99
88
100
class CronItem :
89
- cron : Incomplete
90
- user : str | None
101
+ cron : CronTab | None
102
+ user : _User
91
103
valid : bool
92
104
enabled : bool
93
105
special : bool
94
- comment : Incomplete
95
- command : Incomplete
96
- last_run : Incomplete
97
- env : Incomplete
106
+ comment : str
107
+ command : str | None
108
+ last_run : datetime | None
109
+ env : OrderedVariableList
98
110
pre_comment : bool
99
- marker : Incomplete
100
- stdin : Incomplete
101
- slices : Incomplete
102
- def __init__ (self , command : str = ..., comment : str = ..., user : str | None = ..., pre_comment : bool = ...) -> None : ...
111
+ marker : str | None
112
+ stdin : str | None
113
+ slices : CronSlices
114
+ def __init__ (self , command : str = ..., comment : str = ..., user : _User = ..., pre_comment : bool = ...) -> None : ...
103
115
def __hash__ (self ) -> int : ...
104
116
def __eq__ (self , other : object ) -> bool : ...
105
117
@classmethod
106
118
def from_line (cls : type [Self ], line : str , user : str | None = ..., cron : Incomplete | None = ...) -> Self : ...
107
119
def delete (self ) -> None : ...
108
120
def set_command (self , cmd : str , parse_stdin : bool = ...) -> None : ...
109
121
def set_comment (self , cmt : str , pre_comment : bool = ...) -> None : ...
110
- def parse (self , line ) -> None : ...
122
+ def parse (self , line : str ) -> None : ...
111
123
def enable (self , enabled : bool = ...) -> bool : ...
112
124
def is_enabled (self ) -> bool : ...
113
125
def is_valid (self ) -> bool : ...
114
126
def render (self , specials : bool = ...) -> str : ...
115
- def every_reboot (self ): ...
116
- def every (self , unit : int = ...): ...
117
- def setall (self , * args : Any ): ...
118
- def clear (self ): ...
127
+ def every_reboot (self ) -> None : ...
128
+ def every (self , unit : int = ...) -> Every : ...
129
+ def setall (self , * args : Any ) -> None : ...
130
+ def clear (self ) -> None : ...
119
131
def frequency (self , year : int | None = ...) -> int : ...
120
132
def frequency_per_year (self , year : int | None = ...) -> int : ...
121
133
def frequency_per_day (self ) -> int : ...
122
134
def frequency_per_hour (self ) -> int : ...
123
- def run_pending (self , now : Incomplete | None = ...): ...
124
- def run (self ): ...
125
- def schedule (self , date_from : Incomplete | None = ...): ...
126
- def description (self , ** kw : Any ): ...
135
+ def run_pending (self , now : datetime | None = ...) -> int | str : ...
136
+ def run (self ) -> str : ...
137
+ # TODO: use types from `croniter` module here:
138
+ def schedule (self , date_from : datetime | None = ...) -> Incomplete : ...
139
+ # TODO: use types from `cron_descriptor` here:
140
+ def description (self , ** kw : Incomplete ) -> Incomplete : ...
127
141
@property
128
- def log (self ): ...
142
+ def log (self ) -> CronLog : ...
129
143
@property
130
- def minute (self ) -> CronSlice : ...
144
+ def minute (self ) -> int | str : ...
131
145
@property
132
- def minutes (self ) -> CronSlice : ...
146
+ def minutes (self ) -> int | str : ...
133
147
@property
134
- def hour (self ) -> CronSlice : ...
148
+ def hour (self ) -> int | str : ...
135
149
@property
136
- def hours (self ) -> CronSlice : ...
150
+ def hours (self ) -> int | str : ...
137
151
@property
138
- def day (self ) -> CronSlice : ...
152
+ def day (self ) -> int | str : ...
139
153
@property
140
- def dom (self ) -> CronSlice : ...
154
+ def dom (self ) -> int | str : ...
141
155
@property
142
- def month (self ) -> CronSlice : ...
156
+ def month (self ) -> int | str : ...
143
157
@property
144
- def months (self ) -> CronSlice : ...
158
+ def months (self ) -> int | str : ...
145
159
@property
146
- def dow (self ) -> CronSlice : ...
160
+ def dow (self ) -> int | str : ...
147
161
def __len__ (self ) -> int : ...
148
- def __getitem__ (self , key : SupportsIndex ) -> CronSlice : ...
149
- def __lt__ (self , value ) -> bool : ...
150
- def __gt__ (self , value ) -> bool : ...
162
+ def __getitem__ (self , key : int | str ) -> int | str : ...
163
+ def __lt__ (self , value : object ) -> bool : ...
164
+ def __gt__ (self , value : object ) -> bool : ...
151
165
152
166
class Every :
153
- slices : Incomplete
154
- unit : Incomplete
155
- def __init__ (self , item , units ) -> None : ...
167
+ slices : CronSlices
168
+ unit : int
169
+ # TODO: add generated attributes
170
+ def __init__ (self , item : CronSlices , units : int ) -> None : ...
156
171
def set_attr (self , target : int ) -> Callable [[], None ]: ...
157
172
def year (self ) -> None : ...
158
173
159
174
class CronSlices (list [CronSlice ]):
160
- special : Incomplete
175
+ special : bool | None
161
176
def __init__ (self , * args : Any ) -> None : ...
162
177
def is_self_valid (self , * args : Any ) -> bool : ...
163
178
@classmethod
164
179
def is_valid (cls , * args : Any ) -> bool : ...
165
- def setall (self , * slices ) -> None : ...
180
+ def setall (self , * slices : str ) -> None : ...
166
181
def clean_render (self ) -> str : ...
167
182
def render (self , specials : bool = ...) -> str : ...
168
183
def clear (self ) -> None : ...
@@ -175,64 +190,72 @@ class CronSlices(list[CronSlice]):
175
190
class SundayError (KeyError ): ...
176
191
177
192
class Also :
178
- obj : Incomplete
179
- def __init__ (self , obj ) -> None : ...
180
- def every (self , * a ): ...
181
- def on (self , * a ): ...
182
- def during (self , * a ): ...
193
+ obj : CronSlice
194
+ def __init__ (self , obj : CronSlice ) -> None : ...
195
+ # These method actually use `*args`, but pass them to `CronSlice` methods,
196
+ # this is why they are typed as `Any`.
197
+ def every (self , * a : Any ) -> _Part : ...
198
+ def on (self , * a : Any ) -> list [_Part ]: ...
199
+ def during (self , * a : Any ) -> _Part : ...
200
+
201
+ _Part : TypeAlias = int | CronValue | CronRange
183
202
184
203
class CronSlice :
185
- min : Incomplete
186
- max : Incomplete
187
- name : Incomplete
188
- enum : Incomplete
189
- parts : Incomplete
190
- def __init__ (self , info , value : Incomplete | None = ...) -> None : ...
204
+ min : int | None
205
+ max : int | None
206
+ name : str | None
207
+ enum : list [ str | None ] | None
208
+ parts : list [ _Part ]
209
+ def __init__ (self , info : int | dict [ str , Any ], value : str | None = ...) -> None : ...
191
210
def __hash__ (self ) -> int : ...
192
- def parse (self , value ) -> None : ...
193
- def render (self , resolve : bool = ..., specials : bool = ...): ...
211
+ def parse (self , value : str | None ) -> None : ...
212
+ def render (self , resolve : bool = ..., specials : bool = ...) -> str : ...
194
213
def __eq__ (self , arg : object ) -> bool : ...
195
- def every (self , n_value , also : bool = ...): ...
196
- def on (self , * n_value , ** opts ): ...
197
- def during (self , vfrom , vto , also : bool = ...): ...
214
+ def every (self , n_value : int , also : bool = ...) -> _Part : ...
215
+ # The only known kwarg, others are unused,
216
+ # `*args`` are passed to `parse_value`, so they are `Any`
217
+ def on (self , * n_value : Any , also : bool = ...) -> list [_Part ]: ...
218
+ def during (self , vfrom : int | str , vto : int | str , also : bool = ...) -> _Part : ...
198
219
@property
199
- def also (self ): ...
220
+ def also (self ) -> Also : ...
200
221
def clear (self ) -> None : ...
201
- def get_range (self , * vrange ) : ...
202
- def __iter__ (self ): ...
222
+ def get_range (self , * vrange : int | str | CronValue ) -> list [ int | CronRange ] : ...
223
+ def __iter__ (self ) -> Iterator [ int ] : ...
203
224
def __len__ (self ) -> int : ...
204
- def parse_value (self , val , sunday : Incomplete | None = ...): ...
225
+ def parse_value (self , val : str , sunday : int | None = ...) -> int | CronValue : ...
205
226
206
- def get_cronvalue (value , enums ) : ...
227
+ def get_cronvalue (value : int , enums : list [ str ]) -> int | CronValue : ...
207
228
208
229
class CronValue :
209
- text : Incomplete
210
- value : Incomplete
211
- def __init__ (self , value , enums ) -> None : ...
212
- def __lt__ (self , value ) : ...
230
+ text : str
231
+ value : int
232
+ def __init__ (self , value : str , enums : list [ str ] ) -> None : ...
233
+ def __lt__ (self , value : object ) -> bool : ...
213
234
def __int__ (self ) -> int : ...
214
235
215
236
class CronRange :
216
- dangling : Incomplete
217
- slice : Incomplete
218
- cron : Incomplete
237
+ dangling : int | None
238
+ slice : str
239
+ cron : CronTab | None
219
240
seq : int
220
- def __init__ (self , vslice , * vrange ) -> None : ...
221
- vfrom : Incomplete
222
- vto : Incomplete
223
- def parse (self , value ) -> None : ...
241
+ def __init__ (self , vslice : str , * vrange : int | str | CronValue ) -> None : ...
242
+ # Are not set in `__init__`:
243
+ vfrom : int | CronValue
244
+ vto : int | CronValue
245
+ def parse (self , value : str ) -> None : ...
224
246
def all (self ) -> None : ...
225
- def render (self , resolve : bool = ...): ...
226
- def range (self ): ...
227
- def every (self , value ) -> None : ...
228
- def __lt__ (self , value ) : ...
229
- def __gt__ (self , value ) : ...
247
+ def render (self , resolve : bool = ...) -> str : ...
248
+ def range (self ) -> _range : ...
249
+ def every (self , value : int | str ) -> None : ...
250
+ def __lt__ (self , value : object ) -> bool : ...
251
+ def __gt__ (self , value : object ) -> bool : ...
230
252
def __int__ (self ) -> int : ...
231
253
254
+ # TODO: make generic
232
255
class OrderedVariableList (OrderedDict [Incomplete , Incomplete ]):
233
256
job : Incomplete
234
257
def __init__ (self , * args : Any , ** kw : Any ) -> None : ...
235
258
@property
236
- def previous (self ): ...
237
- def all (self ) : ...
238
- def __getitem__ (self , key ) : ...
259
+ def previous (self ) -> Incomplete : ...
260
+ def all (self : Self ) -> Self : ...
261
+ def __getitem__ (self , key : Incomplete ) -> Incomplete : ...
0 commit comments