# Path: hypergolix/exceptions.py
# class DeadObject(IPCError, PersistenceError, TypeError):
#     ''' Raised when operations are attempted on a local object that is
#     already dead.
#     '''
#     pass
# 
# Path: hypergolix/exceptions.py
# class LocallyImmutable(IPCError, TypeError):
#     ''' Raised when an object is locally immutable. That means either:
#     1. the object is static
#     2. the object is not "owned" by the currently-logged-in Hypergolix
#         process.
#     '''
#     pass
# 
# Path: hypergolix/exceptions.py
# class Unsharable(IPCError, TypeError):
#     ''' Raised when an object cannot be shared, typically because it is
#     private.
#     '''
#     pass
# 
# Path: hypergolix/utils.py
# async def run_coroutine_loopsafe(coro, target_loop):
#     ''' Threadsafe, asyncsafe (ie non-loop-blocking) call to run a coro 
#     in a different event loop and return the result. Wrap in an asyncio
#     future (or await it) to access the result.
#     
#     Resolves the event loop for the current thread by calling 
#     asyncio.get_event_loop(). Because of internal use of await, CANNOT
#     be called explicitly from a third loop.
#     '''
#     # This returns a concurrent.futures.Future, so we need to wait for it, but
#     # we cannot block our event loop, soooo...
#     thread_future = asyncio.run_coroutine_threadsafe(coro, target_loop)
#     return (await await_sync_future(thread_future))
# 
# Path: hypergolix/utils.py
# def call_coroutine_threadsafe(coro, loop):
#     ''' Wrapper on asyncio.run_coroutine_threadsafe that makes a coro
#     behave as if it were called synchronously. In other words, instead
#     of returning a future, it raises the exception or returns the coro's
#     result.
#     
#     Leaving loop as default None will result in asyncio inferring the 
#     loop from the default from the current context (aka usually thread).
#     '''
#     fut = asyncio.run_coroutine_threadsafe(
#         coro = coro,
#         loop = loop
#     )
#     
#     # Block on completion of coroutine and then raise any created exception
#     exc = fut.exception()
#     if exc:
#         raise exc
#         
#     return fut.result()
# 
# Path: hypergolix/utils.py
# class ApiID(Ghid):
#     ''' Subclass Ghid in a way that makes the API ID seem like a normal
#     64-byte string.
#     
#     Remind me again why the hell I'm subclassing ghid for this when I'm
#     ending up removing just about everything that makes it a ghid?
#     '''
#     
#     def __init__(self, address, algo=None):
#         ''' Wrap the normal Ghid creation with a forced algo.
#         '''
#         if len(address) != 64:
#             raise ValueError('Improper API ID length.')
#         
#         elif algo is None:
#             algo = 0
#             
#         elif algo != 0:
#             raise ValueError('Improper API ID format.')
#         
#         super().__init__(algo, address)
#         
#     def __repr__(self):
#         ''' Hide that this is a ghid.
#         '''
#         return type(self).__name__ + '(' + repr(self.address) + ')'
#         
#     @property
#     def algo(self):
#         return self._algo
#         
#     @algo.setter
#     def algo(self, value):
#         # Currently, ensure algo is b'\x00'
#         if value == 0:
#             self._algo = value
#         else:
#             raise ValueError('Invalid address algorithm.')
#             
#     @property
#     def address(self):
#         return self._address
#             
#     @address.setter
#     def address(self, address):
#         self._address = address
#         
#     @classmethod
#     def pseudorandom(cls):
#         return super().pseudorandom(0)
# 
# Path: hypergolix/utils.py
# def _reap_wrapped_task(task):
#     ''' Reap a task that was wrapped to never raise and then
#     executed autonomously using ensure_future.
#     '''
#     task.result()
# 
# Path: hypergolix/embed.py
# class TriplicateAPI(Triplicate, API):
#     ''' Combine loopa's triplicate metaclass with hypothetical.API.
#     '''
# 
# Path: hypergolix/hypothetical.py
# def public_api(func):
#     ''' Decorator to automatically mark the object as the normal thing.
#     '''
#     
#     def fixture_closure(fixture_func, public_func=func):
#         ''' Defines the decorator for @method.fixture.
#         '''
#         # This is the actual __fixture__ method, to be defined via decorator
#         public_func.__fixture__ = fixture_func
#         return public_func
#     
#     def interface_closure(interface_func, public_func=func):
#         ''' Defines the decorator for @method.fixture.
#         '''
#         # This is the actual __interface method, to be defined via decorator
#         public_func.__interface__ = interface_func
#         return public_func
#         
#     func.fixture = fixture_closure
#     func.interface = interface_closure
#     
#     # This denotes that it is an API
#     func.__is_api__ = True
#     
#     return func
# 
# Path: hypergolix/hypothetical.py
# def fixture_api(func):
#     ''' Decorator to mark the method as a fixture-only object.
#     '''
#     ''' Decorator to automatically mark the object as the normal thing.
#     '''
#     
#     # Huh, well, this is easy.
#     func.__is_fixture__ = True
#     return func


import weakref
import traceback
import asyncio
import operator
import inspect
import json
import pickle
import logging
from loopa.utils import triplicated
from loopa.utils import Triplicate
from .exceptions import DeadObject
from .exceptions import LocallyImmutable
from .exceptions import Unsharable
from .utils import run_coroutine_loopsafe
from .utils import call_coroutine_threadsafe
from .utils import ApiID
from .utils import _reap_wrapped_task
from .embed import TriplicateAPI
from .hypothetical import public_api
from .hypothetical import fixture_api
------------------------------------------------------
'''

# Global dependencies


# Internal deps





# ###############################################
# Boilerplate
# ###############################################


logger = logging.getLogger(__name__)

# Control * imports.
__all__ = [
    # 'Inquisitor',
]


# ###############################################
# Library
# ###############################################



# Path: hypergolix/exceptions.py
# class DeadObject(IPCError, PersistenceError, TypeError):
#     ''' Raised when operations are attempted on a local object that is
#     already dead.
#     '''
#     pass
# 
# Path: hypergolix/exceptions.py
# class LocallyImmutable(IPCError, TypeError):
#     ''' Raised when an object is locally immutable. That means either:
#     1. the object is static
#     2. the object is not "owned" by the currently-logged-in Hypergolix
#         process.
#     '''
#     pass
# 
# Path: hypergolix/exceptions.py
# class Unsharable(IPCError, TypeError):
#     ''' Raised when an object cannot be shared, typically because it is
#     private.
#     '''
#     pass
# 
# Path: hypergolix/utils.py
# async def run_coroutine_loopsafe(coro, target_loop):
#     ''' Threadsafe, asyncsafe (ie non-loop-blocking) call to run a coro 
#     in a different event loop and return the result. Wrap in an asyncio
#     future (or await it) to access the result.
#     
#     Resolves the event loop for the current thread by calling 
#     asyncio.get_event_loop(). Because of internal use of await, CANNOT
#     be called explicitly from a third loop.
#     '''
#     # This returns a concurrent.futures.Future, so we need to wait for it, but
#     # we cannot block our event loop, soooo...
#     thread_future = asyncio.run_coroutine_threadsafe(coro, target_loop)
#     return (await await_sync_future(thread_future))
# 
# Path: hypergolix/utils.py
# def call_coroutine_threadsafe(coro, loop):
#     ''' Wrapper on asyncio.run_coroutine_threadsafe that makes a coro
#     behave as if it were called synchronously. In other words, instead
#     of returning a future, it raises the exception or returns the coro's
#     result.
#     
#     Leaving loop as default None will result in asyncio inferring the 
#     loop from the default from the current context (aka usually thread).
#     '''
#     fut = asyncio.run_coroutine_threadsafe(
#         coro = coro,
#         loop = loop
#     )
#     
#     # Block on completion of coroutine and then raise any created exception
#     exc = fut.exception()
#     if exc:
#         raise exc
#         
#     return fut.result()
# 
# Path: hypergolix/utils.py
# class ApiID(Ghid):
#     ''' Subclass Ghid in a way that makes the API ID seem like a normal
#     64-byte string.
#     
#     Remind me again why the hell I'm subclassing ghid for this when I'm
#     ending up removing just about everything that makes it a ghid?
#     '''
#     
#     def __init__(self, address, algo=None):
#         ''' Wrap the normal Ghid creation with a forced algo.
#         '''
#         if len(address) != 64:
#             raise ValueError('Improper API ID length.')
#         
#         elif algo is None:
#             algo = 0
#             
#         elif algo != 0:
#             raise ValueError('Improper API ID format.')
#         
#         super().__init__(algo, address)
#         
#     def __repr__(self):
#         ''' Hide that this is a ghid.
#         '''
#         return type(self).__name__ + '(' + repr(self.address) + ')'
#         
#     @property
#     def algo(self):
#         return self._algo
#         
#     @algo.setter
#     def algo(self, value):
#         # Currently, ensure algo is b'\x00'
#         if value == 0:
#             self._algo = value
#         else:
#             raise ValueError('Invalid address algorithm.')
#             
#     @property
#     def address(self):
#         return self._address
#             
#     @address.setter
#     def address(self, address):
#         self._address = address
#         
#     @classmethod
#     def pseudorandom(cls):
#         return super().pseudorandom(0)
# 
# Path: hypergolix/utils.py
# def _reap_wrapped_task(task):
#     ''' Reap a task that was wrapped to never raise and then
#     executed autonomously using ensure_future.
#     '''
#     task.result()
# 
# Path: hypergolix/embed.py
# class TriplicateAPI(Triplicate, API):
#     ''' Combine loopa's triplicate metaclass with hypothetical.API.
#     '''
# 
# Path: hypergolix/hypothetical.py
# def public_api(func):
#     ''' Decorator to automatically mark the object as the normal thing.
#     '''
#     
#     def fixture_closure(fixture_func, public_func=func):
#         ''' Defines the decorator for @method.fixture.
#         '''
#         # This is the actual __fixture__ method, to be defined via decorator
#         public_func.__fixture__ = fixture_func
#         return public_func
#     
#     def interface_closure(interface_func, public_func=func):
#         ''' Defines the decorator for @method.fixture.
#         '''
#         # This is the actual __interface method, to be defined via decorator
#         public_func.__interface__ = interface_func
#         return public_func
#         
#     func.fixture = fixture_closure
#     func.interface = interface_closure
#     
#     # This denotes that it is an API
#     func.__is_api__ = True
#     
#     return func
# 
# Path: hypergolix/hypothetical.py
# def fixture_api(func):
#     ''' Decorator to mark the method as a fixture-only object.
#     '''
#     ''' Decorator to automatically mark the object as the normal thing.
#     '''
#     
#     # Huh, well, this is easy.
#     func.__is_fixture__ = True
#     return func


# Path: hypergolix/objproxy.py
import weakref
import traceback
import asyncio
import operator
import inspect
import json
import pickle
import logging
from loopa.utils import triplicated
from loopa.utils import Triplicate
from .exceptions import DeadObject
from .exceptions import LocallyImmutable
from .exceptions import Unsharable
from .utils import run_coroutine_loopsafe
from .utils import call_coroutine_threadsafe
from .utils import ApiID
from .utils import _reap_wrapped_task
from .embed import TriplicateAPI
from .hypothetical import public_api
from .hypothetical import fixture_api

------------------------------------------------------
'''

# Global dependencies


# Internal deps





# ###############################################
# Boilerplate
# ###############################################


logger = logging.getLogger(__name__)

# Control * imports.
__all__ = [
    # 'Inquisitor',
]


# ###############################################
# Library
# ###############################################



class ObjCore(metaclass=TriplicateAPI):