Permalink
Browse files

Python: Revamp a bunch of stuff

  • Loading branch information...
endrift committed Jun 25, 2018
1 parent 3f05b12 commit 7fa8de1f0d3a9b10f346bce0bdb81d1ad543e322
@@ -0,0 +1,2 @@
+[MESSAGES CONTROL]
+disable=line-too-long,missing-docstring,too-few-public-methods,too-many-instance-attributes,too-many-public-methods,wrong-import-order
@@ -11,15 +11,6 @@ endforeach()
file(GLOB PYTHON_HEADERS ${CMAKE_CURRENT_SOURCE_DIR}/*.h)
-if(NOT GIT_TAG)
- if(GIT_BRANCH STREQUAL "master" OR NOT GIT_BRANCH)
- set(PYLIB_VERSION -b .dev${GIT_REV}+g${GIT_COMMIT_SHORT})
- else()
- set(PYLIB_VERSION -b .dev${GIT_REV}+${GIT_BRANCH}.g${GIT_COMMIT_SHORT})
- endif()
-endif()
-configure_file(${CMAKE_CURRENT_SOURCE_DIR}/setup.py.in ${CMAKE_CURRENT_BINARY_DIR}/setup.py)
-
add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/lib.c
COMMAND BINDIR=${CMAKE_CURRENT_BINARY_DIR}/.. CPPFLAGS="${INCLUDE_FLAGS}" ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/_builder.py
COMMAND ${CMAKE_COMMAND} -E touch ${CMAKE_CURRENT_BINARY_DIR}/lib.c
@@ -35,15 +26,29 @@ set_target_properties(${BINARY_NAME}-pylib PROPERTIES INCLUDE_DIRECTORIES "${CMA
set_target_properties(${BINARY_NAME}-pylib PROPERTIES COMPILE_DEFINITIONS "${OS_DEFINES};${FEATURE_DEFINES};${FUNCTION_DEFINES}")
add_custom_target(${BINARY_NAME}-py ALL
- COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_BINARY_DIR}/setup.py egg_info -e ${CMAKE_CURRENT_BINARY_DIR} ${PYLIB_VERSION}
- COMMAND BINDIR=${CMAKE_CURRENT_BINARY_DIR}/.. CPPFLAGS="${INCLUDE_FLAGS}" ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_BINARY_DIR}/setup.py build -b ${CMAKE_CURRENT_BINARY_DIR}
+ COMMAND BINDIR=${CMAKE_CURRENT_BINARY_DIR}/.. LIBDIR=${CMAKE_CURRENT_BINARY_DIR}/.. CPPFLAGS="${INCLUDE_FLAGS}" ${PYTHON_EXECUTABLE} setup.py build -b ${CMAKE_CURRENT_BINARY_DIR}
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
DEPENDS ${BINARY_NAME}
- DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/setup.py
+ DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/setup.py
DEPENDS ${PYTHON_HEADERS}
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/_builder.py
DEPENDS ${BINARY_NAME}-pylib)
+add_custom_target(${BINARY_NAME}-py-install
+ COMMAND BINDIR=${CMAKE_CURRENT_BINARY_DIR}/.. LIBDIR=${CMAKE_CURRENT_BINARY_DIR}/.. CPPFLAGS="${INCLUDE_FLAGS}" ${PYTHON_EXECUTABLE} setup.py install -b ${CMAKE_CURRENT_BINARY_DIR}
+ WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
+ DEPENDS ${BINARY_NAME}-py)
+
+add_custom_target(${BINARY_NAME}-py-develop
+ COMMAND BINDIR=${CMAKE_CURRENT_BINARY_DIR}/.. LIBDIR=${CMAKE_CURRENT_BINARY_DIR}/.. CPPFLAGS="${INCLUDE_FLAGS}" ${PYTHON_EXECUTABLE} setup.py develop -b ${CMAKE_CURRENT_BINARY_DIR}
+ WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
+ DEPENDS ${BINARY_NAME}-py)
+
+add_custom_target(${BINARY_NAME}-py-bdist
+ COMMAND BINDIR=${CMAKE_CURRENT_BINARY_DIR}/.. LIBDIR=${CMAKE_CURRENT_BINARY_DIR}/.. CPPFLAGS="${INCLUDE_FLAGS}" ${PYTHON_EXECUTABLE} setup.py bdist_wheel -b ${CMAKE_CURRENT_BINARY_DIR}
+ WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
+ DEPENDS ${BINARY_NAME}-py)
+
file(GLOB BASE_TESTS ${CMAKE_CURRENT_SOURCE_DIR}/test_*.py)
file(GLOB SUBTESTS ${CMAKE_CURRENT_SOURCE_DIR}/tests/*/test_*.py)
foreach(TEST IN LISTS BASE_TESTS SUBTESTS)
@@ -56,6 +61,8 @@ foreach(TEST IN LISTS BASE_TESTS SUBTESTS)
endif()
string(REGEX REPLACE "${CMAKE_CURRENT_SOURCE_DIR}/(tests/.*/)?test_" "" TEST_NAME "${TEST}")
string(REPLACE ".py" "" TEST_NAME "${TEST_NAME}")
- add_test(python-${TEST_NAME} ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_BINARY_DIR}/setup.py build -b ${CMAKE_CURRENT_BINARY_DIR} pytest --extras --addopts ${TEST})
- set_tests_properties(python-${TEST_NAME} PROPERTIES ENVIRONMENT "${PATH}=${CMAKE_CURRENT_BINARY_DIR}/..")
+ add_test(NAME python-${TEST_NAME}
+ COMMAND ${PYTHON_EXECUTABLE} setup.py build -b ${CMAKE_CURRENT_BINARY_DIR} pytest --extras --addopts ${TEST}
+ WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
+ set_tests_properties(python-${TEST_NAME} PROPERTIES ENVIRONMENT "${PATH}=${CMAKE_CURRENT_BINARY_DIR}/..;BINDIR=${CMAKE_CURRENT_BINARY_DIR}/..;LIBDIR=${CMAKE_CURRENT_BINARY_DIR}/..;CPPFLAGS=${INCLUDE_FLAGS}")
endforeach()
@@ -78,10 +78,6 @@
ffi.embedding_init_code("""
import os, os.path
- venv = os.getenv('VIRTUAL_ENV')
- if venv:
- activate = os.path.join(venv, 'bin', 'activate_this.py')
- exec(compile(open(activate, "rb").read(), activate, 'exec'), dict(__file__=activate))
from mgba._pylib import ffi, lib
symbols = {}
globalSyms = {
@@ -109,7 +105,7 @@ def mPythonLoadScript(name, vf):
from mgba.vfs import VFile
vf = VFile(vf)
name = ffi.string(name)
- source = vf.readAll().decode('utf-8')
+ source = vf.read_all().decode('utf-8')
try:
code = compile(source, name, 'exec')
pendingCode.append(code)
@@ -2,15 +2,16 @@
from PIL.ImageOps import autocontrast
from PIL.Image import open as PIOpen
+
class VideoFrame(object):
- def __init__(self, pilImage):
- self.image = pilImage.convert('RGB')
+ def __init__(self, pil_image):
+ self.image = pil_image.convert('RGB')
@staticmethod
def diff(a, b):
diff = difference(a.image, b.image)
- diffNormalized = autocontrast(diff)
- return (VideoFrame(diff), VideoFrame(diffNormalized))
+ diff_normalized = autocontrast(diff)
+ return (VideoFrame(diff), VideoFrame(diff_normalized))
@staticmethod
def load(path):
@@ -4,44 +4,38 @@
Output = namedtuple('Output', ['video'])
+
class Tracer(object):
def __init__(self, core):
self.core = core
- self.fb = Image(*core.desiredVideoDimensions())
- self.core.setVideoBuffer(self.fb)
- self._videoFifo = []
+ self.framebuffer = Image(*core.desired_video_dimensions())
+ self.core.set_video_buffer(self.framebuffer)
+ self._video_fifo = []
- def yieldFrames(self, skip=0, limit=None):
+ def yield_frames(self, skip=0, limit=None):
self.core.reset()
skip = (skip or 0) + 1
while skip > 0:
- frame = self.core.frameCounter
- self.core.runFrame()
+ frame = self.core.frame_counter
+ self.core.run_frame()
skip -= 1
- while frame <= self.core.frameCounter and limit != 0:
- self._videoFifo.append(VideoFrame(self.fb.toPIL()))
+ while frame <= self.core.frame_counter and limit != 0:
+ self._video_fifo.append(VideoFrame(self.framebuffer.to_pil()))
yield frame
- frame = self.core.frameCounter
- self.core.runFrame()
+ frame = self.core.frame_counter
+ self.core.run_frame()
if limit is not None:
assert limit >= 0
limit -= 1
def video(self, generator=None, **kwargs):
if not generator:
- generator = self.yieldFrames(**kwargs)
+ generator = self.yield_frames(**kwargs)
try:
while True:
- if self._videoFifo:
- result = self._videoFifo[0]
- self._videoFifo = self._videoFifo[1:]
- yield result
+ if self._video_fifo:
+ yield self._video_fifo.pop(0)
else:
next(generator)
except StopIteration:
return
-
- def output(self, **kwargs):
- generator = self.yieldFrames(**kwargs)
-
- return mCoreOutput(video=self.video(generator=generator, **kwargs))
@@ -1,96 +1,101 @@
-import os, os.path
-import mgba.core, mgba.image
+import os
+import os.path
+import mgba.core
+import mgba.image
import cinema.movie
import itertools
import glob
import re
import yaml
from copy import deepcopy
from cinema import VideoFrame
-from cinema.util import dictMerge
+from cinema.util import dict_merge
+
class CinemaTest(object):
TEST = 'test.(mvl|gb|gba|nds)'
def __init__(self, path, root, settings={}):
- self.fullPath = path or []
- self.path = os.path.abspath(os.path.join(root, *self.fullPath))
+ self.full_path = path or []
+ self.path = os.path.abspath(os.path.join(root, *self.full_path))
self.root = root
self.name = '.'.join(path)
self.settings = settings
try:
with open(os.path.join(self.path, 'manifest.yml'), 'r') as f:
- dictMerge(self.settings, yaml.safe_load(f))
+ dict_merge(self.settings, yaml.safe_load(f))
except IOError:
pass
self.tests = {}
def __repr__(self):
return '<%s %s>' % (self.__class__.__name__, self.name)
- def setUp(self):
+ def setup(self):
results = [f for f in glob.glob(os.path.join(self.path, 'test.*')) if re.search(self.TEST, f)]
- self.core = mgba.core.loadPath(results[0])
+ self.core = mgba.core.load_path(results[0])
if 'config' in self.settings:
self.config = mgba.core.Config(defaults=self.settings['config'])
- self.core.loadConfig(self.config)
+ self.core.load_config(self.config)
self.core.reset()
- def addTest(self, name, cls=None, settings={}):
+ def add_test(self, name, cls=None, settings={}):
cls = cls or self.__class__
- newSettings = deepcopy(self.settings)
- dictMerge(newSettings, settings)
- self.tests[name] = cls(self.fullPath + [name], self.root, newSettings)
+ new_settings = deepcopy(self.settings)
+ dict_merge(new_settings, settings)
+ self.tests[name] = cls(self.full_path + [name], self.root, new_settings)
return self.tests[name]
- def outputSettings(self):
- outputSettings = {}
+ def output_settings(self):
+ output_settings = {}
if 'frames' in self.settings:
- outputSettings['limit'] = self.settings['frames']
+ output_settings['limit'] = self.settings['frames']
if 'skip' in self.settings:
- outputSettings['skip'] = self.settings['skip']
- return outputSettings
+ output_settings['skip'] = self.settings['skip']
+ return output_settings
def __lt__(self, other):
return self.path < other.path
+
class VideoTest(CinemaTest):
BASELINE = 'baseline_%04u.png'
- def setUp(self):
- super(VideoTest, self).setUp();
+ def setup(self):
+ super(VideoTest, self).setup()
self.tracer = cinema.movie.Tracer(self.core)
- def generateFrames(self):
- for i, frame in zip(itertools.count(), self.tracer.video(**self.outputSettings())):
+ def generate_frames(self):
+ for i, frame in zip(itertools.count(), self.tracer.video(**self.output_settings())):
try:
baseline = VideoFrame.load(os.path.join(self.path, self.BASELINE % i))
yield baseline, frame, VideoFrame.diff(baseline, frame)
except IOError:
yield None, frame, (None, None)
def test(self):
- self.baseline, self.frames, self.diffs = zip(*self.generateFrames())
+ self.baseline, self.frames, self.diffs = zip(*self.generate_frames())
assert not any(any(diffs[0].image.convert("L").point(bool).getdata()) for diffs in self.diffs)
- def generateBaseline(self):
- for i, frame in zip(itertools.count(), self.tracer.video(**self.outputSettings())):
+ def generate_baseline(self):
+ for i, frame in zip(itertools.count(), self.tracer.video(**self.output_settings())):
frame.save(os.path.join(self.path, self.BASELINE % i))
-def gatherTests(root=os.getcwd()):
+
+def gather_tests(root=os.getcwd()):
tests = CinemaTest([], root)
for path, _, files in os.walk(root):
test = [f for f in files if re.match(CinemaTest.TEST, f)]
if not test:
continue
prefix = os.path.commonprefix([path, root])
suffix = path[len(prefix)+1:]
- testPath = suffix.split(os.sep)
- testRoot = tests
- for component in testPath[:-1]:
- newTest = testRoot.tests.get(component)
- if not newTest:
- newTest = testRoot.addTest(component)
- testRoot = newTest
- testRoot.addTest(testPath[-1], VideoTest)
+ test_path = suffix.split(os.sep)
+ test_root = tests
+ for component in test_path[:-1]:
+ new_test = test_root.tests.get(component)
+ if not new_test:
+ new_test = test_root.add_test(component)
+ test_root = new_test
+ test_root.add_test(test_path[-1], VideoTest)
return tests
@@ -1,8 +1,8 @@
-def dictMerge(a, b):
+def dict_merge(a, b):
for key, value in b.items():
if isinstance(value, dict):
if key in a:
- dictMerge(a[key], value)
+ dict_merge(a[key], value)
else:
a[key] = dict(value)
else:
@@ -3,31 +3,34 @@
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-from ._pylib import ffi, lib
+from ._pylib import ffi, lib # pylint: disable=no-name-in-module
from collections import namedtuple
-def createCallback(structName, cbName, funcName=None):
- funcName = funcName or "_py{}{}".format(structName, cbName[0].upper() + cbName[1:])
- fullStruct = "struct {}*".format(structName)
- def cb(handle, *args):
- h = ffi.cast(fullStruct, handle)
- return getattr(ffi.from_handle(h.pyobj), cbName)(*args)
- return ffi.def_extern(name=funcName)(cb)
+def create_callback(struct_name, cb_name, func_name=None):
+ func_name = func_name or "_py{}{}".format(struct_name, cb_name[0].upper() + cb_name[1:])
+ full_struct = "struct {}*".format(struct_name)
-version = ffi.string(lib.projectVersion).decode('utf-8')
+ def callback(handle, *args):
+ handle = ffi.cast(full_struct, handle)
+ return getattr(ffi.from_handle(handle.pyobj), cb_name)(*args)
+
+ return ffi.def_extern(name=func_name)(callback)
+
+
+__version__ = ffi.string(lib.projectVersion).decode('utf-8')
GitInfo = namedtuple("GitInfo", "commit commitShort branch revision")
-git = {}
+GIT = {}
if lib.gitCommit and lib.gitCommit != "(unknown)":
- git['commit'] = ffi.string(lib.gitCommit).decode('utf-8')
+ GIT['commit'] = ffi.string(lib.gitCommit).decode('utf-8')
if lib.gitCommitShort and lib.gitCommitShort != "(unknown)":
- git['commitShort'] = ffi.string(lib.gitCommitShort).decode('utf-8')
+ GIT['commitShort'] = ffi.string(lib.gitCommitShort).decode('utf-8')
if lib.gitBranch and lib.gitBranch != "(unknown)":
- git['branch'] = ffi.string(lib.gitBranch).decode('utf-8')
+ GIT['branch'] = ffi.string(lib.gitBranch).decode('utf-8')
if lib.gitRevision > 0:
- git['revision'] = lib.gitRevision
+ GIT['revision'] = lib.gitRevision
-git = GitInfo(**git)
+GIT = GitInfo(**GIT)
@@ -3,26 +3,27 @@
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-from ._pylib import ffi, lib
+from ._pylib import ffi, lib # pylint: disable=no-name-in-module
+
class _ARMRegisters:
def __init__(self, cpu):
self._cpu = cpu
- def __getitem__(self, r):
- if r > lib.ARM_PC:
+ def __getitem__(self, reg):
+ if reg > lib.ARM_PC:
raise IndexError("Register out of range")
- return self._cpu._native.gprs[r]
+ return self._cpu._native.gprs[reg]
- def __setitem__(self, r, value):
- if r >= lib.ARM_PC:
+ def __setitem__(self, reg, value):
+ if reg >= lib.ARM_PC:
raise IndexError("Register out of range")
- self._cpu._native.gprs[r] = value
+ self._cpu._native.gprs[reg] = value
+
class ARMCore:
def __init__(self, native):
self._native = ffi.cast("struct ARMCore*", native)
self.gprs = _ARMRegisters(self)
self.cpsr = self._native.cpsr
self.spsr = self._native.spsr
-
Oops, something went wrong.

0 comments on commit 7fa8de1

Please sign in to comment.