aerosandbox.tools.inspect_tools#

Module Contents#

Functions#

get_caller_source_location([stacklevel])

Gets the file location where this function itself (get_caller_source_location()) is called.

get_source_code_from_location(filename, lineno[, ...])

Gets the source code of the single statement that begins at the file location specified.

get_caller_source_code([stacklevel, strip_lines])

Gets the source code of wherever this function is called.

get_function_argument_names_from_source_code(source_code)

Gets the names of the function arguments found in a particular line of source code.

codegen(x[, indent_str, _required_imports, ...])

Attempts to generate a string of Python code that, when evaluated, would produce the same value as the input.

dashes()

A quick macro for drawing some dashes, to make the terminal output clearer to distinguish.

aerosandbox.tools.inspect_tools.get_caller_source_location(stacklevel=1)[source]#

Gets the file location where this function itself (get_caller_source_location()) is called.

This is not usually useful by itself. However, with the use of the stacklevel argument, you can get the call location at any point arbitrarily high up in the call stack from this function.

This potentially lets you determine the file location where any Python object was declared.

Examples:

Consider the file below (and assume we somehow have this function in scope):

my_file.py: >>> def my_func(): >>> print( >>> get_caller_source_location(stacklevel=2) >>> ) >>> >>> if_you_can_see_this_it_works = my_func()

This will print out the following: (/path/to/my_file.py, 5, “if_you_can_see_this_it_works = my_func()

“)

Args:

stacklevel: Choose the level of the stack that you want to retrieve source code at. Higher integers will get you higher (i.e., more end-user-facing) in the stack. Same behaviour as the stacklevel argument in warnings.warn().

Returns: A tuple of:

(filename, lineno, code_context)

  • filename: a Path object (see pathlib.Path from the standard Python library) of the file where this function was called.

  • lineno: the line number in the file where this function was called.

  • code_context: the immediate line of code where this function was called. A string. Note that, in the case of

multiline statements, this may not be a complete Python expression. Includes the trailing newline character (”

“) at the end.

Parameters:

stacklevel (int) –

Return type:

(pathlib.Path, int, str)

aerosandbox.tools.inspect_tools.get_source_code_from_location(filename, lineno, code_context=None, strip_lines=False)[source]#

Gets the source code of the single statement that begins at the file location specified.

File location must, at a minimum, contain the filename and the line number. Optionally, you can also provide code_context.

These should have the format:

  • filename: a Path object (see pathlib.Path from the standard Python library) of the file where this function was called.

  • lineno: the line number in the file where this function was called.

Optionally, you can also provide code_context, which has the format:

  • code_context: the immediate line of code where this function was called. A string. Note that, in the case of

multiline statements, this may not be a complete Python expression.

You can get source code from further up the call stack by using the stacklevel argument.

Args:

filename: a Path object (see pathlib.Path from the standard Python library) of the file where this function was called. Alternatively, a string containing a filename.

lineno: the line number in the file where this function was called. An integer. Should refer to the first line of a string in question.

code_context: Optional. Should be a string containing the immediate line of code at this location. If provided, allows short-circuiting (bypassing file I/O) if the line is a complete expression.

strip_lines: A boolean flag about whether or not to strip leading and trailing whitespace off each line of a multi-line function call. See the built-in string method str.strip() for behaviour.

Returns: The source code of the call, as a string. Might be a multi-line string (i.e., contains ‘

‘ characters)

if the call is multi-line. Almost certainly (but not guaranteed due to edge cases) to be a complete Python expression.

Parameters:
  • filename (Union[pathlib.Path, str]) –

  • lineno (int) –

  • code_context (str) –

  • strip_lines (bool) –

Return type:

str

aerosandbox.tools.inspect_tools.get_caller_source_code(stacklevel=1, strip_lines=False)[source]#

Gets the source code of wherever this function is called.

You can get source code from further up the call stack by using the stacklevel argument.

Args:

stacklevel: Choose the level of the stack that you want to retrieve source code at. Higher integers will get you higher (i.e., more end-user-facing) in the stack. Same behaviour as the stacklevel argument in warnings.warn().

strip_lines: A boolean flag about whether or not to strip leading and trailing whitespace off each line of a multi-line function call. See the built-in string method str.strip() for behaviour.

Returns: The source code of the call, as a string. Might be a multi-line string (i.e., contains ‘

‘ characters)

if the call is multi-line. Almost certainly (but not guaranteed due to edge cases) to be a complete Python expression.

Parameters:
  • stacklevel (int) –

  • strip_lines (bool) –

Return type:

str

aerosandbox.tools.inspect_tools.get_function_argument_names_from_source_code(source_code)[source]#

Gets the names of the function arguments found in a particular line of source code.

Specifically, it retrieves the names of the arguments in the first function call found in the source code string.

If the source code line is an assignment statement, only the right-hand-side of the line is analyzed.

Also, removes all line breaks (’

‘).

Examples function inputs and outputs:

“f(a, b)” -> [‘a’, ‘b’] “f(a,b)” -> [‘a’, ‘b’] “f(

a, b)” -> [‘a’, ‘b’]

“g = f(a, b)” -> [‘a’, ‘b’] “g.h = f(a, b)” -> [‘a’, ‘b’] “g.h() = f(a, b)” -> [‘a’, ‘b’] “g.h(i=j) = f(a, b)” -> [‘a’, ‘b’] “f(a, b) + g(h)” -> [‘a’, ‘b’] “f(a: int, b: MyType())” -> [‘a’, ‘b’] “f(a, b).g(c, d)” -> [‘a’, ‘b’] “f(a(b), c)” -> [‘a(b)’, ‘c’] “f(a(b,c), d)” -> [‘a(b,c)’, ‘d’] “f({a:b}, c)” -> [‘{a:b}’, ‘c’] “f(a[b], c)” -> [‘a[b]’, ‘c’] “f({a:b, c:d}, e)” -> [‘{a:b, c:d}’, ‘e’] “f({a:b,

c:d}, e)” -> [‘{a:b,c:d}’, ‘e’]

“f(dict(a=b,c=d), e)” -> [‘dict(a=b,c=d)’, ‘e’] “f(a=1, b=2)” -> [‘a=1’, ‘b=2’] “f()” -> [‘’] “f(a, [i for i in l])” -> [‘a’, ‘[i for i in l]’], “f(incomplete, “ -> raises ValueError “3 + 5” -> raises ValueError “” -> raises ValueError

Args:

source_code: A line of Python source code that includes a function call. Can be a multi-line piece of source code (e.g., includes ‘

‘).

Returns: A list of strings containing all the function arguments. If keyword arguments are found, includes both the key and the value, as-written.

Parameters:

source_code (str) –

Return type:

List[str]

aerosandbox.tools.inspect_tools.codegen(x, indent_str='    ', _required_imports=None, _recursion_depth=0)[source]#

Attempts to generate a string of Python code that, when evaluated, would produce the same value as the input. Also generates the required imports for the code to run.

In other words, in general, the following should evaluate True:

>>> code, imports = codegen(x)
>>> for import_str in imports:
>>>     exec(import_str)
>>> eval(code) == x  # Should evaluate True

Not guaranteed to work for all inputs, but should work for most common cases.

Parameters:
  • x (Any) – The object to generate the code of.

  • indent_str (str) – The string to use for indentation. Defaults to four spaces.

  • _required_imports (Optional[Set[str]]) – A set of strings containing the names of all required imports. This is an internal

  • user. (argument that should not be used by the) –

  • _recursion_depth (int) – The current recursion depth. This is an internal argument that should not be used by the user.

Return type:

Tuple[str, Set[str]]

Returns: A tuple containing:

  • The string of Python code that, when evaluated, would produce the same value as the input.

  • A set of strings that, when evaluated, would import all the required imports for the code to run.

Examples

>>> codegen(5)
('5', set())
>>> codegen([1, 2, 3])
('[1, 2, 3]', set())
>>> codegen(np.array([1, 2, 3]))
('np.array([1, 2, 3])', {'import numpy as np'})
>>> codegen(dict(my_int=4, my_array=np.array([1, 2, 3])))
('{
        'my_int': 4,
        'my_array': np.array([1, 2, 3]),
}', {'import numpy as np'})
aerosandbox.tools.inspect_tools.dashes()[source]#

A quick macro for drawing some dashes, to make the terminal output clearer to distinguish.