Run DCE after a LoopFlatten test to reduce spurious output [nfc]
[llvm-project.git] / lldb / packages / Python / lldbsuite / test / lldb_pylint_helper.py
blob3b746c3f9242df03320edbd76c5378c5507b1db1
1 """
2 Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
3 See https://llvm.org/LICENSE.txt for license information.
4 SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 Sync lldb and related source from a local machine to a remote machine.
8 This facilitates working on the lldb sourcecode on multiple machines
9 and multiple OS types, verifying changes across all.
11 Provides helper support for adding lldb test paths to the python path.
12 """
14 # System modules
15 import os
16 import platform
17 import subprocess
18 import sys
20 # Third-party modules
22 # LLDB modules
25 def add_lldb_test_paths(check_dir):
26 # pylint: disable=line-too-long
27 """Adds lldb test-related paths to the python path.
29 Starting with the given directory and working upward through
30 each parent directory up to the root, it looks for the lldb
31 test directory. When found, the lldb test directory and its
32 child test_runner/lib directory will be added to the python
33 system path.
35 Instructions for use:
37 This method supports a simple way of getting pylint to be able
38 to reliably lint lldb python test scripts (including the test
39 infrastructure itself). To do so, add the following to a
40 .pylintrc file in your home directory:
42 [Master]
43 init-hook='import os; import sys; sys.path.append(os.path.expanduser("~/path/to/lldb/packages/Python/lldbsuite/test")); import lldb_pylint_helper; lldb_pylint_helper.add_lldb_test_paths(os.getcwd()); print("sys.path={}\n".format(sys.path))'
45 Replace ~/path/to/lldb with a valid path to your local lldb source
46 tree. Note you can have multiple lldb source trees on your system, and
47 this will work just fine. The path in your .pylintrc is just needed to
48 find the paths needed for pylint in whatever lldb source tree you're in.
49 pylint will use the python files in whichever tree it is run from.
51 Note it is critical that the init-hook line be contained on a single line.
52 You can remove the print line at the end once you know the pythonpath is
53 getting set up the way you expect.
55 With these changes, you will be able to run the following, for example.
57 cd lldb/sourcetree/1-of-many/test/lang/c/anonymous
58 pylint TestAnonymous.py
60 This will work, and include all the lldb/sourcetree/1-of-many lldb-specific
61 python directories to your path.
63 You can then run it in another lldb source tree on the same machine like
64 so:
66 cd lldb/sourcetree/2-of-many/test/functionalities/inferior-assert
67 pyline TestInferiorAssert.py
69 and this will properly lint that file, using the lldb-specific python
70 directories from the 2-of-many source tree.
72 Note at the time I'm writing this, our tests are in pretty sad shape
73 as far as a stock pylint setup goes. But we need to start somewhere :-)
75 @param check_dir specifies a directory that will be used to start
76 looking for the lldb test infrastructure python library paths.
77 """
78 # Add the test-related packages themselves.
79 add_lldb_test_package_paths(check_dir)
81 # Add the lldb directory itself
82 add_lldb_module_directory()
85 def add_lldb_module_directory():
86 """
87 Desired Approach:
89 Part A: find an lldb
91 1. Walk up the parent chain from the current directory, looking for
92 a directory matching *build*. If we find that, use it as the
93 root of a directory search for an lldb[.exe] executable.
95 2. If 1 fails, use the path and look for an lldb[.exe] in there.
97 If Part A ends up with an lldb, go to part B. Otherwise, give up
98 on the lldb python module path.
100 Part B: use the output from 'lldb[.exe] -P' to find the lldb dir.
102 Current approach:
103 If Darwin, use 'xcrun lldb -P'; others: find lldb on path.
105 Drawback to current approach:
106 If the tester is changing the SB API (adding new methods), pylint
107 will not know about them as it is using the wrong lldb python module.
108 In practice, this should be minor.
110 try:
111 lldb_module_path = None
113 if platform.system() == "Darwin":
114 # Use xcrun to find the selected lldb.
115 lldb_module_path = subprocess.check_output(["xcrun", "lldb", "-P"])
116 elif platform.system() == "Windows":
117 lldb_module_path = subprocess.check_output(["lldb.exe", "-P"], shell=True)
118 else:
119 # Use the shell to run lldb from the path.
120 lldb_module_path = subprocess.check_output(["lldb", "-P"], shell=True)
122 # Trim the result.
123 if lldb_module_path is not None:
124 lldb_module_path = lldb_module_path.strip()
126 # If we have a result, add it to the path
127 if lldb_module_path is not None and len(lldb_module_path) > 0:
128 sys.path.insert(0, lldb_module_path)
129 # pylint: disable=broad-except
130 except Exception as exception:
131 print("failed to find python path: {}".format(exception))
134 def add_lldb_test_package_paths(check_dir):
135 """Adds the lldb test infrastructure modules to the python path.
137 See add_lldb_test_paths for more details.
139 @param check_dir the directory of the test.
142 def child_dirs(parent_dir):
143 return [
144 os.path.join(parent_dir, child)
145 for child in os.listdir(parent_dir)
146 if os.path.isdir(os.path.join(parent_dir, child))
149 check_dir = os.path.realpath(check_dir)
150 while check_dir and len(check_dir) > 0:
151 # If the current directory contains a packages/Python
152 # directory, add that directory to the path.
153 packages_python_child_dir = os.path.join(check_dir, "packages", "Python")
154 if os.path.exists(packages_python_child_dir):
155 sys.path.insert(0, packages_python_child_dir)
156 sys.path.insert(
157 0, os.path.join(packages_python_child_dir, "test_runner", "lib")
160 # Handle third_party module/package directory.
161 third_party_module_dir = os.path.join(
162 check_dir, "third_party", "Python", "module"
164 for child_dir in child_dirs(third_party_module_dir):
165 # Yes, we embed the module in the module parent dir
166 sys.path.insert(0, child_dir)
168 # We're done.
169 break
171 # Continue looking up the parent chain until we have no more
172 # directories to check.
173 new_check_dir = os.path.dirname(check_dir)
174 # We're done when the new check dir is not different
175 # than the current one.
176 if new_check_dir == check_dir:
177 break
178 check_dir = new_check_dir