Skip to content

Commit

Permalink
Merge pull request #227 from robotpy/robot-py-updates
Browse files Browse the repository at this point in the history
Robot py updates
  • Loading branch information
virtuald committed Jan 4, 2024
2 parents 413ed1b + 6e2bf70 commit 6819401
Show file tree
Hide file tree
Showing 9 changed files with 138 additions and 126 deletions.
3 changes: 0 additions & 3 deletions docs/conf.py
Expand Up @@ -11,9 +11,6 @@

# Project must be built+installed to generate docs
import pyfrc
import pyfrc.config

pyfrc.config.config_obj["pyfrc"] = dict(game_specific_messages=[])

# -- RTD configuration ------------------------------------------------

Expand Down
16 changes: 0 additions & 16 deletions pyfrc/config.py

This file was deleted.

35 changes: 20 additions & 15 deletions pyfrc/mains/cli_add_tests.py
@@ -1,6 +1,6 @@
import inspect
import os
from os.path import abspath, dirname, exists, join
import pathlib
import sys

builtin_tests = """'''
This test module imports tests that come with pyfrc, and can be used
Expand All @@ -12,36 +12,41 @@


class PyFrcAddTests:
"""
Adds default pyfrc tests to your robot project directory
"""

def __init__(self, parser=None):
pass

def run(self, options, robot_class, **static_options):
robot_file = abspath(inspect.getfile(robot_class))
robot_path = dirname(robot_file)
def run(self, main_file: pathlib.Path, project_path: pathlib.Path):
if not main_file.exists():
print(
f"ERROR: is this a robot project? {main_file} does not exist",
file=sys.stderr,
)
return 1

try_dirs = [
abspath(join(robot_path, "tests")),
abspath(join(robot_path, "..", "tests")),
]
try_dirs = [project_path / "tests", project_path / ".." / "tests"]

test_directory = try_dirs[0]

for d in try_dirs:
if exists(d):
if d.exists():
test_directory = d
break
else:
os.makedirs(test_directory)
test_directory.mkdir(parents=True)

print("Tests directory is %s" % test_directory)
print(f"Tests directory is {test_directory}")
print()
builtin_tests_file = join(test_directory, "pyfrc_test.py")
if exists(builtin_tests_file):
builtin_tests_file = test_directory / "pyfrc_test.py"
if builtin_tests_file.exists():
print("- pyfrc_test.py already exists")
else:
with open(builtin_tests_file, "w") as fp:
fp.write(builtin_tests)
print("- builtin tests created at", builtin_tests_file)

print()
print("Robot tests can be ran via 'python3 robot.py test'")
print("Robot tests can be ran via 'python3 -m robotpy test'")
31 changes: 19 additions & 12 deletions pyfrc/mains/cli_coverage.py
@@ -1,14 +1,16 @@
import argparse
import inspect
from os.path import dirname
import pathlib
import subprocess
import sys
import typing


class PyFrcCoverage:
"""
Wraps other commands by running them via the coverage module. Requires
the coverage module to be installed.
Wraps other commands by running them via the coverage module.
Requires the coverage module to be installed.
"""

def __init__(self, parser: argparse.ArgumentParser):
Expand All @@ -19,7 +21,13 @@ def __init__(self, parser: argparse.ArgumentParser):
"args", nargs=argparse.REMAINDER, help="Arguments to pass to robot.py"
)

def run(self, options, robot_class, **static_options):
def run(
self,
main_file: pathlib.Path,
project_path: pathlib.Path,
parallel_mode: bool,
args: typing.List[str],
):
try:
import coverage
except ImportError:
Expand All @@ -30,13 +38,11 @@ def run(self, options, robot_class, **static_options):
)
return 1

if len(options.args) == 0:
if len(args) == 0:
print("ERROR: Coverage command requires arguments to run other commands")
return 1

file_location = inspect.getfile(robot_class)

option_args = list(options.args)
option_args = args
if option_args[0] == "test":
option_args.insert(1, "--coverage-mode")

Expand All @@ -47,19 +53,20 @@ def run(self, options, robot_class, **static_options):
"coverage",
"run",
"--source",
dirname(file_location),
str(project_path),
]
if options.parallel_mode:
if parallel_mode:
args.append("--parallel-mode")

args.append(file_location)
args += ["-m", "robotpy", "--main", main_file]
args += option_args

print("+", *args, file=sys.stderr)
retval = subprocess.call(args)
if retval != 0:
return retval

if options.parallel_mode:
if parallel_mode:
subprocess.call([sys.executable, "-m", "coverage", "combine"])

args = [sys.executable, "-m", "coverage", "report", "-m"]
Expand Down
34 changes: 22 additions & 12 deletions pyfrc/mains/cli_create_physics.py
@@ -1,7 +1,6 @@
import inspect
import json
from os import mkdir
from os.path import abspath, dirname, exists, join
import pathlib
import sys


physics_starter = '''
#
Expand Down Expand Up @@ -90,21 +89,32 @@ def update_sim(self, now: float, tm_diff: float) -> None:


class PyFrcCreatePhysics:
"""
Create physics
"""

def __init__(self, parser=None):
pass

def run(self, options, robot_class, **static_options):
robot_file = abspath(inspect.getfile(robot_class))
robot_path = dirname(robot_file)
sim_path = join(robot_path, "sim")

physics_file = join(robot_path, "physics.py")
if exists(physics_file):
def run(
self,
main_file: pathlib.Path,
project_path: pathlib.Path,
):
if not main_file.exists():
print(
f"ERROR: is this a robot project? {main_file} does not exist",
file=sys.stderr,
)
return 1

physics_file = project_path / "physics.py"
if physics_file.exists():
print("- physics.py already exists")
else:
with open(physics_file, "w") as fp:
fp.write(physics_starter)
print("- physics file created at", physics_file)

print()
print("Robot simulation can be run via 'python3 robot.py sim'")
print("Robot simulation can be run via 'python3 -m robotpy sim'")
32 changes: 16 additions & 16 deletions pyfrc/mains/cli_profiler.py
@@ -1,13 +1,16 @@
import argparse
import inspect
from os.path import abspath
import pathlib
import subprocess
import sys
import typing


class PyFrcProfiler:
"""
Wraps other commands by running them via the built in cProfile module.
Use this to profile your program and figure out where you're spending
a lot of time (note that cProfile only profiles the main thread)
"""
Expand All @@ -17,17 +20,15 @@ def __init__(self, parser):
"-o", "--outfile", default=None, help="Save stats to <outfile>"
)
parser.add_argument(
"args", nargs=argparse.REMAINDER, help="Arguments to pass to robot.py"
"args", nargs=argparse.REMAINDER, help="Arguments to pass to robotpy module"
)

def run(self, options, robot_class, **static_options):
print("profiling is not yet implemented for RobotPy 2020")
return 1

from .. import config

config.mode = "profiler"

def run(
self,
main_file: pathlib.Path,
outfile: typing.Optional[str],
args: typing.List[str],
):
try:
import cProfile
except ImportError:
Expand All @@ -37,23 +38,22 @@ def run(self, options, robot_class, **static_options):
)
return 1

if len(options.args) == 0:
if len(args) == 0:
print("ERROR: Profiler command requires arguments to run other commands")
return 1

file_location = abspath(inspect.getfile(robot_class))

if options.outfile:
profile_args = ["-o", options.outfile]
if outfile:
profile_args = ["-o", outfile]
else:
profile_args = ["-s", "tottime"]

# construct the arguments to run the profiler
args = (
[sys.executable, "-m", "cProfile"]
+ profile_args
+ [file_location]
+ options.args
+ ["-m", "robotpy", "--main", str(main_file)]
+ args
)

print("+", *args, file=sys.stderr)
return subprocess.call(args)
23 changes: 14 additions & 9 deletions pyfrc/mains/cli_sim.py
@@ -1,11 +1,12 @@
import os
from os.path import abspath, dirname
import argparse
import importlib.metadata
import inspect
import logging
import pathlib
import sys
import typing

import wpilib


logger = logging.getLogger("pyfrc.sim")
Expand Down Expand Up @@ -56,12 +57,18 @@ def __init__(self, parser: argparse.ArgumentParser):
help=cmd_help,
)

def run(self, options, robot_class, **static_options):
if not options.nogui:
def run(
self,
options: argparse.Namespace,
nogui: bool,
project_path: pathlib.Path,
robot_class: typing.Type[wpilib.RobotBase],
):
if not nogui:
try:
import halsim_gui
except ImportError:
print("robotpy-halsim-gui is not installed!")
print("robotpy-halsim-gui is not installed!", file=sys.stderr)
exit(1)
else:
halsim_gui.loadExtension()
Expand All @@ -74,19 +81,17 @@ def run(self, options, robot_class, **static_options):
try:
module.loadExtension()
except:
print(f"Error loading {name}!")
print(f"Error loading {name}!", file=sys.stderr)
raise

os.chdir(cwd)

# initialize physics, attach to the user robot class
from ..physics.core import PhysicsInterface, PhysicsInitException

robot_file = pathlib.Path(inspect.getfile(robot_class)).absolute()

try:
_, robot_class = PhysicsInterface._create_and_attach(
robot_class, robot_file.parent
robot_class, project_path
)

# run the robot
Expand Down

0 comments on commit 6819401

Please sign in to comment.