This commit is contained in:
Sven Riwoldt
2024-04-01 20:30:24 +02:00
parent fd333f3514
commit c7bc862c6f
6804 changed files with 1065135 additions and 0 deletions

View File

@@ -0,0 +1,140 @@
# Copyright (c) 2009- Spyder Kernels Contributors
#
# Licensed under the terms of the MIT License
# (see spyder_kernels/__init__.py for details)
"""Utility functions."""
import ast
import os
import re
import sys
import sysconfig
def create_pathlist():
"""
Create list of Python library paths to be skipped from module
reloading and Pdb steps.
"""
# Get standard installation paths
try:
paths = sysconfig.get_paths()
standard_paths = [paths['stdlib'],
paths['purelib'],
paths['scripts'],
paths['data']]
except Exception:
standard_paths = []
# Get user installation path
# See spyder-ide/spyder#8776
try:
import site
if getattr(site, 'getusersitepackages', False):
# Virtualenvs don't have this function but
# conda envs do
user_path = [site.getusersitepackages()]
elif getattr(site, 'USER_SITE', False):
# However, it seems virtualenvs have this
# constant
user_path = [site.USER_SITE]
else:
user_path = []
except Exception:
user_path = []
return standard_paths + user_path
def path_is_library(path, initial_pathlist=None):
"""Decide if a path is in user code or a library according to its path."""
# Compute DEFAULT_PATHLIST only once and make it global to reuse it
# in any future call of this function.
if 'DEFAULT_PATHLIST' not in globals():
global DEFAULT_PATHLIST
DEFAULT_PATHLIST = create_pathlist()
if initial_pathlist is None:
initial_pathlist = []
pathlist = initial_pathlist + DEFAULT_PATHLIST
if path is None:
# Path probably comes from a C module that is statically linked
# into the interpreter. There is no way to know its path, so we
# choose to ignore it.
return True
elif any([p in path for p in pathlist]):
# We don't want to consider paths that belong to the standard
# library or installed to site-packages.
return True
elif os.name == 'nt':
if re.search(r'.*\\pkgs\\.*', path):
return True
else:
return False
elif not os.name == 'nt':
# Paths containing the strings below can be part of the default
# Linux installation, Homebrew or the user site-packages in a
# virtualenv.
patterns = [
r'^/usr/lib.*',
r'^/usr/local/lib.*',
r'^/usr/.*/dist-packages/.*',
r'^/home/.*/.local/lib.*',
r'^/Library/.*',
r'^/Users/.*/Library/.*',
r'^/Users/.*/.local/.*',
]
if [p for p in patterns if re.search(p, path)]:
return True
else:
return False
else:
return False
def capture_last_Expr(code_ast, out_varname):
"""Parse line and modify code to capture in globals the last expression."""
# Modify ast code to capture the last expression
capture_last_expression = False
if (
len(code_ast.body)
and isinstance(code_ast.body[-1], ast.Expr)
):
capture_last_expression = True
expr_node = code_ast.body[-1]
# Create new assign node
assign_node = ast.parse(
'globals()[{}] = None'.format(repr(out_varname))).body[0]
# Replace None by the value
assign_node.value = expr_node.value
# Fix line number and column offset
assign_node.lineno = expr_node.lineno
assign_node.col_offset = expr_node.col_offset
if sys.version_info[:2] >= (3, 8):
# Exists from 3.8, necessary from 3.11
assign_node.end_lineno = expr_node.end_lineno
if assign_node.lineno == assign_node.end_lineno:
# Add 'globals()[{}] = ' and remove 'None'
assign_node.end_col_offset += expr_node.end_col_offset - 4
else:
assign_node.end_col_offset = expr_node.end_col_offset
code_ast.body[-1] = assign_node
return code_ast, capture_last_expression
def canonic(filename):
"""
Return canonical form of filename.
This is a copy of bdb.canonic, so that the debugger will process
filenames in the same way
"""
if filename == "<" + filename[1:-1] + ">":
return filename
canonic = os.path.abspath(filename)
canonic = os.path.normcase(canonic)
return canonic