Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feature/python module #37

Merged
merged 4 commits into from
Oct 26, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
3 changes: 3 additions & 0 deletions example/create_sphere.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import maya.cmds as cmds

cmds.polySphere()
5 changes: 5 additions & 0 deletions example/exampleCharacter.py
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,11 @@ def __init__(self, name: str = "ExampleRig") -> None:
# "MotionModuleParenting": utility.MotionModuleParenting(
# self,
# ),
"PythonCreateSphere": utility.PythonCode(
self,
pythonFile=os.path.join(self.exampleCharacterFolder, "create_sphere.py"),
label="PythonCreateSphere",
)
}
self.exportModules = {
# "FBXExport": export.FBXExport(
Expand Down
35 changes: 35 additions & 0 deletions rigsys/modules/utility/runPythonCode.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
"""Python Utility module."""

import logging
import os

from rigsys.modules.utility.utilityBase import UtilityModuleBase


logger = logging.getLogger(__name__)


class PythonCode(UtilityModuleBase):
"""Python utility module.

Takes in a path to a python file and executes it."""

def __init__(self, rig, pythonFile: str, label: str = "", buildOrder: int = 3000, isMuted: bool = False) -> None:
side = "M"
mirror = False
super().__init__(rig, side, label, buildOrder, isMuted, mirror)

self.pythonFile = pythonFile

def run(self):
"""Run the module (execute the python file)."""
if not os.path.exists(self.pythonFile):
raise ValueError(f"File does not exist: {self.pythonFile}")

with open(self.pythonFile) as f:
try:
code = compile(f.read(), self.pythonFile, 'exec')
exec(code, globals(), locals())
except Exception as e:
logger.error(f"Error executing python file: {self.pythonFile}")
raise e
55 changes: 55 additions & 0 deletions rigsys/test/modules/utility/test_utility_runPythonCode.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
"""Test the PythonCode module."""


import os
import unittest

import maya.cmds as cmds

from rigsys import Rig
import rigsys.modules.utility as utility


class TestPythonCode(unittest.TestCase):
"""Test the PythonCode module."""

def setUp(self) -> None:
cmds.file(new=True, force=True)

self.rig = Rig()

self.resourcesFolder = os.path.join(os.path.dirname(__file__), os.pardir, os.pardir, "resources")

return super().setUp()

def tearDown(self) -> None:
return super().tearDown()

def test_general(self):
"""Ensure the module runs properly."""
pythonFilePath = os.path.join(self.resourcesFolder, "create_sphere.py")

self.rig.utilityModules = {
"PythonCode": utility.PythonCode(
self.rig,
pythonFilePath,
)
}

self.rig.build()

self.assertTrue(cmds.objExists("pSphere1"))

def test_errorHandling(self):
"""Ensure the module handles errors properly."""
pythonFilePath = os.path.join(self.resourcesFolder, "invalid_python.py")

self.rig.utilityModules = {
"PythonCode": utility.PythonCode(
self.rig,
pythonFilePath,
)
}

with self.assertRaises(IndentationError):
self.rig.build()
3 changes: 3 additions & 0 deletions rigsys/test/resources/create_sphere.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import maya.cmds as cmds

cmds.polySphere()
1 change: 1 addition & 0 deletions rigsys/test/resources/invalid_python.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
for i in range(10):
36 changes: 35 additions & 1 deletion rigsys/test/testRunner.py
Original file line number Diff line number Diff line change
@@ -1,21 +1,55 @@
"""Run all tests in the test folder."""

import logging
import os
import pytest
import sys

import maya.cmds as cmds

from rigsys.utils.unload import unloadPackages, nukePycFiles


logger = logging.getLogger(__name__)


class StdOutWrapper:
"""Wrapper for stdout that fixes pytest capturing."""

def __init__(self, stdout):
"""Initialize the wrapper."""
self._stdout = stdout

def __getattr__(self, item):
"""Get the attribute from the wrapped stdout."""
if item == "isatty":
return self.isatty
else:
return getattr(self._stdout, item)

def isatty(self):
"""Return False."""
return False


def fix_stdout():
"""Fix Maya stdout so that pytest can capture it."""
sys.stdout = StdOutWrapper(sys.stdout)
sys.stdout._stdout


def runTests(pattern="test_"):
"""Run all tests in the test folder."""
unloadPackages(silent=False, packages=["rigsys"])
nukePycFiles()

testPath = os.path.dirname(__file__)

pytest.main([testPath, "-k", pattern])
try:
pytest.main([testPath, "-k", pattern])
except Exception:
logger.warning("Error running tests. Trying again with fixed stdout.")
fix_stdout()

cmds.file(new=True, force=True)

Expand Down