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
|
"""
Global state initialized at import time.
Used for hidden arguments and developer features.
"""
import os
import sys
from types import ModuleType
from line_profiler import _logger
def _boolean_environ(
envvar,
truey=frozenset({'1', 'on', 'true', 'yes'}),
falsy=frozenset({'0', 'off', 'false', 'no'}),
default=False):
r"""
Args:
envvar (str)
Name for the environment variable to read from.
truey (Collection[str])
Values to be considered truey.
falsy (Collection[str])
Values to be considered falsy.
default (bool)
Default boolean value to resolve to.
Returns:
:py:data:`True`
If the (case-normalized) environment variable is equal to
any of ``truey``.
:py:data:`False`
If the (case-normalized) environment variable is equal to
any of ``falsy``.
``default``
Otherwise.
Example:
>>> from os import environ
>>> from subprocess import run
>>> from sys import executable
>>> from textwrap import dedent
>>>
>>>
>>> def resolve_in_subproc(value, default,
... envvar='MY_ENVVAR',
... truey=('foo',), falsy=('bar',)):
... code = dedent('''
... from {0.__module__} import {0.__name__}
... print({0.__name__}({1!r}, {2!r}, {3!r}, {4!r}))
... ''').strip('\n').format(_boolean_environ, envvar,
... tuple(truey), tuple(falsy),
... bool(default))
... env = environ.copy()
... env[envvar] = value
... proc = run([executable, '-c', code],
... capture_output=True, env=env, text=True)
... proc.check_returncode()
... return {'True': True,
... 'False': False}[proc.stdout.strip()]
...
>>>
>>> # Truey value
>>> assert resolve_in_subproc('FOO', True) == True
>>> assert resolve_in_subproc('FOO', False) == True
>>> # Falsy value
>>> assert resolve_in_subproc('BaR', True) == False
>>> assert resolve_in_subproc('BaR', False) == False
>>> # Mismatch -> fall back to default
>>> assert resolve_in_subproc('baz', True) == True
>>> assert resolve_in_subproc('baz', False) == False
"""
# (TODO: migrate to `line_profiler.cli_utils.boolean()` after
# merging #335)
try:
value = os.environ.get(envvar).casefold()
except AttributeError: # None
return default
non_default_values = falsy if default else truey
if value in {v.casefold() for v in non_default_values}:
return not default
return default
# `kernprof` switches
DEBUG = _boolean_environ('LINE_PROFILER_DEBUG')
NO_EXEC = _boolean_environ('LINE_PROFILER_NO_EXEC')
KEEP_TEMPDIRS = _boolean_environ('LINE_PROFILER_KEEP_TEMPDIRS')
STATIC_ANALYSIS = _boolean_environ('LINE_PROFILER_STATIC_ANALYSIS')
# `line_profiler._line_profiler` switches
WRAP_TRACE = _boolean_environ('LINE_PROFILER_WRAP_TRACE')
SET_FRAME_LOCAL_TRACE = _boolean_environ('LINE_PROFILER_SET_FRAME_LOCAL_TRACE')
_MUST_USE_LEGACY_TRACE = not isinstance(
getattr(sys, 'monitoring', None), ModuleType)
USE_LEGACY_TRACE = (
_MUST_USE_LEGACY_TRACE
or _boolean_environ('LINE_PROFILER_CORE',
# Also provide `coverage-style` aliases
truey={'old', 'legacy', 'ctrace'},
falsy={'new', 'sys.monitoring', 'sysmon'},
default=_MUST_USE_LEGACY_TRACE))
log = _logger.Logger('line_profiler', backend='auto')
|