# Path: invenio_records/dictutils.py
# def dict_lookup(source, lookup_key, parent=False):
#     """Make a lookup into a dict based on a dot notation.
# 
#     Examples of the supported dot notation:
# 
#     - ``'a'`` - Equivalent to ``source['a']``
#     - ``'a.b'`` - Equivalent to ``source['a']['b']``
#     - ``'a.b.0'`` - Equivalent to ``source['a']['b'][0]`` (for lists)
# 
#     List notation is also supported:
# 
#     - `['a']``
#     - ``['a','b']``
#     - ``['a','b', 0]``
# 
#     :param source: The dictionary object to perform the lookup in.
#     :param parent: If parent argument is True, returns the parent node of
#                    matched object.
#     :param lookup_key: A string using dot notation, or a list of keys.
#     """
#     # Copied from dictdiffer (CERN contributed part) and slightly modified.
#     keys = parse_lookup_key(lookup_key)
# 
#     if parent:
#         keys = keys[:-1]
# 
#     # Lookup the key
#     value = source
#     for key in keys:
#         try:
#             if isinstance(value, list):
#                 key = int(key)
#             value = value[key]
#         except (TypeError, IndexError, ValueError) as exc:
#             raise KeyError(lookup_key) from exc
#     return value
# 
# def parse_lookup_key(lookup_key):
#     """Parse a lookup key."""
#     if not lookup_key:
#         raise KeyError("No lookup key specified")
# 
#     # Parse the list of keys
#     if isinstance(lookup_key, str):
#         keys = lookup_key.split('.')
#     elif isinstance(lookup_key, list):
#         keys = lookup_key
#     else:
#         raise TypeError('lookup must be string or list')
# 
#     return keys
# 
# Path: invenio_records/extensions.py
# class ExtensionMixin:
#     """Defines the methods needed by an extension."""
# 
#     def pre_init(self, record, data, model=None, **kwargs):
#         """Called when a new record instance is initialized.
# 
#         Called when a new record is instantiated (i.e. during all
#         ``Record({...})``). This means it's also called when e.g. a record
#         is created via ``Record.create()``.
# 
#         :param data: The dict passed to the record's constructor.
#         :param model: The model class used for initialization.
#         """
# 
#     def post_init(self, record, data, model=None, **kwargs):
#         """Called after a record is initialized."""
# 
#     def pre_dump(self, record, data, dumper=None):
#         """Called before a record is dumped."""
# 
#     def post_dump(self, record, data, dumper=None):
#         """Called after a record is dumped."""
# 
#     def pre_load(self, data, loader=None):
#         """Called before a record is loaded."""
# 
#     def post_load(self, record, data, loader=None):
#         """Called after a record is loaded."""
# 
#     def pre_create(self, record):
#         """Called before a record is created."""
# 
#     def post_create(self, record):
#         """Called after a record is created."""
# 
#     def pre_commit(self, record):
#         """Called before a record is committed."""
# 
#     def pre_delete(self, record, force=False):
#         """Called before a record is deleted."""
# 
#     def post_delete(self, record, force=False):
#         """Called after a record is deleted."""
# 
#     def pre_revert(self, record, revision):
#         """Called before a record is reverted."""
# 
#     def post_revert(self, new_record, revision):
#         """Called after a record is reverted."""
# 
# class RecordExtension(ExtensionMixin):
#     """Base class for a record extensions."""
# 
# class RecordMeta(type):
#     """Metaclass responsible for initializing the extension registry."""
# 
#     def __new__(mcs, name, bases, attrs):
#         """Create a new record class."""
#         # Initialise an "_extensions" attribute on each class, to ensure each
#         # class have a separate extensions registry.
#         if '_extensions' not in attrs:
#             attrs['_extensions'] = []
# 
#         # Construct the class.
#         return super().__new__(mcs, name, bases, attrs)


import inspect
import warnings
from ..dictutils import dict_lookup, parse_lookup_key
from ..extensions import ExtensionMixin, RecordExtension, RecordMeta
    return fields


class SystemFieldContext:
    """Base class for a system field context.

    A system field context is created once you access a field's attribute on
    a class. As the system field may be defined on a super class, this context
    allows us to know from which class the field was accessed.

    Normally you should subclass this class, and implement methods the methods
    on it that requires you to know the record class.
    """

    def __init__(self, field, record_cls):
        """Initialise the field context."""
        self._field = field
        self._record_cls = record_cls

    @property
    def field(self):
        """Access the field to prevent it from being overwritten."""
        return self._field

    @property
    def record_cls(self):
        """Record class to prevent it from being overwritten."""
        return self._record_cls



# Path: invenio_records/dictutils.py
# def dict_lookup(source, lookup_key, parent=False):
#     """Make a lookup into a dict based on a dot notation.
# 
#     Examples of the supported dot notation:
# 
#     - ``'a'`` - Equivalent to ``source['a']``
#     - ``'a.b'`` - Equivalent to ``source['a']['b']``
#     - ``'a.b.0'`` - Equivalent to ``source['a']['b'][0]`` (for lists)
# 
#     List notation is also supported:
# 
#     - `['a']``
#     - ``['a','b']``
#     - ``['a','b', 0]``
# 
#     :param source: The dictionary object to perform the lookup in.
#     :param parent: If parent argument is True, returns the parent node of
#                    matched object.
#     :param lookup_key: A string using dot notation, or a list of keys.
#     """
#     # Copied from dictdiffer (CERN contributed part) and slightly modified.
#     keys = parse_lookup_key(lookup_key)
# 
#     if parent:
#         keys = keys[:-1]
# 
#     # Lookup the key
#     value = source
#     for key in keys:
#         try:
#             if isinstance(value, list):
#                 key = int(key)
#             value = value[key]
#         except (TypeError, IndexError, ValueError) as exc:
#             raise KeyError(lookup_key) from exc
#     return value
# 
# def parse_lookup_key(lookup_key):
#     """Parse a lookup key."""
#     if not lookup_key:
#         raise KeyError("No lookup key specified")
# 
#     # Parse the list of keys
#     if isinstance(lookup_key, str):
#         keys = lookup_key.split('.')
#     elif isinstance(lookup_key, list):
#         keys = lookup_key
#     else:
#         raise TypeError('lookup must be string or list')
# 
#     return keys
# 
# Path: invenio_records/extensions.py
# class ExtensionMixin:
#     """Defines the methods needed by an extension."""
# 
#     def pre_init(self, record, data, model=None, **kwargs):
#         """Called when a new record instance is initialized.
# 
#         Called when a new record is instantiated (i.e. during all
#         ``Record({...})``). This means it's also called when e.g. a record
#         is created via ``Record.create()``.
# 
#         :param data: The dict passed to the record's constructor.
#         :param model: The model class used for initialization.
#         """
# 
#     def post_init(self, record, data, model=None, **kwargs):
#         """Called after a record is initialized."""
# 
#     def pre_dump(self, record, data, dumper=None):
#         """Called before a record is dumped."""
# 
#     def post_dump(self, record, data, dumper=None):
#         """Called after a record is dumped."""
# 
#     def pre_load(self, data, loader=None):
#         """Called before a record is loaded."""
# 
#     def post_load(self, record, data, loader=None):
#         """Called after a record is loaded."""
# 
#     def pre_create(self, record):
#         """Called before a record is created."""
# 
#     def post_create(self, record):
#         """Called after a record is created."""
# 
#     def pre_commit(self, record):
#         """Called before a record is committed."""
# 
#     def pre_delete(self, record, force=False):
#         """Called before a record is deleted."""
# 
#     def post_delete(self, record, force=False):
#         """Called after a record is deleted."""
# 
#     def pre_revert(self, record, revision):
#         """Called before a record is reverted."""
# 
#     def post_revert(self, new_record, revision):
#         """Called after a record is reverted."""
# 
# class RecordExtension(ExtensionMixin):
#     """Base class for a record extensions."""
# 
# class RecordMeta(type):
#     """Metaclass responsible for initializing the extension registry."""
# 
#     def __new__(mcs, name, bases, attrs):
#         """Create a new record class."""
#         # Initialise an "_extensions" attribute on each class, to ensure each
#         # class have a separate extensions registry.
#         if '_extensions' not in attrs:
#             attrs['_extensions'] = []
# 
#         # Construct the class.
#         return super().__new__(mcs, name, bases, attrs)


# Path: invenio_records/systemfields/base.py
import inspect
import warnings
from ..dictutils import dict_lookup, parse_lookup_key
from ..extensions import ExtensionMixin, RecordExtension, RecordMeta

    return fields


class SystemFieldContext:
    """Base class for a system field context.

    A system field context is created once you access a field's attribute on
    a class. As the system field may be defined on a super class, this context
    allows us to know from which class the field was accessed.

    Normally you should subclass this class, and implement methods the methods
    on it that requires you to know the record class.
    """

    def __init__(self, field, record_cls):
        """Initialise the field context."""
        self._field = field
        self._record_cls = record_cls

    @property
    def field(self):
        """Access the field to prevent it from being overwritten."""
        return self._field

    @property
    def record_cls(self):
        """Record class to prevent it from being overwritten."""
        return self._record_cls



class SystemField(ExtensionMixin):