Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
35e353d
Small fixups
pjreiniger Aug 20, 2025
a4ecaca
Merge pull request #193 from pjreiniger/bazel_cleanups
virtuald Aug 21, 2025
ea57e01
Use auditwheel to detect the correct names for built wheels in CI
virtuald Sep 5, 2025
8bed6a9
Merge pull request #198 from robotpy/fix-wheel-names
virtuald Sep 8, 2025
3e34660
ci: Stop building for Python 3.9
auscompgeek Sep 15, 2025
3886c70
Fix UP024 (Replace aliased errors with `OSError`)
auscompgeek Sep 15, 2025
11e20b1
Fix UP032 (Use f-string instead of `format` call)
auscompgeek Sep 15, 2025
d41a7ec
Fix UP004 (Class `Foo` inherits from `object`)
auscompgeek Sep 15, 2025
5c4d455
Fix UP015 (Unnecessary mode argument)
auscompgeek Sep 15, 2025
f902f04
Fix UP010 (Unnecessary `__future__` import `print_function` for targe…
auscompgeek Sep 15, 2025
0473065
Merge pull request #199 from auscompgeek/drop-py39
virtuald Oct 7, 2025
b9359c4
wpimath: Remove floorDiv and floorMod
auscompgeek Sep 16, 2025
da4347f
Merge pull request #200 from robotpy/wpimath-no-floordiv-mod
virtuald Oct 7, 2025
b502797
rdev: provide mechanism to update robotpy entrypoints
virtuald Oct 5, 2025
a342c74
Updated dependencies
virtuald Oct 7, 2025
a8599a0
Merge pull request #201 from robotpy/entrypoint-updater
virtuald Oct 13, 2025
b6af6d5
rdev: add install-prereqs command
virtuald Oct 13, 2025
c95dfaa
Merge pull request #202 from robotpy/dev-install-prereqs
virtuald Oct 14, 2025
57fcfd8
Update __init__.py
virtuald Oct 21, 2025
130f114
Updated dependencies
virtuald Oct 23, 2025
76738fb
Updated dependencies
virtuald Oct 23, 2025
0747115
Updates for 2026
virtuald Oct 21, 2025
61abbf6
Update CI
virtuald Oct 23, 2025
938e26b
Merge remote-tracking branch 'origin/main' into 2027
virtuald Oct 27, 2025
1107b1e
Updated dependencies
virtuald Oct 27, 2025
31892e4
Updated dependencies
virtuald Oct 27, 2025
98c00c8
Updates for alpha 3
virtuald Oct 27, 2025
9956007
Merge pull request #203 from robotpy/2026-dev
virtuald Oct 29, 2025
b2a9754
Merge remote-tracking branch 'origin/main' into 2027
virtuald Oct 29, 2025
1f2b5fb
Update CI
virtuald Oct 29, 2025
c6e1227
Remove duplicate key
virtuald Oct 29, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 13 additions & 7 deletions .github/workflows/dist.yml
Original file line number Diff line number Diff line change
Expand Up @@ -131,11 +131,11 @@ jobs:
- "macos-14" # arm64
- "windows-2022"
python_version:
- '3.9'
- '3.10'
- '3.11'
- '3.12'
- '3.13'
- '3.14'
include:
- os: ubuntu-24.04-arm
python_version: '3.11'
Expand All @@ -146,6 +146,9 @@ jobs:
- os: ubuntu-24.04-arm
python_version: '3.13'
container: python:3.13-bookworm
- os: ubuntu-24.04-arm
python_version: '3.14'
container: python:3.14-bookworm

container: ${{ matrix.container }}

Expand Down Expand Up @@ -236,9 +239,9 @@ jobs:
max-parallel: ${{ fromJSON(needs.setup_concurrency.outputs.max-parallel).v }}
matrix:
os:
- container: wpilib/systemcore-cross-ubuntu:2025-22.04-py313
- container: wpilib/systemcore-cross-ubuntu:2026-24.04-py314
name: systemcore
- container: wpilib/raspbian-cross-ubuntu:2025-bookworm-24.04-py313
- container: wpilib/raspbian-cross-ubuntu:2027-bookworm-24.04-py313
name: raspbian

container:
Expand Down Expand Up @@ -274,19 +277,22 @@ jobs:
max-parallel: ${{ fromJSON(needs.setup_concurrency.outputs.max-parallel).v }}
matrix:
os:
- container: wpilib/systemcore-cross-ubuntu:2025-22.04-py313
- container: wpilib/systemcore-cross-ubuntu:2026-24.04-py314
name: systemcore
base: systemcore

- container: wpilib/raspbian-cross-ubuntu:2025-bookworm-24.04-py311
- container: wpilib/raspbian-cross-ubuntu:2027-bookworm-24.04-py311
name: raspbian-py311
base: raspbian
- container: wpilib/raspbian-cross-ubuntu:2025-bookworm-24.04-py312
- container: wpilib/raspbian-cross-ubuntu:2027-bookworm-24.04-py312
name: raspbian-py312
base: raspbian
- container: wpilib/raspbian-cross-ubuntu:2025-bookworm-24.04-py313
- container: wpilib/raspbian-cross-ubuntu:2027-bookworm-24.04-py313
name: raspbian-py313
base: raspbian
- container: wpilib/raspbian-cross-ubuntu:2027-bookworm-24.04-py314
name: raspbian-py314
base: raspbian

container:
image: "${{ matrix.os.container }}"
Expand Down
8 changes: 6 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,11 @@ Development environment
-----------------------

To install all robotpy packages in [editable mode](https://packaging.python.org/en/latest/guides/distributing-packages-using-setuptools/#working-in-development-mode)
run this:
first run this to install dependencies:

./rdev.sh install-prereqs

Then each time you want to build everything:

./rdev.sh develop

Expand All @@ -55,7 +59,7 @@ rebuild an individual package:

./rdev.sh develop NAME

It can be a slow process,see the [robotpy-build documentation](https://robotpy-build.readthedocs.io/en/stable/tips.html)
It can be a slow process, see the [semiwrap documentation](https://semiwrap.readthedocs.io/en/stable/tips.html)
for tips to make it more efficient.

Cross Compilation
Expand Down
25 changes: 25 additions & 0 deletions devtools/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
from .ctx import Context
from . import ci
from . import update_pyproject
from . import util


#
# Environment variables for configuring the builds
Expand Down Expand Up @@ -61,6 +63,29 @@ def develop(ctx: Context, package: str):
project.develop()


@main.command()
@click.pass_obj
def install_prereqs(ctx: Context):
"""Install developer build dependencies before running develop"""

reqs = set()
reqs.add("editables")
reqs.add("numpy")
reqs.add("pytest")

repo_deps = set()

for project in ctx.subprojects.values():
with ctx.handle_exception(project.name):
repo_deps.add(project.pyproject_name)

for req in project.build_requires + project.dependencies:
if req.name not in repo_deps:
reqs.add(req)

util.run_pip("install", *map(str, reqs))


@main.command()
@click.pass_obj
def scan_headers(ctx: Context):
Expand Down
3 changes: 3 additions & 0 deletions devtools/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@ class Parameters:
wpilib_bin_version: str
wpilib_bin_url: str

#: renames [project.entry-points.KEY*] to [project.entry-points.VALUE]
entrypoints: T.Dict[str, str]

exclude_artifacts: T.Set[str]

requirements: T.Dict[str, str]
Expand Down
50 changes: 39 additions & 11 deletions devtools/subproject.py
Original file line number Diff line number Diff line change
Expand Up @@ -132,8 +132,9 @@ def build_wheel(

tdp = pathlib.Path(td)
twhl = list(tdp.glob("*.whl"))[0]
dst_whl = wheel_path / self._fix_wheel_name(twhl.name)
dst_whl = wheel_path / self._fix_wheel_name(twhl)
shutil.move(twhl, dst_whl)
print("Wrote wheel to", dst_whl)

if install:
# Install the wheel
Expand All @@ -147,19 +148,46 @@ def build_wheel(
)

_adjust_wheel_tags = {
# pypi only accepts manylinux wheels, and we know we're compatible
# TODO(davo): use auditwheel to fix the tags instead
"linux_x86_64": "manylinux_2_35_x86_64",
"linux_aarch64": "manylinux_2_36_aarch64",
# needed for compatibility with python compiled with older xcode
"macosx_11_0_x86_64": "macosx_10_16_x86_64",
"macosx_12_0_x86_64": "macosx_10_16_x86_64",
}

def _fix_wheel_name(self, name: str) -> str:
for old, new in self._adjust_wheel_tags.items():
old_whl = f"{old}.whl"
new_whl = f"{new}.whl"
if name.endswith(old_whl):
name = f"{name[:-len(old_whl)]}{new_whl}"
def _fix_wheel_name(self, wheel_path: pathlib.Path) -> str:
if sys.platform == "linux":
name = self._fix_linux_wheel_name(wheel_path)
else:
name = wheel_path.name
for old, new in self._adjust_wheel_tags.items():
old_whl = f"{old}.whl"
new_whl = f"{new}.whl"
if name.endswith(old_whl):
name = f"{name[:-len(old_whl)]}{new_whl}"

return name

def _fix_linux_wheel_name(self, wheel_path: pathlib.Path) -> str:
# inspired by https://github.com/hsorby/renamewheel, Apache license

from auditwheel.error import NonPlatformWheel, WheelToolsError
from auditwheel.wheel_abi import analyze_wheel_abi
from auditwheel.wheeltools import get_wheel_architecture, get_wheel_libc

try:
arch = get_wheel_architecture(wheel_path.name)
except (WheelToolsError, NonPlatformWheel):
arch = None

try:
libc = get_wheel_libc(wheel_path.name)
except WheelToolsError:
libc = None

try:
winfo = analyze_wheel_abi(libc, arch, wheel_path, frozenset(), True, True)
except NonPlatformWheel:
return wheel_path.name
else:
parts = wheel_path.name.split("-")
parts[-1] = winfo.overall_policy.name
return "-".join(parts) + ".whl"
33 changes: 32 additions & 1 deletion devtools/update_pyproject.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ def __init__(self, ctx: Context) -> None:
# and retain all the comments
self.subprojects: typing.Dict[str, ProjectInfo] = {}
for name, project in self.ctx.subprojects.items():
with open(project.pyproject_path, "r") as fp:
with open(project.pyproject_path) as fp:
data = tomlkit.load(fp)

self.subprojects[name] = ProjectInfo(
Expand Down Expand Up @@ -68,6 +68,31 @@ def wpilib_bin_version(self) -> str:
def wpilib_bin_url(self) -> str:
return self.cfg.params.wpilib_bin_url

def _update_entrypoints(
self,
info: ProjectInfo,
pypi_name: str,
):
data = info.data
eps = data["project"].get("entry-points")
if eps is None:
return

for name in list(eps.keys()):
for prefix, replace in self.cfg.params.entrypoints.items():
if name.startswith(prefix):
if name != replace:
eps[replace] = eps[name]
del eps[name]
print(
f"* {pypi_name}: entry-points.{name} -> entry-points.{replace}"
)
self.commit_changes.add(
f"{pypi_name}: entry-points.{name} -> entry-points.{replace}"
)
info.changed = True
break

def _update_requirements(
self,
info: ProjectInfo,
Expand Down Expand Up @@ -126,6 +151,12 @@ def update_requirements(self):
data["project"]["dependencies"],
)

# project.entry-points
self._update_entrypoints(
info,
pypi_name,
)

def _update_maven(self, info: ProjectInfo):
data = info.data
iter = (
Expand Down
22 changes: 15 additions & 7 deletions rdev.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,18 +11,18 @@
[py_versions]

# Usually the same as wpilib_bin_version
native = "2027.0.0a2"
native = "2027.0.0a3"

# Will eventually sync with native
halsim_native = "2027.0.0a2"
halsim_native = "2027.0.0a3"

# Usually similar to native, but subminor version is bumped for bugfixes
# - ./rdev.sh ci check_tag will fail if this doesn't match current tag
wrapper = "2027.0.0a2"
wrapper = "2027.0.0a3"

[params]

wpilib_bin_version = "2027.0.0-alpha-2"
wpilib_bin_version = "2027.0.0-alpha-3"
wpilib_bin_url = "https://frcmaven.wpi.edu/artifactory/release-2027"
# wpilib_bin_url = "https://frcmaven.wpi.edu/artifactory/development-2027"

Expand All @@ -33,12 +33,20 @@ exclude_artifacts = [

robot_wheel_platform = "linux-systemcore"

[params.entrypoints]
# prefix = "actual"
# - ensures that [project.entry-points.prefix*] are renamed to "actual", which
# makes it easy to upgrade them each year (https://github.com/robotpy/robotpy-cli/issues/5)
# - also reminds me that we have to bump it every year ^_^
robotpy_sim = "robotpy_sim.2027"
robotpy_cli = "robotpy_cli.2027"

[params.requirements]
semiwrap = "~=0.1.7"
hatch-meson = "~=0.1.0b2"
semiwrap = "~=0.2.1"
hatch-meson = "~=0.1.0"
hatch-nativelib = "~=0.2.0"
hatch-robotpy = "~=0.2.1"

robotpy-cli = "~=2027.0.0a1"

[subprojects."robotpy-native-wpiutil"]
py_version = "native"
Expand Down
2 changes: 2 additions & 0 deletions rdev_requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,5 @@ validobj~=1.2

ninja
msvc-runtime>=14.42.34433; platform_system == 'Windows'

auditwheel~=6.4; platform_system == 'Linux'
22 changes: 11 additions & 11 deletions subprojects/pyntcore/pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,30 +1,30 @@
[build-system]
build-backend = "hatchling.build"
requires = [
"semiwrap~=0.1.7",
"hatch-meson~=0.1.0b2",
"semiwrap~=0.2.1",
"hatch-meson~=0.1.0",
"hatch-robotpy~=0.2.1",
"hatchling",
"robotpy-native-ntcore==2027.0.0a2",
"robotpy-wpiutil==2027.0.0a2",
"robotpy-wpinet==2027.0.0a2",
"robotpy-wpilog==2027.0.0a2",
"robotpy-native-ntcore==2027.0.0a3",
"robotpy-wpiutil==2027.0.0a3",
"robotpy-wpinet==2027.0.0a3",
"robotpy-wpilog==2027.0.0a3",
]


[project]
name = "pyntcore"
version = "2027.0.0a2"
version = "2027.0.0a3"
description = "Binary wrappers for the FRC ntcore library"
authors = [
{name = "RobotPy Development Team", email = "robotpy@googlegroups.com"},
]
license = "BSD-3-Clause"
dependencies = [
"robotpy-native-ntcore==2027.0.0a2",
"robotpy-wpiutil==2027.0.0a2",
"robotpy-wpinet==2027.0.0a2",
"robotpy-wpilog==2027.0.0a2",
"robotpy-native-ntcore==2027.0.0a3",
"robotpy-wpiutil==2027.0.0a3",
"robotpy-wpinet==2027.0.0a3",
"robotpy-wpilog==2027.0.0a3",
]

[project.urls]
Expand Down
2 changes: 0 additions & 2 deletions subprojects/pyntcore/tests/test_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@
# works correctly
#

from __future__ import print_function

import pytest

import logging
Expand Down
8 changes: 4 additions & 4 deletions subprojects/pyntcore/tests/test_util.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@


def test_ntproperty(nt: NetworkTableInstance):
class Foo(object):
class Foo:
robotTime = ntproperty(
"/SmartDashboard/robotTime", 0.0, writeDefault=False, inst=nt
)
Expand Down Expand Up @@ -85,14 +85,14 @@ class Foo(object):
def test_ntproperty_emptyarray(nt: NetworkTableInstance):
with pytest.raises(TypeError):

class Foo1(object):
class Foo1:
testArray = ntproperty(
"/SmartDashboard/testArray", [], writeDefault=True, inst=nt
)

with pytest.raises(TypeError):

class Foo2(object):
class Foo2:
testArray = ntproperty(
"/SmartDashboard/testArray", [], writeDefault=False, inst=nt
)
Expand All @@ -106,7 +106,7 @@ def test_ntproperty_multitest(nt: NetworkTableInstance):
pyfrc tests
"""

class Foo(object):
class Foo:
robotTime = ntproperty(
"/SmartDashboard/robotTime", 0.0, writeDefault=False, inst=nt
)
Expand Down
Loading
Loading