Jason Lowe-Power has uploaded this change for review. ( https://gem5-review.googlesource.com/c/public/gem5/+/49470 )

Change subject: scons: emit python stubfiles
......................................................................

scons: emit python stubfiles

Stubfiles in python allow you or your IDE to track the types of python
objects even without the full source code. This is useful for many of
gem5's objects since the source code is embedded in the gem5 binary
where IDEs can't easily see it.

This changeset adds a way to generate the stubfiles as gem5 is being
built. The files are generated to a directory under build/ and after they
are generated, you can point your IDE to that path. This requires the
stubgen program (from mypy) to be installed and does nothing if it's
not available.

Change-Id: I73966c8621d0a7a14060758d322c45df57b71102
Signed-off-by: Jason Lowe-Power <[email protected]>
---
M SConstruct
M src/SConscript
2 files changed, 45 insertions(+), 0 deletions(-)



diff --git a/SConstruct b/SConstruct
index 4091d4b..7d85b4d 100755
--- a/SConstruct
+++ b/SConstruct
@@ -246,6 +246,9 @@
     ('PYTHON_CONFIG', 'Python config binary to use',
      [ 'python3-config', 'python-config']
     ),
+ ('PYTYPES_PATH', 'Path to output the python types stubfiles relative to '
+     'the build directory', 'py_types'),
+    ('PYTHON_STUBGEN', 'Path to the stubgen utility', 'stubgen'),
     ('PROTOC', 'protoc tool', environ.get('PROTOC', 'protoc')),
     ('BATCH', 'Use batch pool for build and tests', False),
     ('BATCH_CMD', 'Batch pool submission command name', 'qdo'),
@@ -491,6 +494,18 @@
         if conf.TryAction('@%s --embed' % python_config)[0]:
             cmd.append('--embed')

+    # Check for stubgen to generate stubfiles
+    pytypes_path = main['PYTYPES_PATH']
+    python_stubgen = main.Detect(main['PYTHON_STUBGEN'])
+    if not python_stubgen:
+ warning("Can't find python's stubgen. Install mypy to generate python "
+                "stubfiles for type annoations.")
+        stubgen_path = None
+    else:
+        stubgen_path = main['PYTHON_STUBGEN']
+    Export('pytypes_path')
+    Export('stubgen_path')
+
     def flag_filter(env, cmd_output):
         flags = cmd_output.split()
         prefixes = ('-l', '-L', '-I')
diff --git a/src/SConscript b/src/SConscript
index 465b14a..57e8e19 100644
--- a/src/SConscript
+++ b/src/SConscript
@@ -372,6 +372,8 @@
             path = []

         modpath = path[:]
+        type_path = '/'.join(modpath + [ modname ])
+
         if modname != '__init__':
             modpath += [ modname ]
         modpath = '.'.join(modpath)
@@ -388,6 +390,8 @@
         self.abspath = abspath
         self.compiled = File(self.filename + 'c')
         self.cpp = File(self.filename + '.cc')
+        self.stubfile = f'{pytypes_path}/{type_path}.pyi'
+
         self.symname = PySource.invalid_sym_char.sub('_', modpath)

         PySource.modules[modpath] = self
@@ -1243,6 +1247,27 @@
 ''')
     code.write(str(target[0]))

+def stubgenPyFile(target, source, env):
+    """ Generate a stubfile (.pyi) for the python source
+    """
+    import subprocess
+    import pathlib
+
+    py_path = pathlib.Path(str(source[0]))
+
+    # The python modules in the m5 directory are correctly grouped into
+    # packages so we can use the base output path. However, the "special"
+ # modules that are outside of the src/python directory (e.g., SimObjects)
+    # should use their module name as the output directory.
+    if 'python/m5' in str(source[0]):
+        output_dir = env['BUILDDIR'] + '/' + pytypes_path
+    else:
+        output_dir = pathlib.Path(str(target[0])).parent
+
+    subprocess.check_call(['stubgen', py_path,
+        '--search-path', py_path.parent, '--output', output_dir],
+        stdout=subprocess.DEVNULL)
+
 if main['USE_PYTHON']:
     # Build a small helper that marshals the Python code using the same
     # version of Python as gem5. This is in an unorthodox location to
@@ -1254,6 +1279,11 @@
                         MakeAction(embedPyFile, Transform("EMBED PY")))
         Source(source.cpp, tags=source.tags, add_tags='python')

+        # Generate the stubfiles
+        if stubgen_path:
+            env.Command(source.stubfile, source.tnode,
+                        MakeAction(stubgenPyFile, Transform("STUBGEN PY")))
+
 ########################################################################
 #
 # Define binaries.  Each different build type (debug, opt, etc.) gets

--
To view, visit https://gem5-review.googlesource.com/c/public/gem5/+/49470
To unsubscribe, or for help writing mail filters, visit https://gem5-review.googlesource.com/settings

Gerrit-Project: public/gem5
Gerrit-Branch: develop
Gerrit-Change-Id: I73966c8621d0a7a14060758d322c45df57b71102
Gerrit-Change-Number: 49470
Gerrit-PatchSet: 1
Gerrit-Owner: Jason Lowe-Power <[email protected]>
Gerrit-MessageType: newchange
_______________________________________________
gem5-dev mailing list -- [email protected]
To unsubscribe send an email to [email protected]
%(web_page_url)slistinfo%(cgiext)s/%(_internal_name)s

Reply via email to