rapydscript-ns 0.9.1 → 0.9.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (82) hide show
  1. package/CHANGELOG.md +22 -1
  2. package/PYTHON_GAPS.md +420 -0
  3. package/README.md +154 -30
  4. package/TODO.md +22 -7
  5. package/language-service/index.js +241 -12
  6. package/language-service/language-service.d.ts +1 -1
  7. package/memory/project_string_impl.md +43 -0
  8. package/package.json +6 -2
  9. package/release/baselib-plain-pretty.js +248 -38
  10. package/release/baselib-plain-ugly.js +8 -8
  11. package/release/compiler.js +821 -305
  12. package/release/signatures.json +15 -15
  13. package/src/ast.pyj +4 -1
  14. package/src/baselib-builtins.pyj +56 -2
  15. package/src/baselib-containers.pyj +2 -0
  16. package/src/baselib-errors.pyj +7 -3
  17. package/src/baselib-internal.pyj +51 -6
  18. package/src/baselib-str.pyj +5 -3
  19. package/src/lib/asyncio.pyj +534 -0
  20. package/src/lib/base64.pyj +399 -0
  21. package/src/lib/bisect.pyj +73 -0
  22. package/src/lib/collections.pyj +1 -1
  23. package/src/lib/csv.pyj +494 -0
  24. package/src/lib/heapq.pyj +98 -0
  25. package/src/lib/html.pyj +382 -0
  26. package/src/lib/http/__init__.pyj +98 -0
  27. package/src/lib/http/client.pyj +304 -0
  28. package/src/lib/http/cookies.pyj +236 -0
  29. package/src/lib/logging.pyj +672 -0
  30. package/src/lib/pythonize.pyj +1 -1
  31. package/src/lib/string.pyj +357 -0
  32. package/src/lib/textwrap.pyj +329 -0
  33. package/src/lib/urllib/__init__.pyj +14 -0
  34. package/src/lib/urllib/error.pyj +66 -0
  35. package/src/lib/urllib/parse.pyj +475 -0
  36. package/src/lib/urllib/request.pyj +86 -0
  37. package/src/monaco-language-service/analyzer.js +5 -2
  38. package/src/monaco-language-service/completions.js +26 -0
  39. package/src/monaco-language-service/diagnostics.js +204 -5
  40. package/src/monaco-language-service/index.js +2 -2
  41. package/src/monaco-language-service/scope.js +1 -0
  42. package/src/output/functions.pyj +152 -6
  43. package/src/output/loops.pyj +26 -2
  44. package/src/output/modules.pyj +1 -1
  45. package/src/output/operators.pyj +15 -0
  46. package/src/output/stream.pyj +0 -1
  47. package/src/parse.pyj +80 -17
  48. package/src/tokenizer.pyj +1 -1
  49. package/test/async_generators.pyj +144 -0
  50. package/test/asyncio.pyj +307 -0
  51. package/test/base64.pyj +202 -0
  52. package/test/bisect.pyj +178 -0
  53. package/test/csv.pyj +405 -0
  54. package/test/float_special.pyj +64 -0
  55. package/test/heapq.pyj +174 -0
  56. package/test/html.pyj +212 -0
  57. package/test/http.pyj +259 -0
  58. package/test/imports.pyj +7 -0
  59. package/test/logging.pyj +356 -0
  60. package/test/long.pyj +130 -0
  61. package/test/parenthesized_with.pyj +141 -0
  62. package/test/python_compat.pyj +3 -5
  63. package/test/python_modulo.pyj +76 -0
  64. package/test/python_modulo_off.pyj +21 -0
  65. package/test/str.pyj +14 -0
  66. package/test/string.pyj +245 -0
  67. package/test/textwrap.pyj +172 -0
  68. package/test/type_display.pyj +48 -0
  69. package/test/type_enforcement.pyj +164 -0
  70. package/test/unit/index.js +80 -6
  71. package/test/unit/language-service-completions.js +119 -0
  72. package/test/unit/language-service-scope.js +32 -0
  73. package/test/unit/language-service.js +128 -4
  74. package/test/unit/run-language-service.js +17 -3
  75. package/test/unit/web-repl.js +2094 -29
  76. package/test/urllib.pyj +193 -0
  77. package/tools/compile.js +1 -1
  78. package/tools/compiler.d.ts +367 -0
  79. package/tools/embedded_compiler.js +7 -7
  80. package/web-repl/main.js +1 -1
  81. package/web-repl/rapydscript.js +3 -3
  82. package/test/omit_function_metadata.pyj +0 -20
@@ -0,0 +1,672 @@
1
+ ###########################################################
2
+ # RapydScript Standard Library
3
+ # License: Apache License 2.0
4
+ # This library is covered under Apache license, so that
5
+ # you can distribute it with your RapydScript applications.
6
+ ###########################################################
7
+
8
+ # Python-compatible logging module.
9
+ #
10
+ # Provides: getLogger, basicConfig, debug, info, warning, error, critical,
11
+ # exception, log, disable, addLevelName, getLevelName,
12
+ # captureWarnings, makeLogRecord, setLogRecordFactory,
13
+ # getLogRecordFactory, Logger, Handler, StreamHandler,
14
+ # FileHandler, NullHandler, Formatter, Filter, LogRecord,
15
+ # NOTSET, DEBUG, INFO, WARNING, WARN, ERROR, CRITICAL, FATAL,
16
+ # lastResort, root.
17
+ #
18
+ # Notes:
19
+ # - FileHandler raises NotImplementedError (no file I/O in JS environments).
20
+ # - StreamHandler writes to console by default (debug→console.debug,
21
+ # info→console.info, warning→console.warn, error/critical→console.error).
22
+ # Pass a stream with a .write(s) method to capture output.
23
+ # - Logger hierarchy (dotted names, propagation) is fully supported.
24
+ # - exception() logs at ERROR level without automatic exc_info capture.
25
+ # - basicConfig() may be called multiple times; pass force=True to reconfigure.
26
+
27
+ # ---------------------------------------------------------------------------
28
+ # Level constants
29
+ # ---------------------------------------------------------------------------
30
+
31
+ NOTSET = 0
32
+ DEBUG = 10
33
+ INFO = 20
34
+ WARNING = 30
35
+ WARN = WARNING
36
+ ERROR = 40
37
+ CRITICAL = 50
38
+ FATAL = CRITICAL
39
+
40
+ _level_to_name = {}
41
+ _level_to_name[NOTSET] = 'NOTSET'
42
+ _level_to_name[DEBUG] = 'DEBUG'
43
+ _level_to_name[INFO] = 'INFO'
44
+ _level_to_name[WARNING] = 'WARNING'
45
+ _level_to_name[ERROR] = 'ERROR'
46
+ _level_to_name[CRITICAL] = 'CRITICAL'
47
+
48
+ _name_to_level = {}
49
+ _name_to_level['NOTSET'] = NOTSET
50
+ _name_to_level['DEBUG'] = DEBUG
51
+ _name_to_level['INFO'] = INFO
52
+ _name_to_level['WARNING'] = WARNING
53
+ _name_to_level['WARN'] = WARNING
54
+ _name_to_level['ERROR'] = ERROR
55
+ _name_to_level['CRITICAL'] = CRITICAL
56
+ _name_to_level['FATAL'] = CRITICAL
57
+
58
+
59
+ def getLevelName(level):
60
+ if jstype(level) is 'number':
61
+ return _level_to_name[level] if level in _level_to_name else ('Level ' + level)
62
+ if jstype(level) is 'string':
63
+ uname = level.toUpperCase()
64
+ return _name_to_level[uname] if uname in _name_to_level else None
65
+ return None
66
+
67
+
68
+ def addLevelName(level, name):
69
+ _level_to_name[level] = name
70
+ _name_to_level[name.toUpperCase()] = level
71
+
72
+
73
+ def _check_level(level):
74
+ if jstype(level) is 'string':
75
+ uname = level.toUpperCase()
76
+ if uname not in _name_to_level:
77
+ raise ValueError('Unknown level: ' + level)
78
+ return _name_to_level[uname]
79
+ if jstype(level) is 'number':
80
+ return level
81
+ raise TypeError('Level must be a string or integer')
82
+
83
+
84
+ # ---------------------------------------------------------------------------
85
+ # Internal JS helpers
86
+ # ---------------------------------------------------------------------------
87
+
88
+ v"""
89
+ var _logging_start_time = Date.now();
90
+
91
+ // %-style message formatting: %s %d %i %f %e %g %x %o %%
92
+ function _logging_fmt_msg(tmpl, args) {
93
+ var i = 0, n = args ? args.length : 0;
94
+ return String(tmpl).replace(/%([sdifFeEgGxo%])/g, function(m, c) {
95
+ if (c === '%') return '%';
96
+ if (i >= n) return m;
97
+ var a = args[i++];
98
+ if (c === 'd' || c === 'i') return String(Math.trunc(Number(a)));
99
+ if (c === 'f' || c === 'F') return Number(a).toFixed(6);
100
+ if (c === 'e') return Number(a).toExponential();
101
+ if (c === 'E') return Number(a).toExponential().toUpperCase();
102
+ if (c === 'g' || c === 'G') return String(Number(a));
103
+ if (c === 'x') return Math.trunc(Number(a)).toString(16);
104
+ if (c === 'o') return Math.trunc(Number(a)).toString(8);
105
+ return String(a);
106
+ });
107
+ }
108
+
109
+ // %(attr)s / %(attr)d / %(attr)f style format for Formatter
110
+ function _logging_format_record(fmt, record) {
111
+ return fmt.replace(/%\((\w+)\)(?:[-+# 0]*\d*(?:\.\d+)?)([sdifFeEgGxo%])/g,
112
+ function(match, key, conv) {
113
+ if (conv === '%') return '%';
114
+ var val = record[key];
115
+ if (val === undefined || val === null) return '';
116
+ if (conv === 'd' || conv === 'i') return String(Math.trunc(Number(val)));
117
+ if (conv === 'f' || conv === 'F') {
118
+ var pm = match.match(/\.(\d+)[fF]/);
119
+ return Number(val).toFixed(pm ? parseInt(pm[1]) : 6);
120
+ }
121
+ if (conv === 'e') return Number(val).toExponential();
122
+ if (conv === 'E') return Number(val).toExponential().toUpperCase();
123
+ if (conv === 'g' || conv === 'G') return String(Number(val));
124
+ if (conv === 'x') return Math.trunc(Number(val)).toString(16);
125
+ if (conv === 'o') return Math.trunc(Number(val)).toString(8);
126
+ return String(val);
127
+ }
128
+ );
129
+ }
130
+
131
+ // Route to the right console method based on level number
132
+ function _logging_console_emit(levelno, msg) {
133
+ if (typeof console === 'undefined') return;
134
+ if (levelno >= 40) {
135
+ console.error(msg);
136
+ } else if (levelno >= 30) {
137
+ console.warn(msg);
138
+ } else if (levelno >= 20) {
139
+ console.info(msg);
140
+ } else {
141
+ console.debug(msg);
142
+ }
143
+ }
144
+
145
+ // Format a timestamp from record.created (seconds since epoch)
146
+ function _logging_iso_time(created, datefmt) {
147
+ var d = new Date(created * 1000);
148
+ function pad2(n) { return n < 10 ? '0' + n : String(n); }
149
+ function pad3(n) { return n < 10 ? '00' + n : (n < 100 ? '0' + n : String(n)); }
150
+ if (datefmt) {
151
+ return datefmt
152
+ .replace('%Y', d.getFullYear())
153
+ .replace('%m', pad2(d.getMonth() + 1))
154
+ .replace('%d', pad2(d.getDate()))
155
+ .replace('%H', pad2(d.getHours()))
156
+ .replace('%M', pad2(d.getMinutes()))
157
+ .replace('%S', pad2(d.getSeconds()))
158
+ .replace('%f', pad3(d.getMilliseconds()) + '000');
159
+ }
160
+ return d.getFullYear() + '-' + pad2(d.getMonth() + 1) + '-' + pad2(d.getDate()) + ' ' +
161
+ pad2(d.getHours()) + ':' + pad2(d.getMinutes()) + ':' + pad2(d.getSeconds()) + ',' +
162
+ pad3(d.getMilliseconds());
163
+ }
164
+
165
+ // Safe kwargs accessor — handles plain JS objects and ρσ_dict (web-repl mode)
166
+ function _logging_kwget(kw, key, dflt) {
167
+ if (kw && kw.jsmap && typeof kw.jsmap.get === 'function') {
168
+ return kw.jsmap.has(key) ? kw.jsmap.get(key) : dflt;
169
+ }
170
+ return (kw && kw[key] !== undefined) ? kw[key] : dflt;
171
+ }
172
+ """
173
+
174
+
175
+ # ---------------------------------------------------------------------------
176
+ # LogRecord
177
+ # ---------------------------------------------------------------------------
178
+
179
+ class LogRecord:
180
+ def __init__(self, name, level, pathname, lineno, msg, args, exc_info, func=None):
181
+ self.name = name
182
+ self.levelno = level
183
+ self.levelname = _level_to_name[level] if level in _level_to_name else ('Level ' + level)
184
+ self.pathname = pathname or ''
185
+ self.filename = pathname or ''
186
+ self.module = ''
187
+ self.funcName = func or '(unknown)'
188
+ self.lineno = lineno or 0
189
+ self.msg = msg
190
+ self.args = args
191
+ self.exc_info = exc_info
192
+ self.exc_text = None
193
+ self.stack_info = None
194
+ now = v'Date.now()'
195
+ self.created = now / 1000.0
196
+ self.msecs = now % 1000
197
+ self.relativeCreated = now - v'_logging_start_time'
198
+ self.thread = 0
199
+ self.threadName = 'MainThread'
200
+ self.process = 0
201
+ self.processName = 'MainProcess'
202
+ self.message = ''
203
+
204
+ def getMessage(self):
205
+ msg = str(self.msg)
206
+ msg = v'_logging_fmt_msg(msg, this.args)'
207
+ return msg
208
+
209
+
210
+ _log_record_factory = LogRecord
211
+
212
+
213
+ def makeLogRecord(d):
214
+ rv = LogRecord('', 0, '', 0, '', None, None)
215
+ v"""
216
+ var _src = (d && d.jsmap) ? (function(){
217
+ var o = {}; d.jsmap.forEach(function(v,k){ o[k]=v; }); return o;
218
+ })() : (d || {});
219
+ var _ks = Object.keys(_src);
220
+ for (var _i = 0; _i < _ks.length; _i++) { rv[_ks[_i]] = _src[_ks[_i]]; }
221
+ """
222
+ return rv
223
+
224
+
225
+ def setLogRecordFactory(factory):
226
+ global _log_record_factory
227
+ _log_record_factory = factory
228
+
229
+
230
+ def getLogRecordFactory():
231
+ return _log_record_factory
232
+
233
+
234
+ def _make_log_record(name, level, msg, args, exc_info=None):
235
+ return _log_record_factory(name, level, '', 0, msg, args, exc_info)
236
+
237
+
238
+ # ---------------------------------------------------------------------------
239
+ # Filter / Filterer
240
+ # ---------------------------------------------------------------------------
241
+
242
+ class Filter:
243
+ def __init__(self, name=''):
244
+ self.name = name
245
+ self.nlen = name.length
246
+
247
+ def filter(self, record):
248
+ if self.nlen == 0:
249
+ return True
250
+ if record.name == self.name:
251
+ return True
252
+ return record.name.startsWith(self.name + '.')
253
+
254
+
255
+ class Filterer:
256
+ def __init__(self):
257
+ self.filters = []
258
+
259
+ def addFilter(self, fltr):
260
+ if self.filters.indexOf(fltr) < 0:
261
+ self.filters.push(fltr)
262
+
263
+ def removeFilter(self, fltr):
264
+ idx = self.filters.indexOf(fltr)
265
+ if idx >= 0:
266
+ self.filters.splice(idx, 1)
267
+
268
+ def filter(self, record):
269
+ for f in self.filters:
270
+ result = True
271
+ if hasattr(f, 'filter'):
272
+ result = f.filter(record)
273
+ elif jstype(f) is 'function':
274
+ result = f(record)
275
+ if not result:
276
+ return False
277
+ return True
278
+
279
+
280
+ # ---------------------------------------------------------------------------
281
+ # Formatter
282
+ # ---------------------------------------------------------------------------
283
+
284
+ _DEFAULT_FMT = '%(levelname)s:%(name)s:%(message)s'
285
+ _DEFAULT_DATEFMT = None
286
+
287
+
288
+ class Formatter:
289
+ def __init__(self, fmt=None, datefmt=None, style='%', validate=True):
290
+ self._fmt = fmt if fmt is not None else _DEFAULT_FMT
291
+ self.datefmt = datefmt
292
+ self._style = style
293
+
294
+ def format(self, record):
295
+ record.message = record.getMessage()
296
+ if self._fmt.indexOf('%(asctime)') >= 0:
297
+ record.asctime = self.formatTime(record, self.datefmt)
298
+ s = v'_logging_format_record(this._fmt, record)'
299
+ if record.exc_info and not record.exc_text:
300
+ record.exc_text = self.formatException(record.exc_info)
301
+ if record.exc_text:
302
+ if s and not s.endsWith('\n'):
303
+ s += '\n'
304
+ s += record.exc_text
305
+ if record.stack_info:
306
+ if s and not s.endsWith('\n'):
307
+ s += '\n'
308
+ s += self.formatStack(record.stack_info)
309
+ return s
310
+
311
+ def formatTime(self, record, datefmt=None):
312
+ return v'_logging_iso_time(record.created, datefmt)'
313
+
314
+ def formatException(self, exc_info):
315
+ if exc_info is None:
316
+ return ''
317
+ exc = exc_info[1] if Array.isArray(exc_info) and exc_info.length > 1 else exc_info
318
+ if exc is None:
319
+ return ''
320
+ if hasattr(exc, 'stack'):
321
+ return str(exc.stack)
322
+ return str(exc)
323
+
324
+ def formatStack(self, stack_info):
325
+ return str(stack_info)
326
+
327
+ def usesTime(self):
328
+ return self._fmt.indexOf('%(asctime)') >= 0
329
+
330
+
331
+ # ---------------------------------------------------------------------------
332
+ # Handler
333
+ # ---------------------------------------------------------------------------
334
+
335
+ class Handler(Filterer):
336
+ def __init__(self, level=NOTSET):
337
+ Filterer.__init__(self)
338
+ self.level = _check_level(level)
339
+ self._name = None
340
+ self.formatter = None
341
+
342
+ def setLevel(self, level):
343
+ self.level = _check_level(level)
344
+
345
+ def setFormatter(self, fmt):
346
+ self.formatter = fmt
347
+
348
+ def format(self, record):
349
+ if self.formatter is not None:
350
+ return self.formatter.format(record)
351
+ return _default_formatter.format(record)
352
+
353
+ def emit(self, record):
354
+ raise NotImplementedError('Handler subclasses must implement emit()')
355
+
356
+ def handle(self, record):
357
+ if not self.filter(record):
358
+ return False
359
+ self.emit(record)
360
+ return True
361
+
362
+ def handleError(self, record):
363
+ pass
364
+
365
+ def close(self):
366
+ pass
367
+
368
+ def createLock(self):
369
+ pass
370
+
371
+ def acquire(self):
372
+ pass
373
+
374
+ def release(self):
375
+ pass
376
+
377
+
378
+ class StreamHandler(Handler):
379
+ def __init__(self, stream=None):
380
+ Handler.__init__(self)
381
+ self.stream = stream
382
+
383
+ def emit(self, record):
384
+ try:
385
+ msg = self.format(record)
386
+ if self.stream is not None:
387
+ self.stream.write(msg + '\n')
388
+ else:
389
+ _logging_console_emit(record.levelno, msg)
390
+ except Exception:
391
+ self.handleError(record)
392
+
393
+ def flush(self):
394
+ pass
395
+
396
+
397
+ class FileHandler(StreamHandler):
398
+ def __init__(self, filename, mode='a', encoding=None, delay=False):
399
+ raise NotImplementedError('FileHandler is not available in JS environments; use StreamHandler with a custom stream instead')
400
+
401
+
402
+ class NullHandler(Handler):
403
+ def emit(self, record):
404
+ pass
405
+
406
+ def handle(self, record):
407
+ pass
408
+
409
+ def createLock(self):
410
+ pass
411
+
412
+
413
+ # ---------------------------------------------------------------------------
414
+ # Default formatter / last-resort handler (initialised after class defs)
415
+ # ---------------------------------------------------------------------------
416
+
417
+ _default_formatter = Formatter()
418
+
419
+
420
+ class _LastResortHandler(StreamHandler):
421
+ def __init__(self):
422
+ StreamHandler.__init__(self)
423
+ self.level = WARNING
424
+
425
+ def emit(self, record):
426
+ msg = record.getMessage()
427
+ _logging_console_emit(record.levelno,
428
+ record.levelname + ':' + record.name + ':' + msg)
429
+
430
+
431
+ lastResort = _LastResortHandler()
432
+
433
+
434
+ # ---------------------------------------------------------------------------
435
+ # Logger
436
+ # ---------------------------------------------------------------------------
437
+
438
+ _manager_loggers = {}
439
+ _disable_level = NOTSET
440
+
441
+
442
+ class Logger(Filterer):
443
+ def __init__(self, name, level=NOTSET):
444
+ Filterer.__init__(self)
445
+ self.name = name
446
+ self.level = _check_level(level)
447
+ self.parent = None
448
+ self.propagate = True
449
+ self.handlers = []
450
+ self.disabled = False
451
+
452
+ def setLevel(self, level):
453
+ self.level = _check_level(level)
454
+
455
+ def isEnabledFor(self, level):
456
+ if self.disabled:
457
+ return False
458
+ if level <= _disable_level:
459
+ return False
460
+ return level >= self.getEffectiveLevel()
461
+
462
+ def getEffectiveLevel(self):
463
+ logger = self
464
+ while logger is not None:
465
+ if logger.level != NOTSET:
466
+ return logger.level
467
+ logger = logger.parent
468
+ return WARNING
469
+
470
+ def addHandler(self, hdlr):
471
+ if self.handlers.indexOf(hdlr) < 0:
472
+ self.handlers.push(hdlr)
473
+
474
+ def removeHandler(self, hdlr):
475
+ idx = self.handlers.indexOf(hdlr)
476
+ if idx >= 0:
477
+ self.handlers.splice(idx, 1)
478
+
479
+ def hasHandlers(self):
480
+ c = self
481
+ while c is not None:
482
+ if c.handlers.length > 0:
483
+ return True
484
+ if not c.propagate:
485
+ break
486
+ c = c.parent
487
+ return False
488
+
489
+ def callHandlers(self, record):
490
+ c = self
491
+ found = 0
492
+ while c is not None:
493
+ for hdlr in c.handlers:
494
+ found += 1
495
+ if record.levelno >= hdlr.level:
496
+ hdlr.handle(record)
497
+ if not c.propagate:
498
+ c = None
499
+ else:
500
+ c = c.parent
501
+ if found == 0 and lastResort is not None:
502
+ if record.levelno >= lastResort.level:
503
+ lastResort.handle(record)
504
+
505
+ def handle(self, record):
506
+ if self.disabled:
507
+ return
508
+ if not self.filter(record):
509
+ return
510
+ self.callHandlers(record)
511
+
512
+ def _log(self, level, msg, args, exc_info=None, stack_info=None):
513
+ record = _make_log_record(self.name, level, msg, args, exc_info)
514
+ record.stack_info = stack_info
515
+ self.handle(record)
516
+
517
+ def debug(self, msg, *args):
518
+ if self.isEnabledFor(DEBUG):
519
+ self._log(DEBUG, msg, args)
520
+
521
+ def info(self, msg, *args):
522
+ if self.isEnabledFor(INFO):
523
+ self._log(INFO, msg, args)
524
+
525
+ def warning(self, msg, *args):
526
+ if self.isEnabledFor(WARNING):
527
+ self._log(WARNING, msg, args)
528
+
529
+ def warn(self, msg, *args):
530
+ if self.isEnabledFor(WARNING):
531
+ self._log(WARNING, msg, args)
532
+
533
+ def error(self, msg, *args):
534
+ if self.isEnabledFor(ERROR):
535
+ self._log(ERROR, msg, args)
536
+
537
+ def critical(self, msg, *args):
538
+ if self.isEnabledFor(CRITICAL):
539
+ self._log(CRITICAL, msg, args)
540
+
541
+ def fatal(self, msg, *args):
542
+ if self.isEnabledFor(CRITICAL):
543
+ self._log(CRITICAL, msg, args)
544
+
545
+ def exception(self, msg, *args):
546
+ self._log(ERROR, msg, args)
547
+
548
+ def log(self, level, msg, *args):
549
+ lvl = _check_level(level)
550
+ if self.isEnabledFor(lvl):
551
+ self._log(lvl, msg, args)
552
+
553
+
554
+ # ---------------------------------------------------------------------------
555
+ # Root logger and hierarchy
556
+ # ---------------------------------------------------------------------------
557
+
558
+ root = Logger('root', WARNING)
559
+ root.parent = None
560
+
561
+
562
+ def _fix_up_parents(alogger):
563
+ name = alogger.name
564
+ i = name.lastIndexOf('.')
565
+ rv = None
566
+ while i > 0 and rv is None:
567
+ substr = name.slice(0, i)
568
+ if substr in _manager_loggers:
569
+ rv = _manager_loggers[substr]
570
+ i = substr.lastIndexOf('.')
571
+ alogger.parent = rv if rv is not None else root
572
+
573
+
574
+ def getLogger(name=None):
575
+ if name is None or name == '' or name == 'root':
576
+ return root
577
+ if name in _manager_loggers:
578
+ return _manager_loggers[name]
579
+ logger = Logger(name)
580
+ _manager_loggers[name] = logger
581
+ _fix_up_parents(logger)
582
+ return logger
583
+
584
+
585
+ def disable(level=CRITICAL):
586
+ global _disable_level
587
+ _disable_level = _check_level(level)
588
+
589
+
590
+ # ---------------------------------------------------------------------------
591
+ # Module-level convenience functions
592
+ # ---------------------------------------------------------------------------
593
+
594
+ def debug(msg, *args):
595
+ if root.isEnabledFor(DEBUG):
596
+ root._log(DEBUG, msg, args)
597
+
598
+
599
+ def info(msg, *args):
600
+ if root.isEnabledFor(INFO):
601
+ root._log(INFO, msg, args)
602
+
603
+
604
+ def warning(msg, *args):
605
+ if root.isEnabledFor(WARNING):
606
+ root._log(WARNING, msg, args)
607
+
608
+
609
+ def warn(msg, *args):
610
+ if root.isEnabledFor(WARNING):
611
+ root._log(WARNING, msg, args)
612
+
613
+
614
+ def error(msg, *args):
615
+ if root.isEnabledFor(ERROR):
616
+ root._log(ERROR, msg, args)
617
+
618
+
619
+ def critical(msg, *args):
620
+ if root.isEnabledFor(CRITICAL):
621
+ root._log(CRITICAL, msg, args)
622
+
623
+
624
+ def exception(msg, *args):
625
+ root._log(ERROR, msg, args)
626
+
627
+
628
+ def log(level, msg, *args):
629
+ lvl = _check_level(level)
630
+ if root.isEnabledFor(lvl):
631
+ root._log(lvl, msg, args)
632
+
633
+
634
+ def captureWarnings(capture):
635
+ pass
636
+
637
+
638
+ # ---------------------------------------------------------------------------
639
+ # basicConfig
640
+ # ---------------------------------------------------------------------------
641
+
642
+ _basic_config_done = False
643
+
644
+
645
+ def basicConfig(**kwargs):
646
+ global _basic_config_done
647
+ force = v'_logging_kwget(kwargs, "force", false)'
648
+ if _basic_config_done and not force:
649
+ return
650
+ if force:
651
+ root.handlers = []
652
+
653
+ level = v'_logging_kwget(kwargs, "level", null)'
654
+ fmt = v'_logging_kwget(kwargs, "format", null)'
655
+ datefmt = v'_logging_kwget(kwargs, "datefmt", null)'
656
+ stream = v'_logging_kwget(kwargs, "stream", null)'
657
+ handlers_arg = v'_logging_kwget(kwargs, "handlers", null)'
658
+
659
+ if handlers_arg is not None:
660
+ for h in handlers_arg:
661
+ if h.formatter is None and (fmt is not None or datefmt is not None):
662
+ h.setFormatter(Formatter(fmt, datefmt))
663
+ root.addHandler(h)
664
+ elif root.handlers.length == 0:
665
+ h = StreamHandler(stream)
666
+ h.setFormatter(Formatter(fmt, datefmt))
667
+ root.addHandler(h)
668
+
669
+ if level is not None:
670
+ root.setLevel(level)
671
+
672
+ _basic_config_done = True
@@ -9,7 +9,7 @@ def strings():
9
9
  ' partition rpartition replace split rsplit splitlines zfill expandtabs').split(' '))
10
10
 
11
11
  if not arguments.length:
12
- exclude = {'split', 'replace'}
12
+ exclude = {'split'}
13
13
  elif arguments[0]:
14
14
  exclude = Array.prototype.slice.call(arguments)
15
15
  else: