Creates a converted instance and binds it to match original entity.
(entity, converted_entity_info, free_nonglobal_var_names)
| 262 | |
| 263 | |
| 264 | def _instantiate(entity, converted_entity_info, free_nonglobal_var_names): |
| 265 | """Creates a converted instance and binds it to match original entity.""" |
| 266 | factory = converted_entity_info.get_factory() |
| 267 | |
| 268 | # `factory` is currently bound to the empty module it was loaded from. |
| 269 | # It must instead be bound to the globals and closure from the original |
| 270 | # entity. |
| 271 | if tf_inspect.isfunction(entity) or tf_inspect.ismethod(entity): |
| 272 | entity_globals = entity.__globals__ |
| 273 | entity_closure = entity.__closure__ or () |
| 274 | elif hasattr(entity, '__module__'): |
| 275 | entity_globals = sys.modules[entity.__module__].__dict__ |
| 276 | entity_closure = () |
| 277 | assert len(entity_closure) == len(free_nonglobal_var_names) |
| 278 | |
| 279 | # Fit the original entity's cells to match the order of factory's cells. |
| 280 | original_names_and_cells = dict(zip(free_nonglobal_var_names, entity_closure)) |
| 281 | new_factory_cells = tuple( |
| 282 | original_names_and_cells[name] for name in factory.__code__.co_freevars) |
| 283 | |
| 284 | bound_factory = types.FunctionType( |
| 285 | code=factory.__code__, |
| 286 | globals=entity_globals, |
| 287 | name=factory.__name__, |
| 288 | argdefs=(), |
| 289 | closure=new_factory_cells) |
| 290 | |
| 291 | # Two other free vars: the internal "ag__" module and the source |
| 292 | # map. These are wired via the parameters of the factory. |
| 293 | converted_entity = bound_factory( # pylint:disable=not-callable |
| 294 | ag_internal, converted_entity_info.source_map, |
| 295 | converted_entity_info.get_module()) |
| 296 | |
| 297 | if tf_inspect.isfunction(entity) or tf_inspect.ismethod(entity): |
| 298 | # Attach the default argument to the converted function. |
| 299 | converted_entity.__defaults__ = entity.__defaults__ |
| 300 | if hasattr(entity, '__kwdefaults__'): |
| 301 | converted_entity.__kwdefaults__ = entity.__kwdefaults__ |
| 302 | |
| 303 | return converted_entity |
| 304 | |
| 305 | |
| 306 | def convert(entity, program_ctx): |
no test coverage detected