Skip to content

Commit

Permalink
py cpp_template: Fix badly scoped name overrides (#13409)
Browse files Browse the repository at this point in the history
* py cpp_template: Fix badly scoped name overrides
  • Loading branch information
EricCousineau-TRI authored May 27, 2020
1 parent 3f56057 commit 6a068e3
Show file tree
Hide file tree
Showing 5 changed files with 17 additions and 5 deletions.
3 changes: 3 additions & 0 deletions bindings/pydrake/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,9 @@ def getDrakePath():
def _execute_extra_python_code(m):
# See `ExecuteExtraPythonCode` in `pydrake_pybind.h` for usage details and
# rationale.
if m.__name__ not in sys.modules:
# N.B. This is necessary for C++ extensions in Python 3.
sys.modules[m.__name__] = m
module_path = m.__name__.split(".")
if len(module_path) == 1:
raise RuntimeError((
Expand Down
6 changes: 4 additions & 2 deletions bindings/pydrake/common/cpp_template.py
Original file line number Diff line number Diff line change
Expand Up @@ -278,7 +278,7 @@ def _on_add(self, param, instantiation):
return instantiation

@classmethod
def define(cls, name, param_list, *args, **kwargs):
def define(cls, name, param_list, *args, scope=None, **kwargs):
"""Provides a decorator for functions that defines a template using
`name`. The template instantiations are added using
`add_instantiations`, where the instantiation function is the decorated
Expand Down Expand Up @@ -308,7 +308,9 @@ def __init__(self):
self.T = T
return Impl
"""
template = cls(name, *args, **kwargs)
if scope is None:
scope = _get_module_from_stack()
template = cls(name, *args, scope=scope, **kwargs)

def decorator(instantiation_func):
template.add_instantiations(instantiation_func, param_list)
Expand Down
2 changes: 2 additions & 0 deletions bindings/pydrake/common/test/cpp_template_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,8 @@ def __mangled_method(self):

return Impl

self.assertEqual(
str(MyTemplate), f"<TemplateClass {_TEST_MODULE}.MyTemplate>")
self.assertIsInstance(MyTemplate, m.TemplateClass)
MyDefault = MyTemplate[None]
MyInt = MyTemplate[int]
Expand Down
7 changes: 5 additions & 2 deletions bindings/pydrake/systems/scalar_conversion.py
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,8 @@ def __init__(self, name, T_list=None, T_pairs=None, scope=None):
self._converter = self._make_converter()

@classmethod
def define(cls, name, T_list=None, T_pairs=None, *args, **kwargs):
def define(
cls, name, T_list=None, T_pairs=None, *args, scope=None, **kwargs):
"""Provides a decorator which can be used define a scalar-type
convertible System as a template.
Expand All @@ -126,7 +127,9 @@ class which will be the instantiation for type ``T`` of the given
args, kwargs: These are passed to the constructor of
``TemplateSystem``.
"""
template = cls(name, T_list, T_pairs, *args, **kwargs)
if scope is None:
scope = _get_module_from_stack()
template = cls(name, T_list, T_pairs, *args, scope=scope, **kwargs)
param_list = [(T,) for T in template._T_list]

def decorator(instantiation_func):
Expand Down
4 changes: 3 additions & 1 deletion bindings/pydrake/systems/test/scalar_conversion_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,8 @@ def test_example_system(self):
"""Tests the Example_ system."""
# Test template.
self.assertIsInstance(Example_, TemplateClass)
self.assertEqual(
str(Example_), f"<TemplateSystem {__name__}.Example_>")
self.assertIs(Example_[float], Example)

# Test parameters.
Expand All @@ -68,7 +70,7 @@ def test_example_system(self):
system_T = Example_[T](0)
self.assertEqual(
system_T.GetSystemType(),
f"pydrake.systems.scalar_conversion.Example_[{T.__name__}]")
f"{__name__}.Example_[{T.__name__}]")

# Test private properties (do NOT use these in your code!).
self.assertTupleEqual(
Expand Down

0 comments on commit 6a068e3

Please sign in to comment.