diff --git a/BUILD.bazel b/BUILD.bazel index 0351d59c771..52a7097e1a7 100644 --- a/BUILD.bazel +++ b/BUILD.bazel @@ -199,6 +199,7 @@ write_source_files( "//hal:robotpy-hal-generator.generate_build_info", "//ntcore:pyntcore-generator.generate_build_info", "//romiVendordep:robotpy-romi-generator.generate_build_info", + "//simulation/halsim_gui:robotpy-halsim-gui-generator.generate_build_info", "//wpilibc:robotpy-wpilib-generator.generate_build_info", "//wpinet:robotpy-wpinet-generator.generate_build_info", "//wpimath:robotpy-wpimath-generator.generate_build_info", diff --git a/apriltag/robotpy_pybind_build_info.bzl b/apriltag/robotpy_pybind_build_info.bzl index 924346b78c5..b1b7dee649b 100644 --- a/apriltag/robotpy_pybind_build_info.bzl +++ b/apriltag/robotpy_pybind_build_info.bzl @@ -2,7 +2,7 @@ load("//shared/bazel/rules/gen:gen-version-file.bzl", "generate_version_file") load("//shared/bazel/rules/robotpy:robotpy_rules.bzl", "create_pybind_library", "robotpy_library") -load("//shared/bazel/rules/robotpy:semiwrap_helpers.bzl", "gen_libinit", "gen_modinit_hpp", "gen_pkgconf", "resolve_casters", "run_header_gen") +load("//shared/bazel/rules/robotpy:semiwrap_helpers.bzl", "gen_libinit", "gen_modinit_hpp", "gen_pkgconf", "make_pyi", "resolve_casters", "run_header_gen") load("//shared/bazel/rules/robotpy:semiwrap_tool_helpers.bzl", "scan_headers", "update_yaml_files") def apriltag_extension(srcs = [], header_to_dat_deps = [], extra_hdrs = [], includes = []): @@ -198,7 +198,7 @@ def apriltag_extension(srcs = [], header_to_dat_deps = [], extra_hdrs = [], incl tags = ["manual", "robotpy"], ) -def define_pybind_library(name, pkgcfgs = [], extra_pybind_hdrs = []): +def define_pybind_library(name, pkgcfgs = [], extra_pybind_hdrs = [], extra_pyi_deps = []): # Helper used to generate all files with one target. native.filegroup( name = "{}.generated_files".format(name), @@ -232,6 +232,14 @@ def define_pybind_library(name, pkgcfgs = [], extra_pybind_hdrs = []): template = "//shared/bazel/rules/robotpy:version_template.in", ) + make_pyi( + name = "robotpy_apriltag._apriltag.make_pyi", + package_name = "robotpy_apriltag._apriltag", + output_files = [["robotpy_apriltag/_apriltag.pyi", "src/main/python/robotpy_apriltag/_apriltag.pyi"]], + module_files = [["robotpy_apriltag", "src/main/python/robotpy_apriltag/__init__.py"], ["robotpy_apriltag._init__apriltag", "src/main/python/robotpy_apriltag/_init__apriltag.py"], ["robotpy_apriltag._apriltag", "src/main/python/robotpy_apriltag/_apriltag"]], + runner = ":{}.make_pyi_runner".format(name), + ) + robotpy_library( name = name, distribution = "robotpy-apriltag", @@ -245,6 +253,10 @@ def define_pybind_library(name, pkgcfgs = [], extra_pybind_hdrs = []): ":src/main/python/robotpy_apriltag/_apriltag", ":apriltag.trampoline_hdr_files", ], + pyi_srcs = [ + ":robotpy_apriltag._apriltag.make_pyi", + ], + pyi_deps = extra_pyi_deps, imports = ["src/main/python"], deps = [ "//apriltag:robotpy-native-apriltag", @@ -274,7 +286,7 @@ def define_pybind_library(name, pkgcfgs = [], extra_pybind_hdrs = []): package_root_file = "src/main/python/robotpy_apriltag/__init__.py", pkgcfgs = pkgcfgs, pyproject_toml = "src/main/python/pyproject.toml", - yaml_files = native.glob(["src/main/python/semiwrap/**"]), + yaml_files = native.glob(["src/main/python/semiwrap/**"], allow_empty = True), ) scan_headers( diff --git a/datalog/robotpy_pybind_build_info.bzl b/datalog/robotpy_pybind_build_info.bzl index 50cd724fd16..7e408ee0ba5 100644 --- a/datalog/robotpy_pybind_build_info.bzl +++ b/datalog/robotpy_pybind_build_info.bzl @@ -2,7 +2,7 @@ load("//shared/bazel/rules/gen:gen-version-file.bzl", "generate_version_file") load("//shared/bazel/rules/robotpy:robotpy_rules.bzl", "create_pybind_library", "robotpy_library") -load("//shared/bazel/rules/robotpy:semiwrap_helpers.bzl", "gen_libinit", "gen_modinit_hpp", "gen_pkgconf", "resolve_casters", "run_header_gen") +load("//shared/bazel/rules/robotpy:semiwrap_helpers.bzl", "gen_libinit", "gen_modinit_hpp", "gen_pkgconf", "make_pyi", "resolve_casters", "run_header_gen") load("//shared/bazel/rules/robotpy:semiwrap_tool_helpers.bzl", "scan_headers", "update_yaml_files") def wpilog_extension(srcs = [], header_to_dat_deps = [], extra_hdrs = [], includes = []): @@ -221,7 +221,7 @@ def wpilog_extension(srcs = [], header_to_dat_deps = [], extra_hdrs = [], includ tags = ["manual", "robotpy"], ) -def define_pybind_library(name, pkgcfgs = [], extra_pybind_hdrs = []): +def define_pybind_library(name, pkgcfgs = [], extra_pybind_hdrs = [], extra_pyi_deps = []): # Helper used to generate all files with one target. native.filegroup( name = "{}.generated_files".format(name), @@ -255,6 +255,14 @@ def define_pybind_library(name, pkgcfgs = [], extra_pybind_hdrs = []): template = "//shared/bazel/rules/robotpy:version_template.in", ) + make_pyi( + name = "wpilog._wpilog.make_pyi", + package_name = "wpilog._wpilog", + output_files = [["wpilog/_wpilog.pyi", "src/main/python/wpilog/_wpilog.pyi"]], + module_files = [["wpilog", "src/main/python/wpilog/__init__.py"], ["wpilog._init__wpilog", "src/main/python/wpilog/_init__wpilog.py"], ["wpilog._wpilog", "src/main/python/wpilog/_wpilog"]], + runner = ":{}.make_pyi_runner".format(name), + ) + robotpy_library( name = name, distribution = "robotpy-wpilog", @@ -268,6 +276,10 @@ def define_pybind_library(name, pkgcfgs = [], extra_pybind_hdrs = []): ":src/main/python/wpilog/_wpilog", ":wpilog.trampoline_hdr_files", ], + pyi_srcs = [ + ":wpilog._wpilog.make_pyi", + ], + pyi_deps = extra_pyi_deps, imports = ["src/main/python"], deps = [ "//datalog:robotpy-native-datalog", @@ -295,7 +307,7 @@ def define_pybind_library(name, pkgcfgs = [], extra_pybind_hdrs = []): package_root_file = "src/main/python/wpilog/__init__.py", pkgcfgs = pkgcfgs, pyproject_toml = "src/main/python/pyproject.toml", - yaml_files = native.glob(["src/main/python/semiwrap/**"]), + yaml_files = native.glob(["src/main/python/semiwrap/**"], allow_empty = True), ) scan_headers( diff --git a/drivers/robotpy_pybind_build_info.bzl b/drivers/robotpy_pybind_build_info.bzl index 28a99f26966..4a0d14d3826 100644 --- a/drivers/robotpy_pybind_build_info.bzl +++ b/drivers/robotpy_pybind_build_info.bzl @@ -2,7 +2,7 @@ load("//shared/bazel/rules/gen:gen-version-file.bzl", "generate_version_file") load("//shared/bazel/rules/robotpy:robotpy_rules.bzl", "create_pybind_library", "robotpy_library") -load("//shared/bazel/rules/robotpy:semiwrap_helpers.bzl", "gen_libinit", "gen_modinit_hpp", "gen_pkgconf", "resolve_casters", "run_header_gen") +load("//shared/bazel/rules/robotpy:semiwrap_helpers.bzl", "gen_libinit", "gen_modinit_hpp", "gen_pkgconf", "make_pyi", "resolve_casters", "run_header_gen") load("//shared/bazel/rules/robotpy:semiwrap_tool_helpers.bzl", "scan_headers", "update_yaml_files") def drivers_extension(srcs = [], header_to_dat_deps = [], extra_hdrs = [], includes = []): @@ -275,7 +275,7 @@ def drivers_extension(srcs = [], header_to_dat_deps = [], extra_hdrs = [], inclu tags = ["manual", "robotpy"], ) -def define_pybind_library(name, pkgcfgs = [], extra_pybind_hdrs = []): +def define_pybind_library(name, pkgcfgs = [], extra_pybind_hdrs = [], extra_pyi_deps = []): # Helper used to generate all files with one target. native.filegroup( name = "{}.generated_files".format(name), @@ -309,6 +309,14 @@ def define_pybind_library(name, pkgcfgs = [], extra_pybind_hdrs = []): template = "//shared/bazel/rules/robotpy:version_template.in", ) + make_pyi( + name = "wpilib_drivers._drivers.make_pyi", + package_name = "wpilib_drivers._drivers", + output_files = [["wpilib_drivers/_drivers.pyi", "src/main/python/wpilib_drivers/_drivers.pyi"]], + module_files = [["wpilib_drivers", "src/main/python/wpilib_drivers/__init__.py"], ["wpilib_drivers._init__drivers", "src/main/python/wpilib_drivers/_init__drivers.py"], ["wpilib_drivers._drivers", "src/main/python/wpilib_drivers/_drivers"]], + runner = ":{}.make_pyi_runner".format(name), + ) + robotpy_library( name = name, distribution = "wpilib-drivers", @@ -322,6 +330,10 @@ def define_pybind_library(name, pkgcfgs = [], extra_pybind_hdrs = []): ":src/main/python/wpilib_drivers/_drivers", ":drivers.trampoline_hdr_files", ], + pyi_srcs = [ + ":wpilib_drivers._drivers.make_pyi", + ], + pyi_deps = extra_pyi_deps, imports = ["src/main/python"], deps = [ "//drivers:robotpy-native-wpilib-drivers", @@ -355,7 +367,7 @@ def define_pybind_library(name, pkgcfgs = [], extra_pybind_hdrs = []): package_root_file = "src/main/python/wpilib_drivers/__init__.py", pkgcfgs = pkgcfgs, pyproject_toml = "src/main/python/pyproject.toml", - yaml_files = native.glob(["src/main/python/semiwrap/**"]), + yaml_files = native.glob(["src/main/python/semiwrap/**"], allow_empty = True), ) scan_headers( diff --git a/fields/robotpy_pybind_build_info.bzl b/fields/robotpy_pybind_build_info.bzl index f335687c474..749254180ad 100644 --- a/fields/robotpy_pybind_build_info.bzl +++ b/fields/robotpy_pybind_build_info.bzl @@ -2,7 +2,7 @@ load("//shared/bazel/rules/gen:gen-version-file.bzl", "generate_version_file") load("//shared/bazel/rules/robotpy:robotpy_rules.bzl", "create_pybind_library", "robotpy_library") -load("//shared/bazel/rules/robotpy:semiwrap_helpers.bzl", "gen_libinit", "gen_modinit_hpp", "gen_pkgconf", "resolve_casters", "run_header_gen") +load("//shared/bazel/rules/robotpy:semiwrap_helpers.bzl", "gen_libinit", "gen_modinit_hpp", "gen_pkgconf", "make_pyi", "resolve_casters", "run_header_gen") load("//shared/bazel/rules/robotpy:semiwrap_tool_helpers.bzl", "scan_headers", "update_yaml_files") def fields_extension(srcs = [], header_to_dat_deps = [], extra_hdrs = [], includes = []): @@ -191,7 +191,7 @@ def fields_extension(srcs = [], header_to_dat_deps = [], extra_hdrs = [], includ tags = ["manual", "robotpy"], ) -def define_pybind_library(name, pkgcfgs = [], extra_pybind_hdrs = []): +def define_pybind_library(name, pkgcfgs = [], extra_pybind_hdrs = [], extra_pyi_deps = []): # Helper used to generate all files with one target. native.filegroup( name = "{}.generated_files".format(name), @@ -225,6 +225,14 @@ def define_pybind_library(name, pkgcfgs = [], extra_pybind_hdrs = []): template = "//shared/bazel/rules/robotpy:version_template.in", ) + make_pyi( + name = "robotpy_fields._fields.make_pyi", + package_name = "robotpy_fields._fields", + output_files = [["robotpy_fields/_fields.pyi", "src/main/python/robotpy_fields/_fields.pyi"]], + module_files = [["robotpy_fields", "src/main/python/robotpy_fields/__init__.py"], ["robotpy_fields._init__fields", "src/main/python/robotpy_fields/_init__fields.py"], ["robotpy_fields._fields", "src/main/python/robotpy_fields/_fields"]], + runner = ":{}.make_pyi_runner".format(name), + ) + robotpy_library( name = name, distribution = "robotpy-fields", @@ -238,6 +246,10 @@ def define_pybind_library(name, pkgcfgs = [], extra_pybind_hdrs = []): ":src/main/python/robotpy_fields/_fields", ":fields.trampoline_hdr_files", ], + pyi_srcs = [ + ":robotpy_fields._fields.make_pyi", + ], + pyi_deps = extra_pyi_deps, imports = ["src/main/python"], deps = [ "//fields:robotpy-native-fields", @@ -267,7 +279,7 @@ def define_pybind_library(name, pkgcfgs = [], extra_pybind_hdrs = []): package_root_file = "src/main/python/robotpy_fields/__init__.py", pkgcfgs = pkgcfgs, pyproject_toml = "src/main/python/pyproject.toml", - yaml_files = native.glob(["src/main/python/semiwrap/**"]), + yaml_files = native.glob(["src/main/python/semiwrap/**"], allow_empty = True), ) scan_headers( diff --git a/hal/robotpy_pybind_build_info.bzl b/hal/robotpy_pybind_build_info.bzl index fe512308fc6..b95febd4d87 100644 --- a/hal/robotpy_pybind_build_info.bzl +++ b/hal/robotpy_pybind_build_info.bzl @@ -2,7 +2,7 @@ load("//shared/bazel/rules/gen:gen-version-file.bzl", "generate_version_file") load("//shared/bazel/rules/robotpy:robotpy_rules.bzl", "create_pybind_library", "robotpy_library") -load("//shared/bazel/rules/robotpy:semiwrap_helpers.bzl", "gen_libinit", "gen_modinit_hpp", "gen_pkgconf", "resolve_casters", "run_header_gen") +load("//shared/bazel/rules/robotpy:semiwrap_helpers.bzl", "gen_libinit", "gen_modinit_hpp", "gen_pkgconf", "make_pyi", "resolve_casters", "run_header_gen") load("//shared/bazel/rules/robotpy:semiwrap_tool_helpers.bzl", "scan_headers", "update_yaml_files") def hal_simulation_extension(srcs = [], header_to_dat_deps = [], extra_hdrs = [], includes = []): @@ -492,7 +492,7 @@ def wpihal_extension(srcs = [], header_to_dat_deps = [], extra_hdrs = [], includ tags = ["manual", "robotpy"], ) -def define_pybind_library(name, pkgcfgs = [], extra_pybind_hdrs = []): +def define_pybind_library(name, pkgcfgs = [], extra_pybind_hdrs = [], extra_pyi_deps = []): # Helper used to generate all files with one target. native.filegroup( name = "{}.generated_files".format(name), @@ -528,6 +528,22 @@ def define_pybind_library(name, pkgcfgs = [], extra_pybind_hdrs = []): template = "//shared/bazel/rules/robotpy:version_template.in", ) + make_pyi( + name = "hal.simulation._simulation.make_pyi", + package_name = "hal.simulation._simulation", + output_files = [["hal/simulation/_simulation.pyi", "src/main/python/hal/simulation/_simulation.pyi"]], + module_files = [["hal.simulation", "src/main/python/hal/simulation/__init__.py"], ["hal.simulation._init__simulation", "src/main/python/hal/simulation/_init__simulation.py"], ["hal.simulation._simulation", "src/main/python/hal/simulation/_simulation"], ["hal", "src/main/python/hal/__init__.py"], ["hal._init__wpi_hal", "src/main/python/hal/_init__wpi_hal.py"], ["hal._wpi_hal", "src/main/python/hal/_wpi_hal"]], + runner = ":{}.make_pyi_runner".format(name), + ) + + make_pyi( + name = "hal._wpi_hal.make_pyi", + package_name = "hal._wpi_hal", + output_files = [["hal/_wpi_hal.pyi", "src/main/python/hal/_wpi_hal.pyi"]], + module_files = [["hal.simulation", "src/main/python/hal/simulation/__init__.py"], ["hal.simulation._init__simulation", "src/main/python/hal/simulation/_init__simulation.py"], ["hal.simulation._simulation", "src/main/python/hal/simulation/_simulation"], ["hal", "src/main/python/hal/__init__.py"], ["hal._init__wpi_hal", "src/main/python/hal/_init__wpi_hal.py"], ["hal._wpi_hal", "src/main/python/hal/_wpi_hal"]], + runner = ":{}.make_pyi_runner".format(name), + ) + robotpy_library( name = name, distribution = "robotpy-hal", @@ -544,6 +560,11 @@ def define_pybind_library(name, pkgcfgs = [], extra_pybind_hdrs = []): ":hal_simulation.trampoline_hdr_files", ":wpihal.trampoline_hdr_files", ], + pyi_srcs = [ + ":hal.simulation._simulation.make_pyi", + ":hal._wpi_hal.make_pyi", + ], + pyi_deps = extra_pyi_deps, imports = ["src/main/python"], deps = [ "//hal:robotpy-native-wpihal", @@ -575,7 +596,7 @@ def define_pybind_library(name, pkgcfgs = [], extra_pybind_hdrs = []): package_root_file = "src/main/python/hal/__init__.py", pkgcfgs = pkgcfgs, pyproject_toml = "src/main/python/pyproject.toml", - yaml_files = native.glob(["src/main/python/semiwrap/**"]), + yaml_files = native.glob(["src/main/python/semiwrap/**"], allow_empty = True), ) scan_headers( diff --git a/ntcore/robotpy_pybind_build_info.bzl b/ntcore/robotpy_pybind_build_info.bzl index a58d9d7c5f4..dcdcc23719c 100644 --- a/ntcore/robotpy_pybind_build_info.bzl +++ b/ntcore/robotpy_pybind_build_info.bzl @@ -2,7 +2,7 @@ load("//shared/bazel/rules/gen:gen-version-file.bzl", "generate_version_file") load("//shared/bazel/rules/robotpy:robotpy_rules.bzl", "create_pybind_library", "robotpy_library") -load("//shared/bazel/rules/robotpy:semiwrap_helpers.bzl", "gen_libinit", "gen_modinit_hpp", "gen_pkgconf", "resolve_casters", "run_header_gen") +load("//shared/bazel/rules/robotpy:semiwrap_helpers.bzl", "gen_libinit", "gen_modinit_hpp", "gen_pkgconf", "make_pyi", "resolve_casters", "run_header_gen") load("//shared/bazel/rules/robotpy:semiwrap_tool_helpers.bzl", "scan_headers", "update_yaml_files") def ntcore_extension(srcs = [], header_to_dat_deps = [], extra_hdrs = [], includes = []): @@ -496,7 +496,7 @@ def ntcore_extension(srcs = [], header_to_dat_deps = [], extra_hdrs = [], includ tags = ["manual", "robotpy"], ) -def define_pybind_library(name, pkgcfgs = [], extra_pybind_hdrs = []): +def define_pybind_library(name, pkgcfgs = [], extra_pybind_hdrs = [], extra_pyi_deps = []): # Helper used to generate all files with one target. native.filegroup( name = "{}.generated_files".format(name), @@ -530,6 +530,14 @@ def define_pybind_library(name, pkgcfgs = [], extra_pybind_hdrs = []): template = "//shared/bazel/rules/robotpy:version_template.in", ) + make_pyi( + name = "ntcore._ntcore.make_pyi", + package_name = "ntcore._ntcore", + output_files = [["ntcore/_ntcore/__init__.pyi", "src/main/python/ntcore/_ntcore/__init__.pyi"], ["ntcore/_ntcore/meta.pyi", "src/main/python/ntcore/_ntcore/meta.pyi"]], + module_files = [["ntcore", "src/main/python/ntcore/__init__.py"], ["ntcore._init__ntcore", "src/main/python/ntcore/_init__ntcore.py"], ["ntcore._ntcore", "src/main/python/ntcore/_ntcore"]], + runner = ":{}.make_pyi_runner".format(name), + ) + robotpy_library( name = name, distribution = "pyntcore", @@ -543,6 +551,10 @@ def define_pybind_library(name, pkgcfgs = [], extra_pybind_hdrs = []): ":src/main/python/ntcore/_ntcore", ":ntcore.trampoline_hdr_files", ], + pyi_srcs = [ + ":ntcore._ntcore.make_pyi", + ], + pyi_deps = extra_pyi_deps, imports = ["src/main/python"], deps = [ "//datalog:robotpy-wpilog", @@ -574,7 +586,7 @@ def define_pybind_library(name, pkgcfgs = [], extra_pybind_hdrs = []): package_root_file = "src/main/python/ntcore/__init__.py", pkgcfgs = pkgcfgs, pyproject_toml = "src/main/python/pyproject.toml", - yaml_files = native.glob(["src/main/python/semiwrap/**"]), + yaml_files = native.glob(["src/main/python/semiwrap/**"], allow_empty = True), ) scan_headers( diff --git a/romiVendordep/robotpy_pybind_build_info.bzl b/romiVendordep/robotpy_pybind_build_info.bzl index 17de5f09ec8..ea71f181bbd 100644 --- a/romiVendordep/robotpy_pybind_build_info.bzl +++ b/romiVendordep/robotpy_pybind_build_info.bzl @@ -2,7 +2,7 @@ load("//shared/bazel/rules/gen:gen-version-file.bzl", "generate_version_file") load("//shared/bazel/rules/robotpy:robotpy_rules.bzl", "create_pybind_library", "robotpy_library") -load("//shared/bazel/rules/robotpy:semiwrap_helpers.bzl", "gen_libinit", "gen_modinit_hpp", "gen_pkgconf", "resolve_casters", "run_header_gen") +load("//shared/bazel/rules/robotpy:semiwrap_helpers.bzl", "gen_libinit", "gen_modinit_hpp", "gen_pkgconf", "make_pyi", "resolve_casters", "run_header_gen") load("//shared/bazel/rules/robotpy:semiwrap_tool_helpers.bzl", "scan_headers", "update_yaml_files") def romi_extension(srcs = [], header_to_dat_deps = [], extra_hdrs = [], includes = []): @@ -198,7 +198,7 @@ def romi_extension(srcs = [], header_to_dat_deps = [], extra_hdrs = [], includes tags = ["manual", "robotpy"], ) -def define_pybind_library(name, pkgcfgs = [], extra_pybind_hdrs = []): +def define_pybind_library(name, pkgcfgs = [], extra_pybind_hdrs = [], extra_pyi_deps = []): # Helper used to generate all files with one target. native.filegroup( name = "{}.generated_files".format(name), @@ -232,6 +232,14 @@ def define_pybind_library(name, pkgcfgs = [], extra_pybind_hdrs = []): template = "//shared/bazel/rules/robotpy:version_template.in", ) + make_pyi( + name = "romi._romi.make_pyi", + package_name = "romi._romi", + output_files = [["romi/_romi.pyi", "src/main/python/romi/_romi.pyi"]], + module_files = [["romi", "src/main/python/romi/__init__.py"], ["romi._init__romi", "src/main/python/romi/_init__romi.py"], ["romi._romi", "src/main/python/romi/_romi"]], + runner = ":{}.make_pyi_runner".format(name), + ) + robotpy_library( name = name, distribution = "robotpy-romi", @@ -245,6 +253,10 @@ def define_pybind_library(name, pkgcfgs = [], extra_pybind_hdrs = []): ":src/main/python/romi/_romi", ":romi.trampoline_hdr_files", ], + pyi_srcs = [ + ":romi._romi.make_pyi", + ], + pyi_deps = extra_pyi_deps, imports = ["src/main/python"], deps = [ "//romiVendordep:robotpy-native-romi", @@ -280,7 +292,7 @@ def define_pybind_library(name, pkgcfgs = [], extra_pybind_hdrs = []): package_root_file = "src/main/python/romi/__init__.py", pkgcfgs = pkgcfgs, pyproject_toml = "src/main/python/pyproject.toml", - yaml_files = native.glob(["src/main/python/semiwrap/**"]), + yaml_files = native.glob(["src/main/python/semiwrap/**"], allow_empty = True), ) scan_headers( diff --git a/shared/bazel/rules/robotpy/BUILD.bazel b/shared/bazel/rules/robotpy/BUILD.bazel index 95cb4631aa6..b214e3ffdb8 100644 --- a/shared/bazel/rules/robotpy/BUILD.bazel +++ b/shared/bazel/rules/robotpy/BUILD.bazel @@ -1,4 +1,5 @@ load("@allwpilib_pip_deps//:requirements.bzl", "requirement", "whl_requirement") +load("@platforms//host:constraints.bzl", "HOST_CONSTRAINTS") load("@rules_cc//cc:cc_library.bzl", "cc_library") load("@rules_python//python:defs.bzl", "py_binary", "py_library") load("@rules_python//python:pip.bzl", "whl_filegroup") @@ -8,6 +9,12 @@ exports_files([ "version_template.in", ]) +config_setting( + name = "host_platform", + constraint_values = HOST_CONSTRAINTS, + visibility = ["//visibility:public"], +) + py_library( name = "hack_pkgcfgs", srcs = ["hack_pkgcfgs.py"], diff --git a/shared/bazel/rules/robotpy/compatibility_select.bzl b/shared/bazel/rules/robotpy/compatibility_select.bzl index 59daa611970..96a8ef65e54 100644 --- a/shared/bazel/rules/robotpy/compatibility_select.bzl +++ b/shared/bazel/rules/robotpy/compatibility_select.bzl @@ -1,6 +1,17 @@ +load("@platforms//host:constraints.bzl", "HOST_CONSTRAINTS") + def robotpy_compatibility_select(): return select({ "@bazel_tools//src/conditions:windows": ["@platforms//:incompatible"], "@wpilib_toolchains//constraints/is_systemcore:systemcore": ["@platforms//:incompatible"], "//conditions:default": [], }) + +def robotpy_host_only_select(values): + return select({ + "//shared/bazel/rules/robotpy:host_platform": values, + "//conditions:default": [], + }) + +def robotpy_host_compatibility(): + return HOST_CONSTRAINTS + robotpy_compatibility_select() diff --git a/shared/bazel/rules/robotpy/generate_pybind_build_file.py b/shared/bazel/rules/robotpy/generate_pybind_build_file.py index e9f4d6e36c3..5aaec5014fa 100644 --- a/shared/bazel/rules/robotpy/generate_pybind_build_file.py +++ b/shared/bazel/rules/robotpy/generate_pybind_build_file.py @@ -13,7 +13,9 @@ CppMacroValue, Entrypoint, ExtensionModule, + InputFile, LocalDependency, + OutputFile, makeplan, ) from semiwrap.pkgconf_cache import PkgconfCache @@ -166,6 +168,66 @@ def __init__(self, item: BuildTarget): assert 0 == len(item.args[idx:]) +class MakePyiConfig: + def __init__( + self, + item: BuildTarget, + project_dir: pathlib.Path, + stripped_include_prefix: str, + ): + args = item.args + self.package_name = args[0] + self.output_files = [] + + idx = 1 + while args[idx] != "--": + output = args[idx + 1] + assert isinstance(output, OutputFile) + output_path = ( + pathlib.PurePosixPath(stripped_include_prefix) + / item.install_path + / output.name + ).as_posix() + self.output_files.append((args[idx], output_path)) + idx += 2 + + self.module_files = [] + idx += 1 + while idx < len(args): + module_name = args[idx] + module = args[idx + 1] + + if isinstance(module, InputFile): + module_path = ( + pathlib.PurePosixPath(stripped_include_prefix) / module.path + ) + elif isinstance(module, (str, pathlib.Path)): + source_path = pathlib.Path(module) + if source_path.is_absolute(): + source_path = source_path.relative_to(project_dir.resolve()) + module_path = ( + pathlib.PurePosixPath(stripped_include_prefix) / source_path + ) + elif isinstance(module, BuildTarget): + output = next(arg for arg in module.args if isinstance(arg, OutputFile)) + module_path = ( + pathlib.PurePosixPath(stripped_include_prefix) + / module.install_path + / output.name + ) + elif isinstance(module, ExtensionModule): + module_path = ( + pathlib.PurePosixPath(stripped_include_prefix) + / module.install_path + / module.package_name.rsplit(".", 1)[-1] + ) + else: + raise TypeError(f"Unknown make-pyi module type {type(module)}") + + self.module_files.append((module_name, module_path.as_posix())) + idx += 2 + + class PublishCastersConfig: def __init__(self, projectcfg, item: BuildTarget): self.project_file = item.args[0].path @@ -238,11 +300,12 @@ def __init__( local_extension_dependencies.add(f"//{base_library}:{dep_name}") else: base_library = fixup_root_package_name(dep_name.split("_")[0]) + shared_lib_name = fixup_shared_lib_name(base_library) local_extension_dependencies.add( - f"//{base_library}:{fixup_shared_lib_name(base_library)}" + f"//{base_library}:{shared_lib_name}" ) dynamic_dependencies.add( - f"//{base_library}:shared/{fixup_shared_lib_name(base_library)}" + f"//{base_library}:shared/{shared_lib_name}" ) if dep_name != self.name: local_extension_dependencies.add( @@ -334,6 +397,7 @@ def generate_pybind_build_file( # Cache built up for an extension module. Gets reset when an ExtensionModule is encountered additional_extension_targets: dict[str, BuildTarget] = {} publish_casters_targets = [] + make_pyi_targets = [] for item in plan: if isinstance(item, ExtensionModule): @@ -351,13 +415,16 @@ def generate_pybind_build_file( if item.command in additional_extension_targets: raise RuntimeError(f"Repeated target {item.command}") additional_extension_targets[item.command] = item + elif item.command == "make-pyi": + make_pyi_targets.append( + MakePyiConfig(item, project_dir, stripped_include_prefix) + ) elif item.command in [ "header2dat", "dat2cpp", "dat2tmplcpp", "dat2tmplhpp", "dat2trampoline", - "make-pyi", ]: pass elif item.command == "publish-casters": @@ -454,6 +521,7 @@ def target_from_python_dep(python_dep): extension_modules=extension_modules, top_level_name=top_level_name, publish_casters_targets=publish_casters_targets, + make_pyi_targets=make_pyi_targets, python_deps=sorted(python_deps), all_local_native_deps=all_local_native_deps, stripped_include_prefix=stripped_include_prefix, diff --git a/shared/bazel/rules/robotpy/generation_utils.py b/shared/bazel/rules/robotpy/generation_utils.py index a6eaf9d9ad2..ec1eea9486f 100644 --- a/shared/bazel/rules/robotpy/generation_utils.py +++ b/shared/bazel/rules/robotpy/generation_utils.py @@ -13,6 +13,8 @@ def fixup_root_package_name(name): return "ntcore" if name == "halsim-ws": return "simulation/halsim_ws_core" + if name == "halsim": + return "simulation/halsim_gui" if name == "halsim_gui": return "simulation/halsim_gui" if name == "wpimath_test": @@ -41,6 +43,8 @@ def fixup_shared_lib_name(name): return "xrpVendordep" if name == "romi": return "romiVendordep" + if name == "simulation/halsim_gui": + return "halsim_gui" return name diff --git a/shared/bazel/rules/robotpy/pybind_build_file_template.jinja2 b/shared/bazel/rules/robotpy/pybind_build_file_template.jinja2 index 438a37171c3..76a77613e92 100644 --- a/shared/bazel/rules/robotpy/pybind_build_file_template.jinja2 +++ b/shared/bazel/rules/robotpy/pybind_build_file_template.jinja2 @@ -9,7 +9,7 @@ load("@rules_cc//cc:cc_library.bzl", "cc_library") load("//shared/bazel/rules/gen:gen-version-file.bzl", "generate_version_file") {%- endif %} load("//shared/bazel/rules/robotpy:robotpy_rules.bzl", "create_pybind_library", "robotpy_library") -load("//shared/bazel/rules/robotpy:semiwrap_helpers.bzl", "gen_libinit", "gen_modinit_hpp", "gen_pkgconf", {% if publish_casters_targets %}"publish_casters", {% endif %}"resolve_casters", "run_header_gen") +load("//shared/bazel/rules/robotpy:semiwrap_helpers.bzl", "gen_libinit", "gen_modinit_hpp", "gen_pkgconf", "make_pyi", {% if publish_casters_targets %}"publish_casters", {% endif %}"resolve_casters", "run_header_gen") load("//shared/bazel/rules/robotpy:semiwrap_tool_helpers.bzl", "scan_headers", "update_yaml_files") {% for extension_module in extension_modules%} def {{extension_module.name}}_extension(srcs = [], header_to_dat_deps = [], extra_hdrs = [], includes = []): @@ -103,7 +103,7 @@ def {{extension_module.name}}_extension(srcs = [], header_to_dat_deps = [], extr name = "{{extension_module.name}}", install_path = "{{stripped_include_prefix}}/{{extension_module.install_path}}/", extension_name = "{{ extension_module.gen_modinit.lib_name }}", - generated_srcs = [":{{extension_module.name}}.generated_srcs"], + generated_srcs = {% if extension_module.generation_data %}[":{{extension_module.name}}.generated_srcs"]{% else %}[]{% endif %}, semiwrap_header = [":{{extension_module.name}}.gen_modinit_hpp"], deps = [ ":{{extension_module.name}}.tmpl_hdrs", @@ -156,7 +156,7 @@ def publish_library_casters(): tags = ["robotpy"], ) {% endfor %} -def define_pybind_library(name, pkgcfgs = [], extra_pybind_hdrs = []): +def define_pybind_library(name, pkgcfgs = [], extra_pybind_hdrs = [], extra_pyi_deps = []): # Helper used to generate all files with one target. native.filegroup( name = "{}.generated_files".format(name), @@ -198,6 +198,15 @@ def define_pybind_library(name, pkgcfgs = [], extra_pybind_hdrs = []): template = "//shared/bazel/rules/robotpy:version_template.in", ) {% endif %} +{%- for pyi_target in make_pyi_targets %} + make_pyi( + name = "{{pyi_target.package_name}}.make_pyi", + package_name = "{{pyi_target.package_name}}", + output_files = {{pyi_target.output_files | jsonify}}, + module_files = {{pyi_target.module_files | jsonify}}, + runner = ":{}.make_pyi_runner".format(name), + ) +{% endfor %} robotpy_library( name = name, distribution = "{{raw_project_config.name}}", @@ -219,6 +228,12 @@ def define_pybind_library(name, pkgcfgs = [], extra_pybind_hdrs = []): ":{{em.name}}.trampoline_hdr_files", {%- endfor %} ], + pyi_srcs = [ + {%- for pyi_target in make_pyi_targets %} + ":{{pyi_target.package_name}}.make_pyi", + {%- endfor %} + ], + pyi_deps = extra_pyi_deps, imports = ["{{stripped_include_prefix}}"], deps = [ {%- for d in python_deps %} @@ -250,7 +265,7 @@ def define_pybind_library(name, pkgcfgs = [], extra_pybind_hdrs = []): package_root_file = "{{package_root_file}}", pkgcfgs = pkgcfgs, pyproject_toml = "{{ stripped_include_prefix }}/pyproject.toml", - yaml_files = native.glob(["{{stripped_include_prefix}}/semiwrap/**"]), + yaml_files = native.glob(["{{stripped_include_prefix}}/semiwrap/**"], allow_empty = True), ) scan_headers( diff --git a/shared/bazel/rules/robotpy/robotpy_rules.bzl b/shared/bazel/rules/robotpy/robotpy_rules.bzl index 6921091690f..156c3309921 100644 --- a/shared/bazel/rules/robotpy/robotpy_rules.bzl +++ b/shared/bazel/rules/robotpy/robotpy_rules.bzl @@ -1,9 +1,10 @@ +load("@allwpilib_pip_deps//:requirements.bzl", "requirement") load("@bazel_lib//lib:copy_file.bzl", "copy_file") load("@pybind11_bazel//:build_defs.bzl", "pybind_extension", "pybind_library") load("@rules_pycross//pycross:defs.bzl", "pycross_wheel_library") -load("@rules_python//python:defs.bzl", "py_library") +load("@rules_python//python:defs.bzl", "py_binary", "py_library") load("@rules_python//python:packaging.bzl", "py_wheel") -load("//shared/bazel/rules/robotpy:compatibility_select.bzl", "robotpy_compatibility_select") +load("//shared/bazel/rules/robotpy:compatibility_select.bzl", "robotpy_compatibility_select", "robotpy_host_only_select") def create_pybind_library( name, @@ -86,6 +87,8 @@ def robotpy_library( name, deps = [], data = [], + pyi_srcs = [], + pyi_deps = [], strip_path_prefixes = None, distribution = None, summary = None, @@ -103,9 +106,26 @@ def robotpy_library( - The python library -wheel - A wheel for the library """ + host_pyi_srcs = robotpy_host_only_select(pyi_srcs) + + if pyi_srcs: + py_binary( + name = name + ".make_pyi_runner", + srcs = ["//shared/bazel/rules/robotpy:wrapper.py"], + main = "//shared/bazel/rules/robotpy:wrapper.py", + data = data, + deps = deps + pyi_deps + [ + "//shared/bazel/rules/robotpy:hack_pkgcfgs", + requirement("numpy"), + requirement("semiwrap"), + ], + tags = ["manual", "robotpy"], + target_compatible_with = robotpy_compatibility_select(), + ) + py_library( name = name + "-lib", - data = data, + data = data + host_pyi_srcs, deps = deps, tags = ["robotpy"], **kwargs @@ -120,7 +140,7 @@ def robotpy_library( requires = requires, project_urls = project_urls, author_email = author_email, - deps = data + [":{}-lib".format(name)], + deps = data + host_pyi_srcs + [":{}-lib".format(name)], strip_path_prefixes = strip_path_prefixes, entry_points = entry_points, description_file = description_file, diff --git a/shared/bazel/rules/robotpy/semiwrap_helpers.bzl b/shared/bazel/rules/robotpy/semiwrap_helpers.bzl index 0812171a0b1..531c1fcbf88 100644 --- a/shared/bazel/rules/robotpy/semiwrap_helpers.bzl +++ b/shared/bazel/rules/robotpy/semiwrap_helpers.bzl @@ -1,5 +1,5 @@ load("@rules_cc//cc:defs.bzl", "cc_library") -load("//shared/bazel/rules/robotpy:compatibility_select.bzl", "robotpy_compatibility_select") +load("//shared/bazel/rules/robotpy:compatibility_select.bzl", "robotpy_compatibility_select", "robotpy_host_compatibility") RESOLVE_CASTERS_DIR = "generated/resolve_casters/" HEADER_DAT_DIR = "generated/header_to_dat/" @@ -8,6 +8,60 @@ DAT_TO_TMPL_CC_DIR = "generated/dat_to_tmpl_cc/" DAT_TO_TMPL_HDR_DIR = "generated/dat_to_tmpl_hdr/" GEN_MODINIT_HDR_DIR = "generated/gen_modinit_hdr/" +def _make_pyi_impl(ctx): + args = ctx.actions.args() + args.add("semiwrap.cmd.make_pyi") + args.add(ctx.attr.package_name) + for stub_path, output_file in zip(ctx.attr.stub_paths, ctx.outputs.outs): + args.add(stub_path) + args.add(output_file.path) + args.add("--") + + module_inputs = [] + for module_name, module_target in zip(ctx.attr.module_names, ctx.attr.module_files): + module_files = module_target.files.to_list() + if len(module_files) != 1: + fail("make_pyi module {} must provide exactly one file".format(module_name)) + module_file = module_files[0] + module_inputs.append(module_file) + args.add(module_name) + args.add(module_file.path) + + ctx.actions.run( + arguments = [args], + executable = ctx.executable.runner, + inputs = module_inputs, + mnemonic = "MakePyi", + outputs = ctx.outputs.outs, + progress_message = "Generating Python stubs for {}".format(ctx.attr.package_name), + ) + +_make_pyi = rule( + implementation = _make_pyi_impl, + attrs = { + "module_files": attr.label_list(allow_files = True, cfg = "target"), + "module_names": attr.string_list(), + "outs": attr.output_list(mandatory = True), + "package_name": attr.string(mandatory = True), + "runner": attr.label(executable = True, cfg = "target", mandatory = True), + "stub_paths": attr.string_list(), + }, +) + +def make_pyi(name, package_name, output_files, module_files, runner): + """Runs semiwrap's pybind11-stubgen wrapper for a compiled extension.""" + _make_pyi( + name = name, + module_files = [module_file for _, module_file in module_files], + module_names = [module_name for module_name, _ in module_files], + outs = [output_file for _, output_file in output_files], + package_name = package_name, + runner = runner, + stub_paths = [stub_path for stub_path, _ in output_files], + target_compatible_with = robotpy_host_compatibility(), + tags = ["robotpy"], + ) + def _location_helper(filename): return " $(locations " + filename + ")" diff --git a/simulation/halsim_gui/BUILD.bazel b/simulation/halsim_gui/BUILD.bazel index fbc3e8cc9f7..814599a298e 100644 --- a/simulation/halsim_gui/BUILD.bazel +++ b/simulation/halsim_gui/BUILD.bazel @@ -3,7 +3,7 @@ load("@rules_cc//cc:defs.bzl", "cc_binary", "cc_test") load("//shared/bazel/rules:cc_rules.bzl", "wpilib_cc_library", "wpilib_cc_shared_library", "wpilib_cc_static_library") load("//shared/bazel/rules:packaging.bzl", "package_default_cc_project") load("//shared/bazel/rules:publishing.bzl", "host_architectures") -load("//shared/bazel/rules/robotpy:build_info_gen.bzl", "generate_robotpy_native_wrapper_build_info") +load("//shared/bazel/rules/robotpy:build_info_gen.bzl", "generate_robotpy_native_wrapper_build_info", "generate_robotpy_pybind_build_info") load("//shared/bazel/rules/robotpy:pytest_util.bzl", "robotpy_py_test") load("//simulation/halsim_gui:robotpy_native_build_info.bzl", "define_native_wrapper") load("//simulation/halsim_gui:robotpy_pybind_build_info.bzl", "define_pybind_library", "halsim_gui_ext_extension") @@ -149,6 +149,13 @@ PKG_CONFIG_DEPS = [ "//wpiutil:robotpy-wpiutil.generated_pkgcfg_files", ] +generate_robotpy_pybind_build_info( + name = "robotpy-halsim-gui-generator", + package_root_file = "src/main/python/halsim_gui/_ext/__init__.py", + pkgcfgs = PKG_CONFIG_DEPS, + pyproject_toml = "src/main/python/pyproject.toml", +) + halsim_gui_ext_extension( srcs = glob(["src/main/python/halsim_gui/_ext/**/*.cpp"]), ) diff --git a/simulation/halsim_gui/robotpy_pybind_build_info.bzl b/simulation/halsim_gui/robotpy_pybind_build_info.bzl index 205790e71a9..5af66031b0a 100644 --- a/simulation/halsim_gui/robotpy_pybind_build_info.bzl +++ b/simulation/halsim_gui/robotpy_pybind_build_info.bzl @@ -2,7 +2,8 @@ load("//shared/bazel/rules/gen:gen-version-file.bzl", "generate_version_file") load("//shared/bazel/rules/robotpy:robotpy_rules.bzl", "create_pybind_library", "robotpy_library") -load("//shared/bazel/rules/robotpy:semiwrap_helpers.bzl", "gen_libinit", "gen_modinit_hpp", "gen_pkgconf", "resolve_casters", "run_header_gen") +load("//shared/bazel/rules/robotpy:semiwrap_helpers.bzl", "gen_libinit", "gen_modinit_hpp", "gen_pkgconf", "make_pyi", "resolve_casters", "run_header_gen") +load("//shared/bazel/rules/robotpy:semiwrap_tool_helpers.bzl", "scan_headers", "update_yaml_files") def halsim_gui_ext_extension(srcs = [], header_to_dat_deps = [], extra_hdrs = [], includes = []): NAME_TRANSFORMS = [ @@ -79,8 +80,8 @@ def halsim_gui_ext_extension(srcs = [], header_to_dat_deps = [], extra_hdrs = [] ], dynamic_deps = [ "//hal:shared/wpiHal", - "//simulation/halsim_gui:shared/halsim_gui", "//ntcore:shared/ntcore", + "//simulation/halsim_gui:shared/halsim_gui", "//wpimath:shared/wpimath", ], extra_hdrs = extra_hdrs, @@ -99,7 +100,7 @@ def halsim_gui_ext_extension(srcs = [], header_to_dat_deps = [], extra_hdrs = [] tags = ["manual", "robotpy"], ) -def define_pybind_library(name, pkgcfgs = []): +def define_pybind_library(name, pkgcfgs = [], extra_pybind_hdrs = [], extra_pyi_deps = []): # Helper used to generate all files with one target. native.filegroup( name = "{}.generated_files".format(name), @@ -133,6 +134,14 @@ def define_pybind_library(name, pkgcfgs = []): template = "//shared/bazel/rules/robotpy:version_template.in", ) + make_pyi( + name = "halsim_gui._ext._halsim_gui_ext.make_pyi", + package_name = "halsim_gui._ext._halsim_gui_ext", + output_files = [["halsim_gui/_ext/_halsim_gui_ext.pyi", "src/main/python/halsim_gui/_ext/_halsim_gui_ext.pyi"]], + module_files = [["halsim_gui._ext", "src/main/python/halsim_gui/_ext/__init__.py"], ["halsim_gui._ext._init__halsim_gui_ext", "src/main/python/halsim_gui/_ext/_init__halsim_gui_ext.py"], ["halsim_gui._ext._halsim_gui_ext", "src/main/python/halsim_gui/_ext/_halsim_gui_ext"]], + runner = ":{}.make_pyi_runner".format(name), + ) + robotpy_library( name = name, distribution = "robotpy-halsim-gui", @@ -146,11 +155,15 @@ def define_pybind_library(name, pkgcfgs = []): ":src/main/python/halsim_gui/_ext/_halsim_gui_ext", ":halsim_gui_ext.trampoline_hdr_files", ], + pyi_srcs = [ + ":halsim_gui._ext._halsim_gui_ext.make_pyi", + ], + pyi_deps = extra_pyi_deps, imports = ["src/main/python"], deps = [ "//hal:robotpy-hal", - "//simulation/halsim_gui:robotpy-native-halsim-gui", "//ntcore:pyntcore", + "//simulation/halsim_gui:robotpy-native-halsim-gui", "//wpimath:robotpy-wpimath", "//wpiutil:robotpy-wpiutil", ], @@ -165,3 +178,31 @@ def define_pybind_library(name, pkgcfgs = []): }, visibility = ["//visibility:public"], ) + + update_yaml_files( + name = "{}-update-yaml".format(name), + yaml_output_directory = "src/main/python/semiwrap", + extra_hdrs = extra_pybind_hdrs + [ + "//datalog:robotpy-native-datalog.copy_headers", + "//hal:robotpy-native-wpihal.copy_headers", + "//ntcore:robotpy-native-ntcore.copy_headers", + "//simulation/halsim_gui:robotpy-native-halsim-gui.copy_headers", + "//wpimath:robotpy-native-wpimath.copy_headers", + "//wpinet:robotpy-native-wpinet.copy_headers", + "//wpiutil:robotpy-native-wpiutil.copy_headers", + ], + package_root_file = "src/main/python/halsim_gui/_ext/__init__.py", + pkgcfgs = pkgcfgs, + pyproject_toml = "src/main/python/pyproject.toml", + yaml_files = native.glob(["src/main/python/semiwrap/**"], allow_empty = True), + ) + + scan_headers( + name = "{}-scan-headers".format(name), + extra_hdrs = extra_pybind_hdrs + [ + "//simulation/halsim_gui:robotpy-native-halsim-gui.copy_headers", + ], + package_root_file = "src/main/python/halsim_gui/_ext/__init__.py", + pkgcfgs = pkgcfgs, + pyproject_toml = "src/main/python/pyproject.toml", + ) diff --git a/wpilibc/robotpy_pybind_build_info.bzl b/wpilibc/robotpy_pybind_build_info.bzl index c72660f067a..25b92bc9405 100644 --- a/wpilibc/robotpy_pybind_build_info.bzl +++ b/wpilibc/robotpy_pybind_build_info.bzl @@ -3,7 +3,7 @@ load("@allwpilib_pip_deps//:requirements.bzl", "requirement") load("//shared/bazel/rules/gen:gen-version-file.bzl", "generate_version_file") load("//shared/bazel/rules/robotpy:robotpy_rules.bzl", "create_pybind_library", "robotpy_library") -load("//shared/bazel/rules/robotpy:semiwrap_helpers.bzl", "gen_libinit", "gen_modinit_hpp", "gen_pkgconf", "resolve_casters", "run_header_gen") +load("//shared/bazel/rules/robotpy:semiwrap_helpers.bzl", "gen_libinit", "gen_modinit_hpp", "gen_pkgconf", "make_pyi", "resolve_casters", "run_header_gen") load("//shared/bazel/rules/robotpy:semiwrap_tool_helpers.bzl", "scan_headers", "update_yaml_files") def wpilib_extension(srcs = [], header_to_dat_deps = [], extra_hdrs = [], includes = []): @@ -1958,7 +1958,7 @@ def wpilib_simulation_extension(srcs = [], header_to_dat_deps = [], extra_hdrs = tags = ["manual", "robotpy"], ) -def define_pybind_library(name, pkgcfgs = [], extra_pybind_hdrs = []): +def define_pybind_library(name, pkgcfgs = [], extra_pybind_hdrs = [], extra_pyi_deps = []): # Helper used to generate all files with one target. native.filegroup( name = "{}.generated_files".format(name), @@ -1994,6 +1994,22 @@ def define_pybind_library(name, pkgcfgs = [], extra_pybind_hdrs = []): template = "//shared/bazel/rules/robotpy:version_template.in", ) + make_pyi( + name = "wpilib._wpilib.make_pyi", + package_name = "wpilib._wpilib", + output_files = [["wpilib/_wpilib/__init__.pyi", "src/main/python/wpilib/_wpilib/__init__.pyi"], ["wpilib/_wpilib/sysid.pyi", "src/main/python/wpilib/_wpilib/sysid.pyi"]], + module_files = [["wpilib", "src/main/python/wpilib/__init__.py"], ["wpilib._init__wpilib", "src/main/python/wpilib/_init__wpilib.py"], ["wpilib._wpilib", "src/main/python/wpilib/_wpilib"], ["wpilib.simulation", "src/main/python/wpilib/simulation/__init__.py"], ["wpilib.simulation._init__simulation", "src/main/python/wpilib/simulation/_init__simulation.py"], ["wpilib.simulation._simulation", "src/main/python/wpilib/simulation/_simulation"]], + runner = ":{}.make_pyi_runner".format(name), + ) + + make_pyi( + name = "wpilib.simulation._simulation.make_pyi", + package_name = "wpilib.simulation._simulation", + output_files = [["wpilib/simulation/_simulation.pyi", "src/main/python/wpilib/simulation/_simulation.pyi"]], + module_files = [["wpilib", "src/main/python/wpilib/__init__.py"], ["wpilib._init__wpilib", "src/main/python/wpilib/_init__wpilib.py"], ["wpilib._wpilib", "src/main/python/wpilib/_wpilib"], ["wpilib.simulation", "src/main/python/wpilib/simulation/__init__.py"], ["wpilib.simulation._init__simulation", "src/main/python/wpilib/simulation/_init__simulation.py"], ["wpilib.simulation._simulation", "src/main/python/wpilib/simulation/_simulation"]], + runner = ":{}.make_pyi_runner".format(name), + ) + robotpy_library( name = name, distribution = "wpilib", @@ -2010,6 +2026,11 @@ def define_pybind_library(name, pkgcfgs = [], extra_pybind_hdrs = []): ":wpilib.trampoline_hdr_files", ":wpilib_simulation.trampoline_hdr_files", ], + pyi_srcs = [ + ":wpilib._wpilib.make_pyi", + ":wpilib.simulation._simulation.make_pyi", + ], + pyi_deps = extra_pyi_deps, imports = ["src/main/python"], deps = [ "//hal:robotpy-hal", @@ -2049,7 +2070,7 @@ def define_pybind_library(name, pkgcfgs = [], extra_pybind_hdrs = []): package_root_file = "src/main/python/wpilib/__init__.py", pkgcfgs = pkgcfgs, pyproject_toml = "src/main/python/pyproject.toml", - yaml_files = native.glob(["src/main/python/semiwrap/**"]), + yaml_files = native.glob(["src/main/python/semiwrap/**"], allow_empty = True), ) scan_headers( diff --git a/wpimath/BUILD.bazel b/wpimath/BUILD.bazel index be711714ca8..61c49452549 100644 --- a/wpimath/BUILD.bazel +++ b/wpimath/BUILD.bazel @@ -414,6 +414,7 @@ wpimath_test_extension( define_test_pybind_library( name = "robotpy-wpimath-test", extra_pybind_hdrs = glob(["src/test/python/cpp/**/*.h"]), + extra_pyi_deps = [":robotpy-wpimath-lib"], pkgcfgs = [ "//wpimath:native/wpimath/robotpy-native-wpimath.pc", "//wpimath:robotpy-wpimath.generated_pkgcfg_files", diff --git a/wpimath/robotpy_pybind_build_info.bzl b/wpimath/robotpy_pybind_build_info.bzl index b3c0866235c..2d12e86890a 100644 --- a/wpimath/robotpy_pybind_build_info.bzl +++ b/wpimath/robotpy_pybind_build_info.bzl @@ -3,7 +3,7 @@ load("@rules_cc//cc:cc_library.bzl", "cc_library") load("//shared/bazel/rules/gen:gen-version-file.bzl", "generate_version_file") load("//shared/bazel/rules/robotpy:robotpy_rules.bzl", "create_pybind_library", "robotpy_library") -load("//shared/bazel/rules/robotpy:semiwrap_helpers.bzl", "gen_libinit", "gen_modinit_hpp", "gen_pkgconf", "publish_casters", "resolve_casters", "run_header_gen") +load("//shared/bazel/rules/robotpy:semiwrap_helpers.bzl", "gen_libinit", "gen_modinit_hpp", "gen_pkgconf", "make_pyi", "publish_casters", "resolve_casters", "run_header_gen") load("//shared/bazel/rules/robotpy:semiwrap_tool_helpers.bzl", "scan_headers", "update_yaml_files") def wpimath_extension(srcs = [], header_to_dat_deps = [], extra_hdrs = [], includes = []): @@ -1402,7 +1402,7 @@ def publish_library_casters(): tags = ["robotpy"], ) -def define_pybind_library(name, pkgcfgs = [], extra_pybind_hdrs = []): +def define_pybind_library(name, pkgcfgs = [], extra_pybind_hdrs = [], extra_pyi_deps = []): # Helper used to generate all files with one target. native.filegroup( name = "{}.generated_files".format(name), @@ -1438,6 +1438,14 @@ def define_pybind_library(name, pkgcfgs = [], extra_pybind_hdrs = []): template = "//shared/bazel/rules/robotpy:version_template.in", ) + make_pyi( + name = "wpimath._wpimath.make_pyi", + package_name = "wpimath._wpimath", + output_files = [["wpimath/_wpimath.pyi", "src/main/python/wpimath/_wpimath.pyi"]], + module_files = [["wpimath", "src/main/python/wpimath/__init__.py"], ["wpimath._init__wpimath", "src/main/python/wpimath/_init__wpimath.py"], ["wpimath._wpimath", "src/main/python/wpimath/_wpimath"]], + runner = ":{}.make_pyi_runner".format(name), + ) + robotpy_library( name = name, distribution = "robotpy-wpimath", @@ -1451,6 +1459,10 @@ def define_pybind_library(name, pkgcfgs = [], extra_pybind_hdrs = []): ":src/main/python/wpimath/_wpimath", ":wpimath.trampoline_hdr_files", ], + pyi_srcs = [ + ":wpimath._wpimath.make_pyi", + ], + pyi_deps = extra_pyi_deps, imports = ["src/main/python"], deps = [ "//wpimath:robotpy-native-wpimath", @@ -1478,7 +1490,7 @@ def define_pybind_library(name, pkgcfgs = [], extra_pybind_hdrs = []): package_root_file = "src/main/python/wpimath/__init__.py", pkgcfgs = pkgcfgs, pyproject_toml = "src/main/python/pyproject.toml", - yaml_files = native.glob(["src/main/python/semiwrap/**"]), + yaml_files = native.glob(["src/main/python/semiwrap/**"], allow_empty = True), ) scan_headers( diff --git a/wpimath/robotpy_pybind_test_info.bzl b/wpimath/robotpy_pybind_test_info.bzl index 9e3a0eb01ba..58116531c6d 100644 --- a/wpimath/robotpy_pybind_test_info.bzl +++ b/wpimath/robotpy_pybind_test_info.bzl @@ -1,7 +1,7 @@ # THIS FILE IS AUTO GENERATED load("//shared/bazel/rules/robotpy:robotpy_rules.bzl", "create_pybind_library", "robotpy_library") -load("//shared/bazel/rules/robotpy:semiwrap_helpers.bzl", "gen_libinit", "gen_modinit_hpp", "gen_pkgconf", "resolve_casters", "run_header_gen") +load("//shared/bazel/rules/robotpy:semiwrap_helpers.bzl", "gen_libinit", "gen_modinit_hpp", "gen_pkgconf", "make_pyi", "resolve_casters", "run_header_gen") load("//shared/bazel/rules/robotpy:semiwrap_tool_helpers.bzl", "scan_headers", "update_yaml_files") def wpimath_test_extension(srcs = [], header_to_dat_deps = [], extra_hdrs = [], includes = []): @@ -99,7 +99,7 @@ def wpimath_test_extension(srcs = [], header_to_dat_deps = [], extra_hdrs = [], tags = ["manual", "robotpy"], ) -def define_pybind_library(name, pkgcfgs = [], extra_pybind_hdrs = []): +def define_pybind_library(name, pkgcfgs = [], extra_pybind_hdrs = [], extra_pyi_deps = []): # Helper used to generate all files with one target. native.filegroup( name = "{}.generated_files".format(name), @@ -127,6 +127,14 @@ def define_pybind_library(name, pkgcfgs = [], extra_pybind_hdrs = []): tags = ["manual", "robotpy"], ) + make_pyi( + name = "wpimath_test._wpimath_test.make_pyi", + package_name = "wpimath_test._wpimath_test", + output_files = [["wpimath_test/_wpimath_test.pyi", "src/test/python/cpp/wpimath_test/_wpimath_test.pyi"]], + module_files = [["wpimath_test", "src/test/python/cpp/wpimath_test/__init__.py"], ["wpimath_test._init__wpimath_test", "src/test/python/cpp/wpimath_test/_init__wpimath_test.py"], ["wpimath_test._wpimath_test", "src/test/python/cpp/wpimath_test/_wpimath_test"]], + runner = ":{}.make_pyi_runner".format(name), + ) + robotpy_library( name = name, distribution = "wpimath_test", @@ -139,6 +147,10 @@ def define_pybind_library(name, pkgcfgs = [], extra_pybind_hdrs = []): ":src/test/python/cpp/wpimath_test/_wpimath_test", ":wpimath_test.trampoline_hdr_files", ], + pyi_srcs = [ + ":wpimath_test._wpimath_test.make_pyi", + ], + pyi_deps = extra_pyi_deps, imports = ["src/test/python/cpp"], deps = [ ], @@ -162,7 +174,7 @@ def define_pybind_library(name, pkgcfgs = [], extra_pybind_hdrs = []): package_root_file = "src/test/python/cpp/wpimath_test/__init__.py", pkgcfgs = pkgcfgs, pyproject_toml = "src/test/python/cpp/pyproject.toml", - yaml_files = native.glob(["src/test/python/cpp/semiwrap/**"]), + yaml_files = native.glob(["src/test/python/cpp/semiwrap/**"], allow_empty = True), ) scan_headers( diff --git a/wpinet/robotpy_pybind_build_info.bzl b/wpinet/robotpy_pybind_build_info.bzl index 2199fc24895..8fc9f451971 100644 --- a/wpinet/robotpy_pybind_build_info.bzl +++ b/wpinet/robotpy_pybind_build_info.bzl @@ -2,7 +2,7 @@ load("//shared/bazel/rules/gen:gen-version-file.bzl", "generate_version_file") load("//shared/bazel/rules/robotpy:robotpy_rules.bzl", "create_pybind_library", "robotpy_library") -load("//shared/bazel/rules/robotpy:semiwrap_helpers.bzl", "gen_libinit", "gen_modinit_hpp", "gen_pkgconf", "resolve_casters", "run_header_gen") +load("//shared/bazel/rules/robotpy:semiwrap_helpers.bzl", "gen_libinit", "gen_modinit_hpp", "gen_pkgconf", "make_pyi", "resolve_casters", "run_header_gen") load("//shared/bazel/rules/robotpy:semiwrap_tool_helpers.bzl", "scan_headers", "update_yaml_files") def wpinet_extension(srcs = [], header_to_dat_deps = [], extra_hdrs = [], includes = []): @@ -169,7 +169,7 @@ def wpinet_extension(srcs = [], header_to_dat_deps = [], extra_hdrs = [], includ tags = ["manual", "robotpy"], ) -def define_pybind_library(name, pkgcfgs = [], extra_pybind_hdrs = []): +def define_pybind_library(name, pkgcfgs = [], extra_pybind_hdrs = [], extra_pyi_deps = []): # Helper used to generate all files with one target. native.filegroup( name = "{}.generated_files".format(name), @@ -203,6 +203,14 @@ def define_pybind_library(name, pkgcfgs = [], extra_pybind_hdrs = []): template = "//shared/bazel/rules/robotpy:version_template.in", ) + make_pyi( + name = "wpinet._wpinet.make_pyi", + package_name = "wpinet._wpinet", + output_files = [["wpinet/_wpinet.pyi", "src/main/python/wpinet/_wpinet.pyi"]], + module_files = [["wpinet", "src/main/python/wpinet/__init__.py"], ["wpinet._init__wpinet", "src/main/python/wpinet/_init__wpinet.py"], ["wpinet._wpinet", "src/main/python/wpinet/_wpinet"]], + runner = ":{}.make_pyi_runner".format(name), + ) + robotpy_library( name = name, distribution = "robotpy-wpinet", @@ -216,6 +224,10 @@ def define_pybind_library(name, pkgcfgs = [], extra_pybind_hdrs = []): ":src/main/python/wpinet/_wpinet", ":wpinet.trampoline_hdr_files", ], + pyi_srcs = [ + ":wpinet._wpinet.make_pyi", + ], + pyi_deps = extra_pyi_deps, imports = ["src/main/python"], deps = [ "//wpinet:robotpy-native-wpinet", @@ -243,7 +255,7 @@ def define_pybind_library(name, pkgcfgs = [], extra_pybind_hdrs = []): package_root_file = "src/main/python/wpinet/__init__.py", pkgcfgs = pkgcfgs, pyproject_toml = "src/main/python/pyproject.toml", - yaml_files = native.glob(["src/main/python/semiwrap/**"]), + yaml_files = native.glob(["src/main/python/semiwrap/**"], allow_empty = True), ) scan_headers( diff --git a/wpiutil/robotpy_pybind_build_info.bzl b/wpiutil/robotpy_pybind_build_info.bzl index bc95892dcea..11629fbe86d 100644 --- a/wpiutil/robotpy_pybind_build_info.bzl +++ b/wpiutil/robotpy_pybind_build_info.bzl @@ -3,7 +3,7 @@ load("@rules_cc//cc:cc_library.bzl", "cc_library") load("//shared/bazel/rules/gen:gen-version-file.bzl", "generate_version_file") load("//shared/bazel/rules/robotpy:robotpy_rules.bzl", "create_pybind_library", "robotpy_library") -load("//shared/bazel/rules/robotpy:semiwrap_helpers.bzl", "gen_libinit", "gen_modinit_hpp", "gen_pkgconf", "publish_casters", "resolve_casters", "run_header_gen") +load("//shared/bazel/rules/robotpy:semiwrap_helpers.bzl", "gen_libinit", "gen_modinit_hpp", "gen_pkgconf", "make_pyi", "publish_casters", "resolve_casters", "run_header_gen") load("//shared/bazel/rules/robotpy:semiwrap_tool_helpers.bzl", "scan_headers", "update_yaml_files") def wpiutil_extension(srcs = [], header_to_dat_deps = [], extra_hdrs = [], includes = []): @@ -282,7 +282,7 @@ def publish_library_casters(): tags = ["robotpy"], ) -def define_pybind_library(name, pkgcfgs = [], extra_pybind_hdrs = []): +def define_pybind_library(name, pkgcfgs = [], extra_pybind_hdrs = [], extra_pyi_deps = []): # Helper used to generate all files with one target. native.filegroup( name = "{}.generated_files".format(name), @@ -318,6 +318,14 @@ def define_pybind_library(name, pkgcfgs = [], extra_pybind_hdrs = []): template = "//shared/bazel/rules/robotpy:version_template.in", ) + make_pyi( + name = "wpiutil._wpiutil.make_pyi", + package_name = "wpiutil._wpiutil", + output_files = [["wpiutil/_wpiutil/__init__.pyi", "src/main/python/wpiutil/_wpiutil/__init__.pyi"], ["wpiutil/_wpiutil/sync.pyi", "src/main/python/wpiutil/_wpiutil/sync.pyi"], ["wpiutil/_wpiutil/wpistruct.pyi", "src/main/python/wpiutil/_wpiutil/wpistruct.pyi"]], + module_files = [["wpiutil", "src/main/python/wpiutil/__init__.py"], ["wpiutil._init__wpiutil", "src/main/python/wpiutil/_init__wpiutil.py"], ["wpiutil._wpiutil", "src/main/python/wpiutil/_wpiutil"]], + runner = ":{}.make_pyi_runner".format(name), + ) + robotpy_library( name = name, distribution = "robotpy-wpiutil", @@ -331,6 +339,10 @@ def define_pybind_library(name, pkgcfgs = [], extra_pybind_hdrs = []): ":src/main/python/wpiutil/_wpiutil", ":wpiutil.trampoline_hdr_files", ], + pyi_srcs = [ + ":wpiutil._wpiutil.make_pyi", + ], + pyi_deps = extra_pyi_deps, imports = ["src/main/python"], deps = [ "//wpiutil:robotpy-native-wpiutil", @@ -356,7 +368,7 @@ def define_pybind_library(name, pkgcfgs = [], extra_pybind_hdrs = []): package_root_file = "src/main/python/wpiutil/__init__.py", pkgcfgs = pkgcfgs, pyproject_toml = "src/main/python/pyproject.toml", - yaml_files = native.glob(["src/main/python/semiwrap/**"]), + yaml_files = native.glob(["src/main/python/semiwrap/**"], allow_empty = True), ) scan_headers( diff --git a/wpiutil/src/test/python/test_pyi.py b/wpiutil/src/test/python/test_pyi.py new file mode 100644 index 00000000000..70c022d6d5e --- /dev/null +++ b/wpiutil/src/test/python/test_pyi.py @@ -0,0 +1,13 @@ +import pathlib + +import wpiutil._wpiutil + + +def test_compiled_extension_has_type_stubs(): + extension_path = pathlib.Path(wpiutil._wpiutil.__file__) + stub_dir = extension_path.with_name("_wpiutil") + + for stub_name in ("__init__.pyi", "sync.pyi", "wpistruct.pyi"): + stub_path = stub_dir / stub_name + assert stub_path.is_file() + assert stub_path.stat().st_size > 0 diff --git a/xrpVendordep/robotpy_pybind_build_info.bzl b/xrpVendordep/robotpy_pybind_build_info.bzl index 306de7d3685..84b927b1300 100644 --- a/xrpVendordep/robotpy_pybind_build_info.bzl +++ b/xrpVendordep/robotpy_pybind_build_info.bzl @@ -2,7 +2,7 @@ load("//shared/bazel/rules/gen:gen-version-file.bzl", "generate_version_file") load("//shared/bazel/rules/robotpy:robotpy_rules.bzl", "create_pybind_library", "robotpy_library") -load("//shared/bazel/rules/robotpy:semiwrap_helpers.bzl", "gen_libinit", "gen_modinit_hpp", "gen_pkgconf", "resolve_casters", "run_header_gen") +load("//shared/bazel/rules/robotpy:semiwrap_helpers.bzl", "gen_libinit", "gen_modinit_hpp", "gen_pkgconf", "make_pyi", "resolve_casters", "run_header_gen") load("//shared/bazel/rules/robotpy:semiwrap_tool_helpers.bzl", "scan_headers", "update_yaml_files") def xrp_extension(srcs = [], header_to_dat_deps = [], extra_hdrs = [], includes = []): @@ -218,7 +218,7 @@ def xrp_extension(srcs = [], header_to_dat_deps = [], extra_hdrs = [], includes tags = ["manual", "robotpy"], ) -def define_pybind_library(name, pkgcfgs = [], extra_pybind_hdrs = []): +def define_pybind_library(name, pkgcfgs = [], extra_pybind_hdrs = [], extra_pyi_deps = []): # Helper used to generate all files with one target. native.filegroup( name = "{}.generated_files".format(name), @@ -252,6 +252,14 @@ def define_pybind_library(name, pkgcfgs = [], extra_pybind_hdrs = []): template = "//shared/bazel/rules/robotpy:version_template.in", ) + make_pyi( + name = "xrp._xrp.make_pyi", + package_name = "xrp._xrp", + output_files = [["xrp/_xrp.pyi", "src/main/python/xrp/_xrp.pyi"]], + module_files = [["xrp", "src/main/python/xrp/__init__.py"], ["xrp._init__xrp", "src/main/python/xrp/_init__xrp.py"], ["xrp._xrp", "src/main/python/xrp/_xrp"]], + runner = ":{}.make_pyi_runner".format(name), + ) + robotpy_library( name = name, distribution = "robotpy-xrp", @@ -265,6 +273,10 @@ def define_pybind_library(name, pkgcfgs = [], extra_pybind_hdrs = []): ":src/main/python/xrp/_xrp", ":xrp.trampoline_hdr_files", ], + pyi_srcs = [ + ":xrp._xrp.make_pyi", + ], + pyi_deps = extra_pyi_deps, imports = ["src/main/python"], deps = [ "//wpilibc:robotpy-wpilib", @@ -300,7 +312,7 @@ def define_pybind_library(name, pkgcfgs = [], extra_pybind_hdrs = []): package_root_file = "src/main/python/xrp/__init__.py", pkgcfgs = pkgcfgs, pyproject_toml = "src/main/python/pyproject.toml", - yaml_files = native.glob(["src/main/python/semiwrap/**"]), + yaml_files = native.glob(["src/main/python/semiwrap/**"], allow_empty = True), ) scan_headers(