def create_section(self, course_id, name, sis_section_id):
        """
        Create a canvas section in the given course id.

        https://canvas.instructure.com/doc/api/sections.html#method.sections.create
        """
        url = COURSES_API.format(course_id) + "/sections"
        body = {"course_section": {"name": name,
                                   "sis_section_id": sis_section_id}}

        return CanvasSection(data=self._post_resource(url, body))

def create_section ( self , course_id , name , sis_section_id ) : url = COURSES_API . format ( course_id ) + "/sections" body = { "course_section" : { "name" : name , "sis_section_id" : sis_section_id } } return CanvasSection ( data = self . _post_resource ( url , body ) )

Create a canvas section in the given course id .


def update_section(self, section_id, name, sis_section_id):
        """
        Update a canvas section with the given section id.

        https://canvas.instructure.com/doc/api/sections.html#method.sections.update
        """
        url = SECTIONS_API.format(section_id)
        body = {"course_section": {}}

        if name:
            body["course_section"]["name"] = name

        if sis_section_id:
            body["course_section"]["sis_section_id"] = sis_section_id

        return CanvasSection(data=self._put_resource(url, body))

def update_section ( self , section_id , name , sis_section_id ) : url = SECTIONS_API . format ( section_id ) body = { "course_section" : { } } if name : body [ "course_section" ] [ "name" ] = name if sis_section_id : body [ "course_section" ] [ "sis_section_id" ] = sis_section_id return CanvasSection ( data = self . _put_resource ( url , body ) )

Update a canvas section with the given section id .


def get_quizzes(self, course_id):
        """
        List quizzes for a given course

        https://canvas.instructure.com/doc/api/quizzes.html#method.quizzes_api.index
        """
        url = QUIZZES_API.format(course_id)
        data = self._get_resource(url)
        quizzes = []
        for datum in data:
            quizzes.append(Quiz(data=datum))
        return quizzes

def get_quizzes ( self , course_id ) : url = QUIZZES_API . format ( course_id ) data = self . _get_resource ( url ) quizzes = [ ] for datum in data : quizzes . append ( Quiz ( data = datum ) ) return quizzes


def get_account(self, account_id):
        """
        Return account resource for given canvas account id.

        https://canvas.instructure.com/doc/api/accounts.html#method.accounts.show
        """
        url = ACCOUNTS_API.format(account_id)
        return CanvasAccount(data=self._get_resource(url))

def get_account ( self , account_id ) : url = ACCOUNTS_API . format ( account_id ) return CanvasAccount ( data = self . _get_resource ( url ) )

Return account resource for given canvas account id .


def get_sub_accounts(self, account_id, params={}):
        """
        Return list of subaccounts within the account with the passed
        canvas id.

        https://canvas.instructure.com/doc/api/accounts.html#method.accounts.sub_accounts
        """
        url = ACCOUNTS_API.format(account_id) + "/sub_accounts"

        accounts = []
        for datum in self._get_paged_resource(url, params=params):
            accounts.append(CanvasAccount(data=datum))

        return accounts

def get_sub_accounts ( self , account_id , params = { } ) : url = ACCOUNTS_API . format ( account_id ) + "/sub_accounts" accounts = [ ] for datum in self . _get_paged_resource ( url , params = params ) : accounts . append ( CanvasAccount ( data = datum ) ) return accounts

Return list of subaccounts within the account with the passed canvas id .


def update_account(self, account):
        """
        Update the passed account. Returns the updated account.

        https://canvas.instructure.com/doc/api/accounts.html#method.accounts.update
        """
        url = ACCOUNTS_API.format(account.account_id)
        body = {"account": {"name": account.name}}

        return CanvasAccount(data=self._put_resource(url, body))

def update_account ( self , account ) : url = ACCOUNTS_API . format ( account . account_id ) body = { "account" : { "name" : account . name } } return CanvasAccount ( data = self . _put_resource ( url , body ) )

Update the passed account . Returns the updated account .


def update_sis_id(self, account_id, sis_account_id):
        """
        Updates the SIS ID for the account identified by the passed account ID.

        https://canvas.instructure.com/doc/api/accounts.html#method.accounts.update
        """
        if account_id == self._canvas_account_id:
            raise Exception("SIS ID cannot be updated for the root account")

        url = ACCOUNTS_API.format(account_id)
        body = {"account": {"sis_account_id": sis_account_id}}

        return CanvasAccount(data=self._put_resource(url, body))

Updates the SIS ID for the account identified by the passed account ID .


def get_auth_settings(self, account_id):
        """
        Return the authentication settings for the passed account_id.

        https://canvas.instructure.com/doc/api/authentication_providers.html#method.account_authorization_configs.show_sso_settings
        """
        url = ACCOUNTS_API.format(account_id) + "/sso_settings"
        return CanvasSSOSettings(data=self._get_resource(url))

def get_auth_settings ( self , account_id ) : url = ACCOUNTS_API . format ( account_id ) + "/sso_settings" return CanvasSSOSettings ( data = self . _get_resource ( url ) )

Return the authentication settings for the passed account_id .


def update_auth_settings(self, account_id, auth_settings):
        """
        Update the authentication settings for the passed account_id.

        https://canvas.instructure.com/doc/api/authentication_providers.html#method.account_authorization_configs.update_sso_settings
        """
        url = ACCOUNTS_API.format(account_id) + "/sso_settings"
        data = self._put_resource(url, auth_settings.json_data())
        return CanvasSSOSettings(data=data)

def update_auth_settings ( self , account_id , auth_settings ) : url = ACCOUNTS_API . format ( account_id ) + "/sso_settings" data = self . _put_resource ( url , auth_settings . json_data ( ) ) return CanvasSSOSettings ( data = data )

Update the authentication settings for the passed account_id .


def get_term_by_sis_id(self, sis_term_id):
        """
        Return a term resource for the passed SIS ID.
        """
        for term in self.get_all_terms():
            if term.sis_term_id == sis_term_id:
                return term

def get_term_by_sis_id ( self , sis_term_id ) : for term in self . get_all_terms ( ) : if term . sis_term_id == sis_term_id : return term

Return a term resource for the passed SIS ID .


def import_str(self, csv, params={}):
        """
        Imports a CSV string.

        https://canvas.instructure.com/doc/api/sis_imports.html#method.sis_imports_api.create
        """
        if not self._canvas_account_id:
            raise MissingAccountID()

        params["import_type"] = SISImportModel.CSV_IMPORT_TYPE
        url = SIS_IMPORTS_API.format(
            self._canvas_account_id) + ".json{}".format(self._params(params))
        headers = {"Content-Type": "text/csv"}

        return SISImportModel(data=self._post_resource(url, headers, csv))

def import_str ( self , csv , params = { } ) : if not self . _canvas_account_id : raise MissingAccountID ( ) params [ "import_type" ] = SISImportModel . CSV_IMPORT_TYPE url = SIS_IMPORTS_API . format ( self . _canvas_account_id ) + ".json{}" . format ( self . _params ( params ) ) headers = { "Content-Type" : "text/csv" } return SISImportModel ( data = self . _post_resource ( url , headers , csv ) )


def import_dir(self, dir_path, params={}):
        """
        Imports a directory of CSV files.

        https://canvas.instructure.com/doc/api/sis_imports.html#method.sis_imports_api.create
        """
        if not self._canvas_account_id:
            raise MissingAccountID()

        body = self._build_archive(dir_path)
        params["import_type"] = SISImportModel.CSV_IMPORT_TYPE
        url = SIS_IMPORTS_API.format(
            self._canvas_account_id) + ".json{}".format(self._params(params))
        headers = {"Content-Type": "application/zip"}

        return SISImportModel(data=self._post_resource(url, headers, body))

def import_dir ( self , dir_path , params = { } ) : if not self . _canvas_account_id : raise MissingAccountID ( ) body = self . _build_archive ( dir_path ) params [ "import_type" ] = SISImportModel . CSV_IMPORT_TYPE url = SIS_IMPORTS_API . format ( self . _canvas_account_id ) + ".json{}" . format ( self . _params ( params ) ) headers = { "Content-Type" : "application/zip" } return SISImportModel ( data = self . _post_resource ( url , headers , body ) )


def get_import_status(self, sis_import):
        """
        Get the status of an already created SIS import.

        https://canvas.instructure.com/doc/api/sis_imports.html#method.sis_imports_api.show
        """
        if not self._canvas_account_id:
            raise MissingAccountID()

        url = SIS_IMPORTS_API.format(
            self._canvas_account_id) + "/{}.json".format(sis_import.import_id)

        return SISImportModel(data=self._get_resource(url))

def get_import_status ( self , sis_import ) : if not self . _canvas_account_id : raise MissingAccountID ( ) url = SIS_IMPORTS_API . format ( self . _canvas_account_id ) + "/{}.json" . format ( sis_import . import_id ) return SISImportModel ( data = self . _get_resource ( url ) )

Get the status of an already created SIS import .


def _build_archive(self, dir_path):
        """
        Creates a zip archive from files in path.
        """
        zip_path = os.path.join(dir_path, "import.zip")
        archive = zipfile.ZipFile(zip_path, "w")

        for filename in CSV_FILES:
            filepath = os.path.join(dir_path, filename)

            if os.path.exists(filepath):
                archive.write(filepath, filename, zipfile.ZIP_DEFLATED)

        archive.close()

        with open(zip_path, "rb") as f:
            body = f.read()

        return body

def _build_archive ( self , dir_path ) : zip_path = os . path . join ( dir_path , "import.zip" ) archive = zipfile . ZipFile ( zip_path , "w" ) for filename in CSV_FILES : filepath = os . path . join ( dir_path , filename ) if os . path . exists ( filepath ) : archive . write ( filepath , filename , zipfile . ZIP_DEFLATED ) archive . close ( ) with open ( zip_path , "rb" ) as f : body = f . read ( ) return body

Creates a zip archive from files in path .


def get_assignments(self, course_id):
        """
        List assignments for a given course

        https://canvas.instructure.com/doc/api/assignments.html#method.assignments_api.index
        """
        url = ASSIGNMENTS_API.format(course_id)
        data = self._get_resource(url)
        assignments = []
        for datum in data:
            assignments.append(Assignment(data=datum))
        return assignments

def get_assignments ( self , course_id ) : url = ASSIGNMENTS_API . format ( course_id ) data = self . _get_resource ( url ) assignments = [ ] for datum in data : assignments . append ( Assignment ( data = datum ) ) return assignments


def update_assignment(self, assignment):
        """
        Modify an existing assignment.

        https://canvas.instructure.com/doc/api/assignments.html#method.assignments_api.update
        """
        url = ASSIGNMENTS_API.format(assignment.course_id) + "/{}".format(
            assignment.assignment_id)

        data = self._put_resource(url, assignment.json_data())
        return Assignment(data=data)

def update_assignment ( self , assignment ) : url = ASSIGNMENTS_API . format ( assignment . course_id ) + "/{}" . format ( assignment . assignment_id ) data = self . _put_resource ( url , assignment . json_data ( ) ) return Assignment ( data = data )


def get_available_reports(self, account_id):
        """
        Returns the list of reports for the canvas account id.

        https://canvas.instructure.com/doc/api/account_reports.html#method.account_reports.available_reports
        """
        url = ACCOUNTS_API.format(account_id) + "/reports"

        report_types = []
        for datum in self._get_resource(url):
            report_types.append(ReportType(data=datum, account_id=account_id))
        return report_types

def get_available_reports ( self , account_id ) : url = ACCOUNTS_API . format ( account_id ) + "/reports" report_types = [ ] for datum in self . _get_resource ( url ) : report_types . append ( ReportType ( data = datum , account_id = account_id ) ) return report_types

Returns the list of reports for the canvas account id .


def get_reports_by_type(self, account_id, report_type):
        """
        Shows all reports of the passed report_type that have been run
        for the canvas account id.

        https://canvas.instructure.com/doc/api/account_reports.html#method.account_reports.index
        """
        url = ACCOUNTS_API.format(account_id) + "/reports/{}".format(
            report_type)

        reports = []
        for datum in self._get_resource(url):
            datum["account_id"] = account_id
            reports.append(Report(data=datum))

        return reports

def get_reports_by_type ( self , account_id , report_type ) : url = ACCOUNTS_API . format ( account_id ) + "/reports/{}" . format ( report_type ) reports = [ ] for datum in self . _get_resource ( url ) : datum [ "account_id" ] = account_id reports . append ( Report ( data = datum ) ) return reports

Shows all reports of the passed report_type that have been run for the canvas account id .


def create_report(self, report_type, account_id, term_id=None, params={}):
        """
        Generates a report instance for the canvas account id.

        https://canvas.instructure.com/doc/api/account_reports.html#method.account_reports.create
        """
        if term_id is not None:
            params["enrollment_term_id"] = term_id

        url = ACCOUNTS_API.format(account_id) + "/reports/{}".format(
            report_type)
        body = {"parameters": params}

        data = self._post_resource(url, body)
        data["account_id"] = account_id
        return Report(data=data)

def create_report ( self , report_type , account_id , term_id = None , params = { } ) : if term_id is not None : params [ "enrollment_term_id" ] = term_id url = ACCOUNTS_API . format ( account_id ) + "/reports/{}" . format ( report_type ) body = { "parameters" : params } data = self . _post_resource ( url , body ) data [ "account_id" ] = account_id return Report ( data = data )

Generates a report instance for the canvas account id .


def create_course_provisioning_report(self, account_id, term_id=None,
                                          params={}):
        """
        Convenience method for create_report, for creating a course
        provisioning report.
        """
        params["courses"] = True
        return self.create_report(ReportType.PROVISIONING, account_id, term_id,
                                  params)

def create_course_provisioning_report ( self , account_id , term_id = None , params = { } ) : params [ "courses" ] = True return self . create_report ( ReportType . PROVISIONING , account_id , term_id , params )

Convenience method for create_report for creating a course provisioning report .


def create_course_sis_export_report(self, account_id, term_id=None,
                                        params={}):
        """
        Convenience method for create_report, for creating a course sis export
        report.
        """
        params["courses"] = True
        return self.create_report(ReportType.SIS_EXPORT, account_id, term_id,
                                  params)

def create_course_sis_export_report ( self , account_id , term_id = None , params = { } ) : params [ "courses" ] = True return self . create_report ( ReportType . SIS_EXPORT , account_id , term_id , params )

Convenience method for create_report for creating a course sis export report .


def create_unused_courses_report(self, account_id, term_id=None):
        """
        Convenience method for create_report, for creating an unused courses
        report.
        """
        return self.create_report(ReportType.UNUSED_COURSES, account_id,
                                  term_id)

def create_unused_courses_report ( self , account_id , term_id = None ) : return self . create_report ( ReportType . UNUSED_COURSES , account_id , term_id )

Convenience method for create_report for creating an unused courses report .


def get_report_data(self, report):
        """
        Returns a completed report as a list of csv strings.
        """
        if report.report_id is None or report.status is None:
            raise ReportFailureException(report)

        interval = getattr(settings, 'CANVAS_REPORT_POLLING_INTERVAL', 5)
        while report.status != "complete":
            if report.status == "error":
                raise ReportFailureException(report)
            sleep(interval)
            report = self.get_report_status(report)

        if report.attachment is None or report.attachment.url is None:
            return

        data = self._get_report_file(report.attachment.url)

        return data.split("\n")

def get_report_data ( self , report ) : if report . report_id is None or report . status is None : raise ReportFailureException ( report ) interval = getattr ( settings , 'CANVAS_REPORT_POLLING_INTERVAL' , 5 ) while report . status != "complete" : if report . status == "error" : raise ReportFailureException ( report ) sleep ( interval ) report = self . get_report_status ( report ) if report . attachment is None or report . attachment . url is None : return data = self . _get_report_file ( report . attachment . url ) return data . split ( "\n" )

Returns a completed report as a list of csv strings .


def get_report_status(self, report):
        """
        Returns the status of a report.

        https://canvas.instructure.com/doc/api/account_reports.html#method.account_reports.show
        """
        if (report.account_id is None or report.type is None or
                report.report_id is None):
            raise ReportFailureException(report)

        url = ACCOUNTS_API.format(report.account_id) + "/reports/{}/{}".format(
            report.type, report.report_id)

        data = self._get_resource(url)
        data["account_id"] = report.account_id
        return Report(data=data)

def get_report_status ( self , report ) : if ( report . account_id is None or report . type is None or report . report_id is None ) : raise ReportFailureException ( report ) url = ACCOUNTS_API . format ( report . account_id ) + "/reports/{}/{}" . format ( report . type , report . report_id ) data = self . _get_resource ( url ) data [ "account_id" ] = report . account_id return Report ( data = data )


def delete_report(self, report):
        """
        Deletes a generated report instance.

        https://canvas.instructure.com/doc/api/account_reports.html#method.account_reports.destroy
        """
        url = ACCOUNTS_API.format(report.account_id) + "/reports/{}/{}".format(
            report.type, report.report_id)

        response = self._delete_resource(url)
        return True

def delete_report ( self , report ) : url = ACCOUNTS_API . format ( report . account_id ) + "/reports/{}/{}" . format ( report . type , report . report_id ) response = self . _delete_resource ( url ) return True


def move_detections(label, dy, dx):
    """
    Move detections in direction dx, dy.

    :param label: The label dict containing all detection lists.
    :param dy: The delta in y direction as a number.
    :param dx: The delta in x direction as a number.
    :return:
    """
    for k in label.keys():
        if k.startswith("detection"):
            detections = label[k]
            for detection in detections:
                detection.move_image(-dx, -dy)

def move_detections ( label , dy , dx ) : for k in label . keys ( ) : if k . startswith ( "detection" ) : detections = label [ k ] for detection in detections : detection . move_image ( - dx , - dy )


def hflip_detections(label, w):
    """
    Horizontally flip detections according to an image flip.

    :param label: The label dict containing all detection lists.
    :param w: The width of the image as a number.
    :return:
    """
    for k in label.keys():
        if k.startswith("detection"):
            detections = label[k]
            for detection in detections:
                detection.cx = w - detection.cx
                if k == "detections_2.5d":
                    detection.theta = math.pi - detection.theta

def hflip_detections ( label , w ) : for k in label . keys ( ) : if k . startswith ( "detection" ) : detections = label [ k ] for detection in detections : detection . cx = w - detection . cx if k == "detections_2.5d" : detection . theta = math . pi - detection . theta

Horizontally flip detections according to an image flip .


def get_dict_from_obj(obj):
    '''
    Edit to get the dict even when the object is a GenericRelatedObjectManager.
    Added the try except.
    '''
    obj_dict = obj.__dict__
    obj_dict_result = obj_dict.copy()
    for key, value in obj_dict.items():
        if key.endswith('_id'):
            key2 = key.replace('_id', '')
            try:
                field, model, direct, m2m = obj._meta.get_field_by_name(key2)
                if isinstance(field, ForeignKey):
                    obj_dict_result[key2] = obj_dict_result[key]
                    del obj_dict_result[key]
            except FieldDoesNotExist:
                pass
    manytomany_list = obj._meta.many_to_many
    for manytomany in manytomany_list:
        pks = [obj_rel.pk for obj_rel in manytomany.value_from_object(obj).select_related()]
        if pks:
            obj_dict_result[manytomany.name] = pks
    return obj_dict_result

def get_dict_from_obj ( obj ) : obj_dict = obj . __dict__ obj_dict_result = obj_dict . copy ( ) for key , value in obj_dict . items ( ) : if key . endswith ( '_id' ) : key2 = key . replace ( '_id' , '' ) try : field , model , direct , m2m = obj . _meta . get_field_by_name ( key2 ) if isinstance ( field , ForeignKey ) : obj_dict_result [ key2 ] = obj_dict_result [ key ] del obj_dict_result [ key ] except FieldDoesNotExist : pass manytomany_list = obj . _meta . many_to_many for manytomany in manytomany_list : pks = [ obj_rel . pk for obj_rel in manytomany . value_from_object ( obj ) . select_related ( ) ] if pks : obj_dict_result [ manytomany . name ] = pks return obj_dict_result

Edit to get the dict even when the object is a GenericRelatedObjectManager . Added the try except .


def get_config(self, request, **kwargs):
        """
        Get the arguments given to the template tag element and complete these
        with the ones from the settings.py if necessary.
        """
        config = kwargs

        config_from_settings = deepcopy(inplace_settings.DEFAULT_INPLACE_EDIT_OPTIONS)
        config_one_by_one = inplace_settings.DEFAULT_INPLACE_EDIT_OPTIONS_ONE_BY_ONE

        if not config_one_by_one:
            # Solution 1: Using default config only if none specified.
            if not config and config_from_settings:
                config = config_from_settings
        else:
            # Solution 2: Updating the configured config with the default one.
            config = dict(config_from_settings, **config)
        return config

def get_config ( self , request , ** kwargs ) : config = kwargs config_from_settings = deepcopy ( inplace_settings . DEFAULT_INPLACE_EDIT_OPTIONS ) config_one_by_one = inplace_settings . DEFAULT_INPLACE_EDIT_OPTIONS_ONE_BY_ONE if not config_one_by_one : if not config and config_from_settings : config = config_from_settings else : config = dict ( config_from_settings , ** config ) return config

Get the arguments given to the template tag element and complete these with the ones from the settings . py if necessary .


def empty_value(self):
        '''
        Get the text to display when the field is empty.
        '''
        edit_empty_value = self.config.get('edit_empty_value', False)
        if edit_empty_value:
            return edit_empty_value
        else:
            return unicode(inplace_settings.INPLACEEDIT_EDIT_EMPTY_VALUE)

def empty_value ( self ) : edit_empty_value = self . config . get ( 'edit_empty_value' , False ) if edit_empty_value : return edit_empty_value else : return unicode ( inplace_settings . INPLACEEDIT_EDIT_EMPTY_VALUE )

Get the text to display when the field is empty .


def parse_args_kwargs(parser, token):
    """
    Parse uniformly args and kwargs from a templatetag

    Usage::

      For parsing a template like this:

      {% footag my_contents,height=10,zoom=20 as myvar %}

      You simply do this:

      @register.tag
      def footag(parser, token):
          args, kwargs = parse_args_kwargs(parser, token)
    """
    bits = token.contents.split(' ')

    if len(bits) <= 1:
        raise template.TemplateSyntaxError("'%s' takes at least one argument" % bits[0])

    if token.contents[13] == '"':
        end_quote = token.contents.index('"', 14) + 1
        args = [template.Variable(token.contents[13:end_quote])]
        kwargs_start = end_quote
    else:
        try:
            next_space = token.contents.index(' ', 14)
            kwargs_start = next_space + 1
        except ValueError:
            next_space = None
            kwargs_start = None
        args = [template.Variable(token.contents[13:next_space])]

    kwargs = {}
    kwargs_list = token.contents[kwargs_start:].split(',')
    for kwargs_item in kwargs_list:
        if '=' in kwargs_item:
            k, v = kwargs_item.split('=', 1)
            k = k.strip()
            kwargs[k] = template.Variable(v)
    return args, kwargs

def
parse_args_kwargs
(
parser
,
token
)
:
bits
=
token
.
contents
.
split
(
' '
)
if
len
(
bits
)
<=
1
:
raise
template
.
TemplateSyntaxError
(
"'%s' takes at least one argument"
%
bits
[
0
]
)
if
token
.
contents
[
13
]
==
'"'
:
end_quote
=
token
.
contents
.
index
(
'"'
,
14
)
+
1
args
=
[
template
.
Variable
(
token
.
contents
[
13
:
end_quote
]
)
]
kwargs_start
=
end_quote
else
:
try
:
next_space
=
token
.
contents
.
index
(
' '
,
14
)
kwargs_start
=
next_space
+
1
except
ValueError
:
next_space
=
kwargs_start
=
args
=
[
template
.
Variable
(
token
.
contents
[
13
:
next_space
]
)
]
kwargs
=
{
}
kwargs_list
=
token
.
contents
[
kwargs_start
:
]
.
split
(
','
)
for
kwargs_item
in
kwargs_list
:
if
'='
in
kwargs_item
:
k
,
v
=
kwargs_item
.
split
(
'='
,
1
)
k
=
k
.
strip
(
)
kwargs
[
k
]
=
template
.
Variable
(
v
)
return
args
,
kwargs


def create_metrics(
            self, metric_configs: Iterable[MetricConfig]) -> Dict[str, Metric]:
        """Create and register metrics from a list of MetricConfigs."""
        return self.registry.create_metrics(metric_configs)

def create_metrics ( self , metric_configs : Iterable [ MetricConfig ] ) -> Dict [ str , Metric ] : return self . registry . create_metrics ( metric_configs )

Create and register metrics from a list of MetricConfigs .


def _setup_logging(self, log_level: str):
        """Setup logging for the application and aiohttp."""
        level = getattr(logging, log_level)
        names = (
            'aiohttp.access', 'aiohttp.internal', 'aiohttp.server',
            'aiohttp.web', self.name)
        for name in names:
            setup_logger(name=name, stream=sys.stderr, level=level)

def _setup_logging ( self , log_level : str ) : level = getattr ( logging , log_level ) names = ( 'aiohttp.access' , 'aiohttp.internal' , 'aiohttp.server' , 'aiohttp.web' , self . name ) for name in names : setup_logger ( name = name , stream = sys . stderr , level = level )

Setup logging for the application and aiohttp .


def _configure_registry(self, include_process_stats: bool = False):
        """Configure the MetricRegistry."""
        if include_process_stats:
            self.registry.register_additional_collector(
                ProcessCollector(registry=None))

def _configure_registry ( self , include_process_stats : bool = False ) : if include_process_stats : self . registry . register_additional_collector ( ProcessCollector ( registry = None ) )


def create_metrics(self,
                       configs: Iterable[MetricConfig]) -> Dict[str, Metric]:
        """Create Prometheus metrics from a list of MetricConfigs."""
        metrics: Dict[str, Metric] = {
            config.name: self._register_metric(config)
            for config in configs
        }
        self._metrics.update(metrics)
        return metrics

def create_metrics ( self , configs : Iterable [ MetricConfig ] ) -> Dict [ str , Metric ] : metrics : Dict [ str , Metric ] = { config . name : self . _register_metric ( config ) for config in configs } self . _metrics . update ( metrics ) return metrics

Create Prometheus metrics from a list of MetricConfigs .


def get_metric(
            self, name: str,
            labels: Union[Dict[str, str], None] = None) -> Metric:
        """Return a metric, optionally configured with labels."""
        metric = self._metrics[name]
        if labels:
            return metric.labels(**labels)

        return metric

def get_metric ( self , name : str , labels : Union [ Dict [ str , str ] , None ] = None ) -> Metric : metric = self . _metrics [ name ] if labels : return metric . labels ( ** labels ) return metric

Return a metric optionally configured with labels .


async def _handle_home(self, request: Request) -> Response:
        """Home page request handler."""
        if self.description:
            title = f'{self.name} - {self.description}'
        else:
            title = self.name

        text = dedent(
            f'''<!DOCTYPE html>

                <title>{title}</title>

{title}

                  Metric are exported at the
                  /metrics endpoint.

            ''')
        return Response(content_type='text/html', text=text)

async
def
_handle_home
(
self
,
request
:
Request
)
->
Response
:
if
self
.
description
:
title
=
f'{self.name} - {self.description}'
else
:
title
=
self
.
name
text
=
dedent
(
f
)
return
Response
(
content_type
=
'text/html'
,
text
=
text
)


async def _handle_metrics(self, request: Request) -> Response:
        """Handler for metrics."""
        if self._update_handler:
            await self._update_handler(self.registry.get_metrics())
        response = Response(body=self.registry.generate_metrics())
        response.content_type = CONTENT_TYPE_LATEST
        return response

async def _handle_metrics ( self , request : Request ) -> Response : if self . _update_handler : await self . _update_handler ( self . registry . get_metrics ( ) ) response = Response ( body = self . registry . generate_metrics ( ) ) response . content_type = CONTENT_TYPE_LATEST return response


def wa(client, event, channel, nick, rest):
	"""
	A free-text query resolver by Wolfram|Alpha. Returns the first
	result, if available.
	"""
	client = wolframalpha.Client(pmxbot.config['Wolfram|Alpha API key'])
	res = client.query(rest)
	return next(res.results).text

def
wa
(
client
,
event
,
channel
,
nick
,
rest
)
:
client
=
wolframalpha
.
Client
(
pmxbot
.
config
[
'Wolfram|Alpha API key'
]
)
res
=
client
.
query
(
rest
)
return
next
(
res
.
results
)
.
text

A free - text query resolver by Wolfram|Alpha . Returns the first result if available .


def fix_HTTPMessage():
	"""
	Python 2 uses a deprecated method signature and doesn't provide the
	forward compatibility.
	Add it.
	"""
	if six.PY3:
		return

	http_client.HTTPMessage.get_content_type = http_client.HTTPMessage.gettype
	http_client.HTTPMessage.get_param = http_client.HTTPMessage.getparam

def fix_HTTPMessage ( ) : if six . PY3 : return http_client . HTTPMessage . get_content_type = http_client . HTTPMessage . gettype http_client . HTTPMessage . get_param = http_client . HTTPMessage . getparam

Python 2 uses a deprecated method signature and doesn t provide the forward compatibility . Add it .


def query(self, input, params=(), **kwargs):
        """
        Query Wolfram|Alpha using the v2.0 API

        Allows for arbitrary parameters to be passed in
        the query. For example, to pass assumptions:

            client.query(input='pi', assumption='*C.pi-_*NamedConstant-')

        To pass multiple assumptions, pass multiple items
        as params:

            params = (
                ('assumption', '*C.pi-_*NamedConstant-'),
                ('assumption', 'DateOrder_**Day.Month.Year--'),
            )
            client.query(input='pi', params=params)

        For more details on Assumptions, see
        https://products.wolframalpha.com/api/documentation.html#6
        """
        data = dict(
            input=input,
            appid=self.app_id,
        )
        data = itertools.chain(params, data.items(), kwargs.items())

        query = urllib.parse.urlencode(tuple(data))
        url = 'https://api.wolframalpha.com/v2/query?' + query
        resp = urllib.request.urlopen(url)
        assert resp.headers.get_content_type() == 'text/xml'
        assert resp.headers.get_param('charset') == 'utf-8'
        return Result(resp)

Query Wolfram|Alpha using the v2 . 0 API


def info(self):
        """
        The pods, assumptions, and warnings of this result.
        """
        return itertools.chain(self.pods, self.assumptions, self.warnings)

def info ( self ) : return itertools . chain ( self . pods , self . assumptions , self . warnings )

The pods assumptions and warnings of this result .


def results(self):
        """
        The pods that hold the response to a simple, discrete query.
        """
        return (
            pod
            for pod in self.pods
            if pod.primary
            or pod.title == 'Result'
        )

def results ( self ) : return ( pod for pod in self . pods if pod . primary or pod . title == 'Result' )

The pods that hold the response to a simple discrete query .


def encode(request, data):
        """ Add request content data to request body, set Content-type header.

        Should be overridden by subclasses if not using JSON encoding.

        Args:
            request (HTTPRequest): The request object.
            data (dict, None): Data to be encoded.

        Returns:
            HTTPRequest: The request object.
        """
        if data is None:
            return request

        request.add_header('Content-Type', 'application/json')
        request.data = json.dumps(data)

        return request

def encode ( request , data ) : if data is None : return request request . add_header ( 'Content-Type' , 'application/json' ) request . data = json . dumps ( data ) return request

Add request content data to request body set Content - type header .


def call_api(
            self,
            method,
            url,
            headers=None,
            params=None,
            data=None,
            files=None,
            timeout=None,
    ):
        """ Call API.

        This returns object containing data, with error details if applicable.

        Args:
            method (str): The HTTP method to use.
            url (str): Resource location relative to the base URL.
            headers (dict or None): Extra request headers to set.
            params (dict or None): Query-string parameters.
            data (dict or None): Request body contents for POST or PUT requests.
            files (dict or None: Files to be passed to the request.
            timeout (int): Maximum time before timing out.

        Returns:
            ResultParser or ErrorParser.
        """
        method = method.upper()
        headers = deepcopy(headers) or {}
        headers['Accept'] = self.accept_type
        params = deepcopy(params) or {}
        data = data or {}
        files = files or {}

        if self.username and self.api_key:
            params.update(self.get_credentials())

        url = urljoin(self.base_url, url)

        r = requests.request(
            method,
            url,
            headers=headers,
            params=params,
            files=files,
            data=data,
            timeout=timeout,
        )

        return r, r.status_code

def call_api ( self , method , url , headers = None , params = None , data = None , files = None , timeout = None , ) : method = method . upper ( ) headers = deepcopy ( headers ) or { } headers [ 'Accept' ] = self . accept_type params = deepcopy ( params ) or { } data = data or { } files = files or { } if self . username and self . api_key : params . update ( self . get_credentials ( ) ) url = urljoin ( self . base_url , url ) r = requests . request ( method , url , headers = headers , params = params , files = files , data = data , timeout = timeout , ) return r , r . status_code


def get(self, url, params=None, **kwargs):
        """ Call the API with a GET request.

        Args:
            url (str): Resource location relative to the base URL.
            params (dict or None): Query-string parameters.

        Returns:
            ResultParser or ErrorParser.
        """
        return self.call_api(
            "GET",
            url,
            params=params,
            **kwargs
        )

def get ( self , url , params = None , ** kwargs ) : return self . call_api ( "GET" , url , params = params , ** kwargs )


def delete(self, url, params=None, **kwargs):
        """ Call the API with a DELETE request.

        Args:
            url (str): Resource location relative to the base URL.
            params (dict or None): Query-string parameters.

        Returns:
            ResultParser or ErrorParser.
        """
        return self.call_api(
            "DELETE",
            url,
            params=params,
            **kwargs
        )

def delete ( self , url , params = None , ** kwargs ) : return self . call_api ( "DELETE" , url , params = params , ** kwargs )


def put(self, url, params=None, data=None, files=None, **kwargs):
        """ Call the API with a PUT request.

        Args:
            url (str): Resource location relative to the base URL.
            params (dict or None): Query-string parameters.
            data (dict or None): Request body contents.
            files (dict or None: Files to be passed to the request.

        Returns:
            An instance of ResultParser or ErrorParser.
        """
        return self.call_api(
            "PUT",
            url,
            params=params,
            data=data,
            files=files,
            **kwargs
        )

def put ( self , url , params = None , data = None , files = None , ** kwargs ) : return self . call_api ( "PUT" , url , params = params , data = data , files = files , ** kwargs )


def post(self, url, params=None, data=None, files=None, **kwargs):
        """ Call the API with a POST request.

        Args:
            url (str): Resource location relative to the base URL.
            params (dict or None): Query-string parameters.
            data (dict or None): Request body contents.
            files (dict or None: Files to be passed to the request.

        Returns:
            An instance of ResultParser or ErrorParser.
        """
        return self.call_api(
            "POST",
            url,
            params=params,
            data=data,
            files=files,
            **kwargs
        )

def post ( self , url , params = None , data = None , files = None , ** kwargs ) : return self . call_api ( "POST" , url , params = params , data = data , files = files , ** kwargs )


def _process_query(self, query, prepared=False):
        """ Process query recursively, if the text is too long,
        it is split and processed bit a bit.

        Args:
            query (sdict): Text to be processed.
            prepared (bool): True when the query is ready to be submitted via
            POST request.
        Returns:
            str: Body ready to be submitted to the API.
        """

        # Exit condition and POST
        if prepared is True:
            files = {'query': str(query)}

            logger.debug('About to submit the following query {}'.format(query))

            res, status = self.post(
                self.disambiguate_service,
                files=files,
                headers={'Accept': 'application/json'},
            )

            if status == 200:
                return self.decode(res), status
            else:
                logger.debug('Disambiguation failed.')
                return None, status

        text = query['text']

        sentence_coordinates = [
            {
                "offsetStart": 0,
                "offsetEnd": len(text)
            }
        ]

        total_nb_sentences = len(sentence_coordinates)  # Sentences from text.
        sentences_groups = []

        if len(text) > self.max_text_length:
            res, status_code = self.segment(text)

            if status_code == 200:
                sentence_coordinates = res['sentences']
                total_nb_sentences = len(sentence_coordinates)
            else:
                logger.error('Error during the segmentation of the text.')

            logger.debug(
                'Text too long, split in {} sentences; building groups of {} '
                'sentences.'.format(
                    total_nb_sentences, self.sentences_per_group
                )
            )
            sentences_groups = self._group_sentences(
                total_nb_sentences,
                self.sentences_per_group
            )
        else:
            query['sentence'] = "true"

        if total_nb_sentences > 1:
            query['sentences'] = sentence_coordinates

        if len(sentences_groups) > 0:
            for group in sentences_groups:
                query['processSentence'] = group

                res, status_code = self._process_query(query, prepared=True)

                if status_code == 200:
                    if 'entities' in res:
                        query['entities'] = res[u'entities']
                    query['language'] = res[u'language']
                else:
                    logger.error(
                        "Error when processing the query {}".format(query)
                    )
                    return None, status_code

        else:
            res, status_code = self._process_query(query, prepared=True)

            if status_code == 200:
                query['language'] = res[u'language']
                if 'entities' in res:
                    query['entities'] = res[u'entities']
            else:
                logger.error("Error when processing the query {}".format(query))
                return None, status_code

        return query, status_code

Process query recursively if the text is too long it is split and processed bit a bit .


def _group_sentences(total_nb_sentences, group_length):
        """ Split sentences in groups, given a specific group length.

        Args:
            total_nb_sentences (int): Total available sentences.
            group_length (int): Limit of length for each group.

        Returns:
            list: Contains groups (lists) of sentences.
        """
        sentences_groups = []
        current_sentence_group = []

        for i in range(0, total_nb_sentences):
            if i % group_length == 0:
                if len(current_sentence_group) > 0:
                    sentences_groups.append(current_sentence_group)
                current_sentence_group = [i]
            else:
                current_sentence_group.append(i)

        if len(current_sentence_group) > 0:
            sentences_groups.append(current_sentence_group)

        return sentences_groups

def _group_sentences ( total_nb_sentences , group_length ) : sentences_groups = [ ] current_sentence_group = [ ] for i in range ( 0 , total_nb_sentences ) : if i % group_length == 0 : if len ( current_sentence_group ) > 0 : sentences_groups . append ( current_sentence_group ) current_sentence_group = [ i ] else : current_sentence_group . append ( i ) if len ( current_sentence_group ) > 0 : sentences_groups . append ( current_sentence_group ) return sentences_groups

Split sentences in groups given a specific group length .


def disambiguate_pdf(self, file, language=None, entities=None):
        """ Call the disambiguation service in order to process a pdf file .

        Args:
            pdf (file): PDF file to be disambiguated.
            language (str): language of text (if known)

        Returns:
            dict, int: API response and API status.
        """

        body = {
            "customisation": "generic"
        }

        if language:
            body['language'] = {"lang": language}

        if entities:
            body['entities'] = entities

        files = {
            'query': str(body),
            'file': (
                file,
                open(file, 'rb'),
                'application/pdf',
                {'Expires': '0'}
            )
        }

        res, status = self.post(
            self.disambiguate_service,
            files=files,
            headers={'Accept': 'application/json'},
        )

        if status != 200:
            logger.debug('Disambiguation failed with error ' + str(status))

        return self.decode(res), status

def
disambiguate_pdf
(
self
,
file
,
language
=
,
entities
=
)
:
body
=
{
"customisation"
:
"generic"
}
if
language
:
body
[
'language'
]
=
{
"lang"
:
language
}
if
entities
:
body
[
'entities'
]
=
entities
files
=
{
'query'
:
str
(
body
)
,
'file'
:
(
file
,
open
(
file
,
'rb'
)
,
'application/pdf'
,
{
'Expires'
:
'0'
}
)
}
res
,
status
=
self
.
post
(
self
.
disambiguate_service
,
files
=
files
,
headers
=
{
'Accept'
:
'application/json'
}
,
)
if
status
!=
200
:
logger
.
debug
(
'Disambiguation failed with error '
+
str
(
status
)
)
return
self
.
decode
(
res
)
,
status


def disambiguate_query(self, query, language=None, entities=None):
        """ Call the disambiguation service in order to disambiguate a search query.

        Args:
            text (str): Query to be disambiguated.
            language (str): language of text (if known)
            entities (list): list of entities or mentions to be supplied by
                the user.

        Returns:
            dict, int: API response and API status.
        """

        body = {
            "shortText": query,
            "entities": [],
            "onlyNER": "false",
            "customisation": "generic"
        }

        if language:
            body['language'] = {"lang": language}

        if entities:
            body['entities'] = entities

        files = {'query': str(body)}

        logger.debug('About to submit the following query {}'.format(body))

        res, status = self.post(
            self.disambiguate_service,
            files=files,
            headers={'Accept': 'application/json'},
        )

        if status == 200:
            return self.decode(res), status
        else:
            logger.debug('Disambiguation failed.')
            return None, status

Call the disambiguation service in order to disambiguate a search query .


def segment(self, text):
        """ Call the segmenter in order to split text in sentences.

        Args:
            text (str): Text to be segmented.

        Returns:
            dict, int: A dict containing a list of dicts with the offsets of
                each sentence; an integer representing the response code.
        """

        files = {'text': text}
        res, status_code = self.post(self.segmentation_service, files=files)

        if status_code != 200:
            logger.debug('Segmentation failed.')

        return self.decode(res), status_code

def
segment
(
self
,
text
)
:
files
=
{
'text'
:
text
}
res
,
status_code
=
self
.
post
(
self
.
segmentation_service
,
files
=
files
)
if
status_code
!=
200
:
logger
.
debug
(
'Segmentation failed.'
)
return
self
.
decode
(
res
)
,
status_code

Call the segmenter in order to split text in sentences .


def get_language(self, text):
        """ Recognise the language of the text in input

        Args:
              id (str): The text whose the language needs to be recognised

        Returns:
            dict, int: A dict containing the recognised language and the
                confidence score.
        """
        files = {'text': text}
        res, status_code = self.post(self.language_service, files=files)

        if status_code != 200:
            logger.debug('Language recognition failed.')

        return self.decode(res), status_code

def
get_language
(
self
,
text
)
:
files
=
{
'text'
:
text
}
res
,
status_code
=
self
.
post
(
self
.
language_service
,
files
=
files
)
if
status_code
!=
200
:
logger
.
debug
(
'Language recognition failed.'
)
return
self
.
decode
(
res
)
,
status_code


def get_concept(self, conceptId, lang='en'):
        """ Fetch the concept from the Knowledge base

        Args:
              id (str): The concept id to be fetched, it can be Wikipedia
                page id or Wikiedata id.

        Returns:
            dict, int: A dict containing the concept information; an integer
                representing the response code.
        """
        url = urljoin(self.concept_service + '/', conceptId)

        res, status_code = self.get(url, params={'lang': lang})

        if status_code != 200:
            logger.debug('Fetch concept failed.')

        return self.decode(res), status_code

def
get_concept
(
self
,
conceptId
,
lang
=
'en'
)
:
url
=
urljoin
(
self
.
concept_service
+
'/'
,
conceptId
)
res
,
status_code
=
self
.
get
(
url
,
params
=
{
'lang'
:
lang
}
)
if
status_code
!=
200
:
logger
.
debug
(
'Fetch concept failed.'
)
return
self
.
decode
(
res
)
,
status_code


def fit(self, features, classes):
        """Constructs the MDR ensemble from the provided training data

        Parameters
        ----------
        features: array-like {n_samples, n_features}
            Feature matrix
        classes: array-like {n_samples}
            List of class labels for prediction

        Returns
        -------
        None

        """
        self.ensemble.fit(features, classes)

        # Construct the feature map from the ensemble predictions
        unique_rows = list(set([tuple(row) for row in features]))
        for row in unique_rows:
            self.feature_map[row] = self.ensemble.predict([row])[0]

def fit ( self , features , classes ) : self . ensemble . fit ( features , classes ) unique_rows = list ( set ( [ tuple ( row ) for row in features ] ) ) for row in unique_rows : self . feature_map [ row ] = self . ensemble . predict ( [ row ] ) [ 0 ]


def score(self, features, classes, scoring_function=None, **scoring_function_kwargs):
        """Estimates the accuracy of the predictions from the MDR ensemble

        Parameters
        ----------
        features: array-like {n_samples, n_features}
            Feature matrix to predict from
        classes: array-like {n_samples}
            List of true class labels

        Returns
        -------
        accuracy_score: float
            The estimated accuracy based on the constructed feature

        """
        new_feature = self.ensemble.predict(features)

        if scoring_function is None:
            return accuracy_score(classes, new_feature)
        else:
            return scoring_function(classes, new_feature, **scoring_function_kwargs)

def score ( self , features , classes , scoring_function = None , ** scoring_function_kwargs ) : new_feature = self . ensemble . predict ( features ) if scoring_function is None : return accuracy_score ( classes , new_feature ) else : return scoring_function ( classes , new_feature , ** scoring_function_kwargs )


def fit(self, features, class_labels):
        """Constructs the MDR feature map from the provided training data.

        Parameters
        ----------
        features: array-like {n_samples, n_features}
            Feature matrix
        class_labels: array-like {n_samples}
            List of true class labels

        Returns
        -------
        self: A copy of the fitted model

        """
        unique_labels = sorted(np.unique(class_labels))
        if len(unique_labels) != 2:
            raise ValueError('MDR only supports binary endpoints.')

        # Count the distribution of classes that fall into each MDR grid cell
        self.class_count_matrix = defaultdict(lambda: defaultdict(int))
        for row_i in range(features.shape[0]):
            feature_instance = tuple(features[row_i])
            self.class_count_matrix[feature_instance][class_labels[row_i]] += 1
        self.class_count_matrix = dict(self.class_count_matrix)

        # Only applies to binary classification
        overall_class_fraction = float(sum(class_labels == unique_labels[0])) / class_labels.size

        # If one class is more abundant in a MDR grid cell than it is overall, then assign the cell to that class
        self.feature_map = {}
        for feature_instance in self.class_count_matrix:
            counts = self.class_count_matrix[feature_instance]
            fraction = float(counts[unique_labels[0]]) / np.sum(list(counts.values()))
            if fraction > overall_class_fraction:
                self.feature_map[feature_instance] = unique_labels[0]
            elif fraction == overall_class_fraction:
                self.feature_map[feature_instance] = self.tie_break
            else:
                self.feature_map[feature_instance] = unique_labels[1]

        return self

def
fit
(
self
,
features
,
class_labels
)
:
unique_labels
=
sorted
(
np
.
unique
(
class_labels
)
)
if
len
(
unique_labels
)
!=
2
:
raise
ValueError
(
'MDR only supports binary endpoints.'
)
self
.
class_count_matrix
=
defaultdict
(
lambda
:
defaultdict
(
int
)
)
for
row_i
in
range
(
features
.
shape
[
0
]
)
:
feature_instance
=
tuple
(
features
[
row_i
]
)
self
.
class_count_matrix
[
feature_instance
]
[
class_labels
[
row_i
]
]
+=
1
self
.
class_count_matrix
=
dict
(
self
.
class_count_matrix
)
overall_class_fraction
=
float
(
sum
(
class_labels
==
unique_labels
[
0
]
)
)
/
class_labels
.
size
self
.
feature_map
=
{
}
for
feature_instance
in
self
.
class_count_matrix
:
counts
=
self
.
class_count_matrix
[
feature_instance
]
fraction
=
float
(
counts
[
unique_labels
[
0
]
]
)
/
np
.
sum
(
list
(
counts
.
values
(
)
)
)
if
fraction
>
overall_class_fraction
:
self
.
feature_map
[
feature_instance
]
=
unique_labels
[
0
]
elif
fraction
==
overall_class_fraction
:
self
.
feature_map
[
feature_instance
]
=
self
.
tie_break
else
:
self
.
feature_map
[
feature_instance
]
=
unique_labels
[
1
]
return
self

Constructs the MDR feature map from the provided training data .


def fit_predict(self, features, class_labels):
        """Convenience function that fits the provided data then constructs predictions from the provided features.

        Parameters
        ----------
        features: array-like {n_samples, n_features}
            Feature matrix
        class_labels: array-like {n_samples}
            List of true class labels

        Returns
        ----------
        array-like: {n_samples}
            Constructed features from the provided feature matrix

        """
        self.fit(features, class_labels)
        return self.predict(features)

def fit_predict ( self , features , class_labels ) : self . fit ( features , class_labels ) return self . predict ( features )

Convenience function that fits the provided data then constructs predictions from the provided features .


def score(self, features, class_labels, scoring_function=None, **scoring_function_kwargs):
        """Estimates the accuracy of the predictions from the constructed feature.

        Parameters
        ----------
        features: array-like {n_samples, n_features}
            Feature matrix to predict from
        class_labels: array-like {n_samples}
            List of true class labels

        Returns
        -------
        accuracy_score: float
            The estimated accuracy based on the constructed feature

        """
        if self.feature_map is None:
            raise ValueError('The MDR model must be fit before score can be called.')

        new_feature = self.predict(features)

        if scoring_function is None:
            return accuracy_score(class_labels, new_feature)
        else:
            return scoring_function(class_labels, new_feature, **scoring_function_kwargs)

Estimates the accuracy of the predictions from the constructed feature .


def fit(self, features, targets):
        """Constructs the Continuous MDR feature map from the provided training data.

        Parameters
        ----------
        features: array-like {n_samples, n_features}
            Feature matrix
        targets: array-like {n_samples}
            List of target values for prediction

        Returns
        -------
        self: A copy of the fitted model

        """
        self.feature_map = defaultdict(lambda: self.default_label)
        self.overall_mean_trait_value = np.mean(targets)
        self.mdr_matrix_values = defaultdict(list)

        for row_i in range(features.shape[0]):
            feature_instance = tuple(features[row_i])
            self.mdr_matrix_values[feature_instance].append(targets[row_i])

        for feature_instance in self.mdr_matrix_values:
            grid_mean_trait_value = np.mean(self.mdr_matrix_values[feature_instance])
            if grid_mean_trait_value > self.overall_mean_trait_value:
                self.feature_map[feature_instance] = 1
            elif grid_mean_trait_value == self.overall_mean_trait_value:
                self.feature_map[feature_instance] = self.tie_break
            else:
                self.feature_map[feature_instance] = 0

        # Convert defaultdict to dict so CMDR objects can be easily pickled
        self.feature_map = dict(self.feature_map)
        self.mdr_matrix_values = dict(self.mdr_matrix_values)

        return self

def fit ( self , features , targets ) : self . feature_map = defaultdict ( lambda : self . default_label ) self . overall_mean_trait_value = np . mean ( targets ) self . mdr_matrix_values = defaultdict ( list ) for row_i in range ( features . shape [ 0 ] ) : feature_instance = tuple ( features [ row_i ] ) self . mdr_matrix_values [ feature_instance ] . append ( targets [ row_i ] ) for feature_instance in self . mdr_matrix_values : grid_mean_trait_value = np . mean ( self . mdr_matrix_values [ feature_instance ] ) if grid_mean_trait_value > self . overall_mean_trait_value : self . feature_map [ feature_instance ] = 1 elif grid_mean_trait_value == self . overall_mean_trait_value : self . feature_map [ feature_instance ] = self . tie_break else : self . feature_map [ feature_instance ] = 0 self . feature_map = dict ( self . feature_map ) self . mdr_matrix_values = dict ( self . mdr_matrix_values ) return self

Constructs the Continuous MDR feature map from the provided training data .


def transform(self, features):
        """Uses the Continuous MDR feature map to construct a new feature from the provided features.

        Parameters
        ----------
        features: array-like {n_samples, n_features}
            Feature matrix to transform

        Returns
        ----------
        array-like: {n_samples}
            Constructed feature from the provided feature matrix
            The constructed feature will be a binary variable, taking the values 0 and 1

        """
        new_feature = np.zeros(features.shape[0], dtype=np.int)

        for row_i in range(features.shape[0]):
            feature_instance = tuple(features[row_i])
            if feature_instance in self.feature_map:
                new_feature[row_i] = self.feature_map[feature_instance]
            else:
                new_feature[row_i] = self.default_label

        return new_feature.reshape(features.shape[0], 1)

def transform ( self , features ) : new_feature = np . zeros ( features . shape [ 0 ] , dtype = np . int ) for row_i in range ( features . shape [ 0 ] ) : feature_instance = tuple ( features [ row_i ] ) if feature_instance in self . feature_map : new_feature [ row_i ] = self . feature_map [ feature_instance ] else : new_feature [ row_i ] = self . default_label return new_feature . reshape ( features . shape [ 0 ] , 1 )

Uses the Continuous MDR feature map to construct a new feature from the provided features .


def score(self, features, targets):
        """Estimates the quality of the ContinuousMDR model using a t-statistic.

        Parameters
        ----------
        features: array-like {n_samples, n_features}
            Feature matrix to predict from
        targets: array-like {n_samples}
            List of true target values

        Returns
        -------
        quality_score: float
            The estimated quality of the Continuous MDR model

        """
        if self.feature_map is None:
            raise ValueError('The Continuous MDR model must be fit before score() can be called.')

        group_0_trait_values = []
        group_1_trait_values = []

        for feature_instance in self.feature_map:
            if self.feature_map[feature_instance] == 0:
                group_0_trait_values.extend(self.mdr_matrix_values[feature_instance])
            else:
                group_1_trait_values.extend(self.mdr_matrix_values[feature_instance])

        return abs(ttest_ind(group_0_trait_values, group_1_trait_values).statistic)

Estimates the quality of the ContinuousMDR model using a t - statistic .


def _mdr_predict(X, Y, labels):
    """Fits a MDR model to variables X and Y with the given labels, then returns the resulting predictions

    This is a convenience method that should only be used internally.

    Parameters
    ----------
    X: array-like (# samples)
        An array of values corresponding to one feature in the MDR model
    Y: array-like (# samples)
        An array of values corresponding to one feature in the MDR model
    labels: array-like (# samples)
        The class labels corresponding to features X and Y

    Returns
    ----------
    predictions: array-like (# samples)
        The predictions from the fitted MDR model

    """
    return MDR().fit_predict(np.column_stack((X, Y)), labels)

def _mdr_predict ( X , Y , labels ) : return MDR ( ) . fit_predict ( np . column_stack ( ( X , Y ) ) , labels )

Fits a MDR model to variables X and Y with the given labels then returns the resulting predictions


def n_way_models(mdr_instance, X, y, n=[2], feature_names=None):
    """Fits a MDR model to all n-way combinations of the features in X.

    Note that this function performs an exhaustive search through all feature combinations and can be computationally expensive.

    Parameters
    ----------
    mdr_instance: object
        An instance of the MDR type to use.
    X: array-like (# rows, # features)
        NumPy matrix containing the features
    y: array-like (# rows, 1)
        NumPy matrix containing the target values
    n: list (default: [2])
        The maximum size(s) of the MDR model to generate.
        e.g., if n == [3], all 3-way models will be generated.
    feature_names: list (default: None)
        The corresponding names of the features in X.
        If None, then the features will be named according to their order.

    Returns
    ----------
    (fitted_model, fitted_model_score, fitted_model_features): tuple of (list, list, list)
        fitted_model contains the MDR model fitted to the data.
        fitted_model_score contains the training scores corresponding to the fitted MDR model.
        fitted_model_features contains a list of the names of the features that were used in the corresponding model.

    """
    if feature_names is None:
        feature_names = list(range(X.shape[1]))

    for cur_n in n:
        for features in itertools.combinations(range(X.shape[1]), cur_n):
            mdr_model = copy.deepcopy(mdr_instance)
            mdr_model.fit(X[:, features], y)
            mdr_model_score = mdr_model.score(X[:, features], y)
            model_features = [feature_names[feature] for feature in features]
            yield mdr_model, mdr_model_score, model_features

def n_way_models ( mdr_instance , X , y , n = [ 2 ] , feature_names = None ) : if feature_names is None : feature_names = list ( range ( X . shape [ 1 ] ) ) for cur_n in n : for features in itertools . combinations ( range ( X . shape [ 1 ] ) , cur_n ) : mdr_model = copy . deepcopy ( mdr_instance ) mdr_model . fit ( X [ : , features ] , y ) mdr_model_score = mdr_model . score ( X [ : , features ] , y ) model_features = [ feature_names [ feature ] for feature in features ] yield mdr_model , mdr_model_score , model_features

Fits a MDR model to all n - way combinations of the features in X .


def plot_mdr_grid(mdr_instance):
    """Visualizes the MDR grid of a given fitted MDR instance. Only works for 2-way MDR models.

    This function is currently incomplete.

    Parameters
    ----------
    mdr_instance: object
        A fitted instance of the MDR type to visualize.

    Returns
    ----------
    fig: matplotlib.figure
        Figure object for the visualized MDR grid.

    """
    var1_levels = list(set([variables[0] for variables in mdr_instance.feature_map]))
    var2_levels = list(set([variables[1] for variables in mdr_instance.feature_map]))
    max_count = np.array(list(mdr_instance.class_count_matrix.values())).flatten().max()

    """
    TODO:
        - Add common axis labels
        - Make sure this scales for smaller and larger record sizes
        - Extend to 3-way+ models, e.g., http://4.bp.blogspot.com/-vgKCjEkWFUc/UPwPuHo6XvI/AAAAAAAAAE0/fORHqDcoikE/s1600/model.jpg
    """

    fig, splots = plt.subplots(ncols=len(var1_levels), nrows=len(var2_levels), sharey=True, sharex=True)
    fig.set_figwidth(6)
    fig.set_figheight(6)

    for (var1, var2) in itertools.product(var1_levels, var2_levels):
        class_counts = mdr_instance.class_count_matrix[(var1, var2)]
        splot = splots[var2_levels.index(var2)][var1_levels.index(var1)]
        splot.set_yticks([])
        splot.set_xticks([])
        splot.set_ylim(0, max_count * 1.5)
        splot.set_xlim(-0.5, 1.5)

        if var2_levels.index(var2) == 0:
            splot.set_title('X1 = {}'.format(var1), fontsize=12)
        if var1_levels.index(var1) == 0:
            splot.set_ylabel('X2 = {}'.format(var2), fontsize=12)

        bars = splot.bar(left=range(class_counts.shape[0]),
                         height=class_counts, width=0.5,
                         color='black', align='center')

        bgcolor = 'lightgrey' if mdr_instance.feature_map[(var1, var2)] == 0 else 'darkgrey'
        splot.set_axis_bgcolor(bgcolor)
        for index, bar in enumerate(bars):
            splot.text(index, class_counts[index] + (max_count * 0.1), class_counts[index], ha='center')

    fig.tight_layout()
    return fig

def
plot_mdr_grid
(
mdr_instance
)
:
var1_levels
=
list
(
set
(
[
variables
[
0
]
for
variables
in
mdr_instance
.
feature_map
]
)
)
var2_levels
=
list
(
set
(
[
variables
[
1
]
for
variables
in
mdr_instance
.
feature_map
]
)
)
max_count
=
np
.
array
(
list
(
mdr_instance
.
class_count_matrix
.
values
(
)
)
)
.
flatten
(
)
.
max
(
)
fig
,
splots
=
plt
.
subplots
(
ncols
=
len
(
var1_levels
)
,
nrows
=
len
(
var2_levels
)
,
sharey
=
True
,
sharex
=
True
)
fig
.
set_figwidth
(
6
)
fig
.
set_figheight
(
6
)
for
(
var1
,
var2
)
in
itertools
.
product
(
var1_levels
,
var2_levels
)
:
class_counts
=
mdr_instance
.
class_count_matrix
[
(
var1
,
var2
)
]
splot
=
splots
[
var2_levels
.
index
(
var2
)
]
[
var1_levels
.
index
(
var1
)
]
splot
.
set_yticks
(
[
]
)
splot
.
set_xticks
(
[
]
)
splot
.
set_ylim
(
0
,
max_count
*
1.5
)
splot
.
set_xlim
(
0.5
,
1.5
)
if
var2_levels
.
index
(
var2
)
==
0
:
splot
.
set_title
(
'X1 = {}'
.
format
(
var1
)
,
fontsize
=
12
)
if
var1_levels
.
index
(
var1
)
==
0
:
splot
.
set_ylabel
(
'X2 = {}'
.
format
(
var2
)
,
fontsize
=
12
)
bars
=
splot
.
bar
(
left
=
range
(
class_counts
.
shape
[
0
]
)
,
height
=
class_counts
,
width
=
0.5
,
color
=
'black'
,
align
=
'center'
)
bgcolor
=
'lightgrey'
if
mdr_instance
.
feature_map
[
(
var1
,
var2
)
]
==
0
else
'darkgrey'
splot
.
set_axis_bgcolor
(
bgcolor
)
for
index
,
bar
in
enumerate
(
bars
)
:
splot
.
text
(
index
,
class_counts
[
index
]
+
(
max_count
*
0.1
)
,
class_counts
[
index
]
,
ha
=
'center'
)
fig
.
tight_layout
(
)
return
fig

Visualizes the MDR grid of a given fitted MDR instance . Only works for 2 - way MDR models . This function is currently incomplete .


def get_config(app, prefix='hive_'):
    """Conveniently get the security configuration for the specified
    application without the annoying 'SECURITY_' prefix.

    :param app: The application to inspect
    """
    items = app.config.items()
    prefix = prefix.upper()

    def strip_prefix(tup):
        return (tup[0].replace(prefix, ''), tup[1])

    return dict([strip_prefix(i) for i in items if i[0].startswith(prefix)])

def get_config ( app , prefix = 'hive_' ) : items = app . config . items ( ) prefix = prefix . upper ( ) def strip_prefix ( tup ) : return ( tup [ 0 ] . replace ( prefix , '' ) , tup [ 1 ] ) return dict ( [ strip_prefix ( i ) for i in items if i [ 0 ] . startswith ( prefix ) ] )

Conveniently get the security configuration for the specified application without the annoying SECURITY_ prefix .


def config_value(key, app=None, default=None, prefix='hive_'):
    """Get a Flask-Security configuration value.

    :param key: The configuration key without the prefix `SECURITY_`
    :param app: An optional specific application to inspect. Defaults to
                Flask's `current_app`
    :param default: An optional default value if the value is not set
    """
    app = app or current_app
    return get_config(app, prefix=prefix).get(key.upper(), default)

def config_value ( key , app = None , default = None , prefix = 'hive_' ) : app = app or current_app return get_config ( app , prefix = prefix ) . get ( key . upper ( ) , default )

Get a Flask - Security configuration value .


def vector(members: Iterable[T], meta: Optional[IPersistentMap] = None) -> Vector[T]:
    """Creates a new vector."""
    return Vector(pvector(members), meta=meta)

def vector ( members : Iterable [ T ] , meta : Optional [ IPersistentMap ] = None ) -> Vector [ T ] : return Vector ( pvector ( members ) , meta = meta )


def v(*members: T, meta: Optional[IPersistentMap] = None) -> Vector[T]:
    """Creates a new vector from members."""
    return Vector(pvector(members), meta=meta)

def v ( * members : T , meta : Optional [ IPersistentMap ] = None ) -> Vector [ T ] : return Vector ( pvector ( members ) , meta = meta )


def eval_file(filename: str, ctx: compiler.CompilerContext, module: types.ModuleType):
    """Evaluate a file with the given name into a Python module AST node."""
    last = None
    for form in reader.read_file(filename, resolver=runtime.resolve_alias):
        last = compiler.compile_and_exec_form(form, ctx, module)
    return last

def eval_file ( filename : str , ctx : compiler . CompilerContext , module : types . ModuleType ) : last = None for form in reader . read_file ( filename , resolver = runtime . resolve_alias ) : last = compiler . compile_and_exec_form ( form , ctx , module ) return last

Evaluate a file with the given name into a Python module AST node .


def eval_stream(stream, ctx: compiler.CompilerContext, module: types.ModuleType):
    """Evaluate the forms in stdin into a Python module AST node."""
    last = None
    for form in reader.read(stream, resolver=runtime.resolve_alias):
        last = compiler.compile_and_exec_form(form, ctx, module)
    return last

def eval_stream ( stream , ctx : compiler . CompilerContext , module : types . ModuleType ) : last = None for form in reader . read ( stream , resolver = runtime . resolve_alias ) : last = compiler . compile_and_exec_form ( form , ctx , module ) return last

Evaluate the forms in stdin into a Python module AST node .


def eval_str(s: str, ctx: compiler.CompilerContext, module: types.ModuleType, eof: Any):
    """Evaluate the forms in a string into a Python module AST node."""
    last = eof
    for form in reader.read_str(s, resolver=runtime.resolve_alias, eof=eof):
        last = compiler.compile_and_exec_form(form, ctx, module)
    return last

def eval_str ( s : str , ctx : compiler . CompilerContext , module : types . ModuleType , eof : Any ) : last = eof for form in reader . read_str ( s , resolver = runtime . resolve_alias , eof = eof ) : last = compiler . compile_and_exec_form ( form , ctx , module ) return last

Evaluate the forms in a string into a Python module AST node .


def bootstrap_repl(which_ns: str) -> types.ModuleType:
    """Bootstrap the REPL with a few useful vars and returned the
    bootstrapped module so it's functions can be used by the REPL
    command."""
    repl_ns = runtime.Namespace.get_or_create(sym.symbol("basilisp.repl"))
    ns = runtime.Namespace.get_or_create(sym.symbol(which_ns))
    repl_module = importlib.import_module("basilisp.repl")
    ns.add_alias(sym.symbol("basilisp.repl"), repl_ns)
    ns.refer_all(repl_ns)
    return repl_module

def bootstrap_repl ( which_ns : str ) -> types . ModuleType : repl_ns = runtime . Namespace . get_or_create ( sym . symbol ( "basilisp.repl" ) ) ns = runtime . Namespace . get_or_create ( sym . symbol ( which_ns ) ) repl_module = importlib . import_module ( "basilisp.repl" ) ns . add_alias ( sym . symbol ( "basilisp.repl" ) , repl_ns ) ns . refer_all ( repl_ns ) return repl_module

Bootstrap the REPL with a few useful vars and returned the bootstrapped module so it s functions can be used by the REPL command .


def run(  # pylint: disable=too-many-arguments
    file_or_code,
    code,
    in_ns,
    use_var_indirection,
    warn_on_shadowed_name,
    warn_on_shadowed_var,
    warn_on_var_indirection,
):
    """Run a Basilisp script or a line of code, if it is provided."""
    basilisp.init()
    ctx = compiler.CompilerContext(
        filename=CLI_INPUT_FILE_PATH
        if code
        else (
            STDIN_INPUT_FILE_PATH if file_or_code == STDIN_FILE_NAME else file_or_code
        ),
        opts={
            compiler.WARN_ON_SHADOWED_NAME: warn_on_shadowed_name,
            compiler.WARN_ON_SHADOWED_VAR: warn_on_shadowed_var,
            compiler.USE_VAR_INDIRECTION: use_var_indirection,
            compiler.WARN_ON_VAR_INDIRECTION: warn_on_var_indirection,
        },
    )
    eof = object()

    with runtime.ns_bindings(in_ns) as ns:
        if code:
            print(runtime.lrepr(eval_str(file_or_code, ctx, ns.module, eof)))
        elif file_or_code == STDIN_FILE_NAME:
            print(
                runtime.lrepr(
                    eval_stream(click.get_text_stream("stdin"), ctx, ns.module)
                )
            )
        else:
            print(runtime.lrepr(eval_file(file_or_code, ctx, ns.module)))

def run ( file_or_code , code , in_ns , use_var_indirection , warn_on_shadowed_name , warn_on_shadowed_var , warn_on_var_indirection , ) : basilisp . init ( ) ctx = compiler . CompilerContext ( filename = CLI_INPUT_FILE_PATH if code else ( STDIN_INPUT_FILE_PATH if file_or_code == STDIN_FILE_NAME else file_or_code ) , opts = { compiler . WARN_ON_SHADOWED_NAME : warn_on_shadowed_name , compiler . WARN_ON_SHADOWED_VAR : warn_on_shadowed_var , compiler . USE_VAR_INDIRECTION : use_var_indirection , compiler . WARN_ON_VAR_INDIRECTION : warn_on_var_indirection , } , ) eof = object ( ) with runtime . ns_bindings ( in_ns ) as ns : if code : print ( runtime . lrepr ( eval_str ( file_or_code , ctx , ns . module , eof ) ) ) elif file_or_code == STDIN_FILE_NAME : print ( runtime . lrepr ( eval_stream ( click . get_text_stream ( "stdin" ) , ctx , ns . module ) ) ) else : print ( runtime . lrepr ( eval_file ( file_or_code , ctx , ns . module ) ) )

Run a Basilisp script or a line of code if it is provided .


def multifn(dispatch: DispatchFunction, default=None) -> MultiFunction[T]:
    """Decorator function which can be used to make Python multi functions."""
    name = sym.symbol(dispatch.__qualname__, ns=dispatch.__module__)
    return MultiFunction(name, dispatch, default)

def multifn ( dispatch : DispatchFunction , default = None ) -> MultiFunction [ T ] : name = sym . symbol ( dispatch . __qualname__ , ns = dispatch . __module__ ) return MultiFunction ( name , dispatch , default )

Decorator function which can be used to make Python multi functions .


def __add_method(m: lmap.Map, key: T, method: Method) -> lmap.Map:
        """Swap the methods atom to include method with key."""
        return m.assoc(key, method)

def __add_method ( m : lmap . Map , key : T , method : Method ) -> lmap . Map : return m . assoc ( key , method )

Swap the methods atom to include method with key .


def add_method(self, key: T, method: Method) -> None:
        """Add a new method to this function which will respond for
        key returned from the dispatch function."""
        self._methods.swap(MultiFunction.__add_method, key, method)

def add_method ( self , key : T , method : Method ) -> None : self . _methods . swap ( MultiFunction . __add_method , key , method )

Add a new method to this function which will respond for key returned from the dispatch function .


def get_method(self, key: T) -> Optional[Method]:
        """Return the method which would handle this dispatch key or
        None if no method defined for this key and no default."""
        method_cache = self.methods
        # The 'type: ignore' comment below silences a spurious MyPy error
        # about having a return statement in a method which does not return.
        return Maybe(method_cache.entry(key, None)).or_else(
            lambda: method_cache.entry(self._default, None)  # type: ignore
        )

def get_method ( self , key : T ) -> Optional [ Method ] : method_cache = self . methods return Maybe ( method_cache . entry ( key , None ) ) . or_else ( lambda : method_cache . entry ( self . _default , None ) )

Return the method which would handle this dispatch key or None if no method defined for this key and no default .


def __remove_method(m: lmap.Map, key: T) -> lmap.Map:
        """Swap the methods atom to remove method with key."""
        return m.dissoc(key)

def __remove_method ( m : lmap . Map , key : T ) -> lmap . Map : return m . dissoc ( key )

Swap the methods atom to remove method with key .


def remove_method(self, key: T) -> Optional[Method]:
        """Remove the method defined for this key and return it."""
        method = self.methods.entry(key, None)
        if method:
            self._methods.swap(MultiFunction.__remove_method, key)
        return method

def remove_method ( self , key : T ) -> Optional [ Method ] : method = self . methods . entry ( key , None ) if method : self . _methods . swap ( MultiFunction . __remove_method , key ) return method

Remove the method defined for this key and return it .


def _is_macro(v: Var) -> bool:
    """Return True if the Var holds a macro function."""
    return (
        Maybe(v.meta)
        .map(lambda m: m.entry(SYM_MACRO_META_KEY, None))  # type: ignore
        .or_else_get(False)
    )

def _is_macro ( v : Var ) -> bool : return ( Maybe ( v . meta ) . map ( lambda m : m . entry ( SYM_MACRO_META_KEY , None ) ) . or_else_get ( False ) )

Return True if the Var holds a macro function .


def _loc(form: Union[LispForm, ISeq]) -> Optional[Tuple[int, int]]:
    """Fetch the location of the form in the original filename from the
    input form, if it has metadata."""
    try:
        meta = form.meta  # type: ignore
        line = meta.get(reader.READER_LINE_KW)  # type: ignore
        col = meta.get(reader.READER_COL_KW)  # type: ignore
    except AttributeError:
        return None
    else:
        assert isinstance(line, int) and isinstance(col, int)
        return line, col

def _loc ( form : Union [ LispForm , ISeq ] ) -> Optional [ Tuple [ int , int ] ] : try : meta = form . meta line = meta . get ( reader . READER_LINE_KW ) col = meta . get ( reader . READER_COL_KW ) except AttributeError : return None else : assert isinstance ( line , int ) and isinstance ( col , int ) return line , col

Fetch the location of the form in the original filename from the input form if it has metadata .


def _with_loc(f: ParseFunction):
    """Attach any available location information from the input form to
    the node environment returned from the parsing function."""

    @wraps(f)
    def _parse_form(ctx: ParserContext, form: Union[LispForm, ISeq]) -> Node:
        form_loc = _loc(form)
        if form_loc is None:
            return f(ctx, form)
        else:
            return f(ctx, form).fix_missing_locations(form_loc)

    return _parse_form

def _with_loc ( f : ParseFunction ) : @ wraps ( f ) def _parse_form ( ctx : ParserContext , form : Union [ LispForm , ISeq ] ) -> Node : form_loc = _loc ( form ) if form_loc is None : return f ( ctx , form ) else : return f ( ctx , form ) . fix_missing_locations ( form_loc ) return _parse_form

Attach any available location information from the input form to the node environment returned from the parsing function .


def _assert_no_recur(node: Node) -> None:
    """Assert that `recur` forms do not appear in any position of this or
    child AST nodes."""
    if node.op == NodeOp.RECUR:
        raise ParserException(
            "recur must appear in tail position", form=node.form, lisp_ast=node
        )
    elif node.op in {NodeOp.FN, NodeOp.LOOP}:
        pass
    else:
        node.visit(_assert_no_recur)

def
_assert_no_recur
(
node
:
Node
)
->
:
if
node
.
op
==
NodeOp
.
RECUR
:
raise
ParserException
(
"recur must appear in tail position"
,
form
=
node
.
form
,
lisp_ast
=
node
)
elif
node
.
op
in
{
NodeOp
.
FN
,
NodeOp
.
LOOP
}
:
pass
else
:
node
.
visit
(
_assert_no_recur
)

Assert that recur forms do not appear in any position of this or child AST nodes .


def _assert_recur_is_tail(node: Node) -> None:  # pylint: disable=too-many-branches
    """Assert that `recur` forms only appear in the tail position of this
    or child AST nodes.

    `recur` forms may only appear in `do` nodes (both literal and synthetic
    `do` nodes) and in either the :then or :else expression of an `if` node."""
    if node.op == NodeOp.DO:
        assert isinstance(node, Do)
        for child in node.statements:
            _assert_no_recur(child)
        _assert_recur_is_tail(node.ret)
    elif node.op in {NodeOp.FN, NodeOp.FN_METHOD, NodeOp.METHOD}:
        assert isinstance(node, (Fn, FnMethod, Method))
        node.visit(_assert_recur_is_tail)
    elif node.op == NodeOp.IF:
        assert isinstance(node, If)
        _assert_no_recur(node.test)
        _assert_recur_is_tail(node.then)
        _assert_recur_is_tail(node.else_)
    elif node.op in {NodeOp.LET, NodeOp.LETFN}:
        assert isinstance(node, (Let, LetFn))
        for binding in node.bindings:
            assert binding.init is not None
            _assert_no_recur(binding.init)
        _assert_recur_is_tail(node.body)
    elif node.op == NodeOp.LOOP:
        assert isinstance(node, Loop)
        for binding in node.bindings:
            assert binding.init is not None
            _assert_no_recur(binding.init)
    elif node.op == NodeOp.RECUR:
        pass
    elif node.op == NodeOp.TRY:
        assert isinstance(node, Try)
        _assert_recur_is_tail(node.body)
        for catch in node.catches:
            _assert_recur_is_tail(catch)
        if node.finally_:
            _assert_no_recur(node.finally_)
    else:
        node.visit(_assert_no_recur)

def _assert_recur_is_tail ( node : Node ) -> None : if node . op == NodeOp . DO : assert isinstance ( node , Do ) for child in node . statements : _assert_no_recur ( child ) _assert_recur_is_tail ( node . ret ) elif node . op in { NodeOp . FN , NodeOp . FN_METHOD , NodeOp . METHOD } : assert isinstance ( node , ( Fn , FnMethod , Method ) ) node . visit ( _assert_recur_is_tail ) elif node . op == NodeOp . IF : assert isinstance ( node , If ) _assert_no_recur ( node . test ) _assert_recur_is_tail ( node . then ) _assert_recur_is_tail ( node . else_ ) elif node . op in { NodeOp . LET , NodeOp . LETFN } : assert isinstance ( node , ( Let , LetFn ) ) for binding in node . bindings : assert binding . init is not None _assert_no_recur ( binding . init ) _assert_recur_is_tail ( node . body ) elif node . op == NodeOp . LOOP : assert isinstance ( node , Loop ) for binding in node . bindings : assert binding . init is not None _assert_no_recur ( binding . init ) elif node . op == NodeOp . RECUR : pass elif node . op == NodeOp . TRY : assert isinstance ( node , Try ) _assert_recur_is_tail ( node . body ) for catch in node . catches : _assert_recur_is_tail ( catch ) if node . finally_ : _assert_no_recur ( node . finally_ ) else : node . visit ( _assert_no_recur )

Assert that recur forms only appear in the tail position of this or child AST nodes .


def __resolve_bare_symbol(
    ctx: ParserContext, form: sym.Symbol
) -> Union[MaybeClass, VarRef]:
    """Resolve a non-namespaced symbol into a Python name or a local
    Basilisp Var."""
    assert form.ns is None

    # Look up the symbol in the namespace mapping of the current namespace.
    v = ctx.current_ns.find(form)
    if v is not None:
        return VarRef(form=form, var=v, env=ctx.get_node_env())

    if "." in form.name:
        raise ParserException(
            "symbol names may not contain the '.' operator", form=form
        )

    munged = munge(form.name, allow_builtins=True)
    if munged in vars(builtins):
        return MaybeClass(
            form=form,
            class_=munged,
            target=vars(builtins)[munged],
            env=ctx.get_node_env(),
        )

    assert munged not in vars(ctx.current_ns.module)
    raise ParserException(
        f"unable to resolve symbol '{form}' in this context", form=form
    )

Resolve a non - namespaced symbol into a Python name or a local Basilisp Var .


def _resolve_sym(
    ctx: ParserContext, form: sym.Symbol
) -> Union[MaybeClass, MaybeHostForm, VarRef]:
    """Resolve a Basilisp symbol as a Var or Python name."""
    # Support special class-name syntax to instantiate new classes
    #   (Classname. *args)
    #   (aliased.Classname. *args)
    #   (fully.qualified.Classname. *args)
    if form.ns is None and form.name.endswith("."):
        try:
            ns, name = form.name[:-1].rsplit(".", maxsplit=1)
            form = sym.symbol(name, ns=ns)
        except ValueError:
            form = sym.symbol(form.name[:-1])

    if form.ns is not None:
        return __resolve_namespaced_symbol(ctx, form)
    else:
        return __resolve_bare_symbol(ctx, form)

def _resolve_sym ( ctx : ParserContext , form : sym . Symbol ) -> Union [ MaybeClass , MaybeHostForm , VarRef ] : if form . ns is None and form . name . endswith ( "." ) : try : ns , name = form . name [ : - 1 ] . rsplit ( "." , maxsplit = 1 ) form = sym . symbol ( name , ns = ns ) except ValueError : form = sym . symbol ( form . name [ : - 1 ] ) if form . ns is not None : return __resolve_namespaced_symbol ( ctx , form ) else : return __resolve_bare_symbol ( ctx , form )

Resolve a Basilisp symbol as a Var or Python name .


def parse_ast(ctx: ParserContext, form: ReaderForm) -> Node:
    """Take a Lisp form as an argument and produce a Basilisp syntax
    tree matching the clojure.tools.analyzer AST spec."""
    return _parse_ast(ctx, form).assoc(top_level=True)

def parse_ast ( ctx : ParserContext , form : ReaderForm ) -> Node : return _parse_ast ( ctx , form ) . assoc ( top_level = True )

Take a Lisp form as an argument and produce a Basilisp syntax tree matching the clojure . tools . analyzer AST spec .


def warn_on_shadowed_var(self) -> bool:
        """If True, warn when a def'ed Var name is shadowed in an inner scope.

        Implied by warn_on_shadowed_name. The value of warn_on_shadowed_name
        supersedes the value of this flag."""
        return self.warn_on_shadowed_name or self._opts.entry(
            WARN_ON_SHADOWED_VAR, False
        )

def warn_on_shadowed_var ( self ) -> bool : return self . warn_on_shadowed_name or self . _opts . entry ( WARN_ON_SHADOWED_VAR , False )

If True warn when a def ed Var name is shadowed in an inner scope .


def put_new_symbol(  # pylint: disable=too-many-arguments
        self,
        s: sym.Symbol,
        binding: Binding,
        warn_on_shadowed_name: bool = True,
        warn_on_shadowed_var: bool = True,
        warn_if_unused: bool = True,
    ):
        """Add a new symbol to the symbol table.

        This function allows individual warnings to be disabled for one run
        by supplying keyword arguments temporarily disabling those warnings.
        In certain cases, we do not want to issue warnings again for a
        previously checked case, so this is a simple way of disabling these
        warnings for those cases.

        If WARN_ON_SHADOWED_NAME compiler option is active and the
        warn_on_shadowed_name keyword argument is True, then a warning will be
        emitted if a local name is shadowed by another local name. Note that
        WARN_ON_SHADOWED_NAME implies WARN_ON_SHADOWED_VAR.

        If WARN_ON_SHADOWED_VAR compiler option is active and the
        warn_on_shadowed_var keyword argument is True, then a warning will be
        emitted if a named var is shadowed by a local name."""
        st = self.symbol_table
        if warn_on_shadowed_name and self.warn_on_shadowed_name:
            if st.find_symbol(s) is not None:
                logger.warning(f"name '{s}' shadows name from outer scope")
        if (
            warn_on_shadowed_name or warn_on_shadowed_var
        ) and self.warn_on_shadowed_var:
            if self.current_ns.find(s) is not None:
                logger.warning(f"name '{s}' shadows def'ed Var from outer scope")
        if s.meta is not None and s.meta.entry(SYM_NO_WARN_WHEN_UNUSED_META_KEY, None):
            warn_if_unused = False
        st.new_symbol(s, binding, warn_if_unused=warn_if_unused)


def map_lrepr(
    entries: Callable[[], Iterable[Tuple[Any, Any]]],
    start: str,
    end: str,
    meta=None,
    **kwargs,
) -> str:
    """Produce a Lisp representation of an associative collection, bookended
    with the start and end string supplied. The entries argument must be a
    callable which will produce tuples of key-value pairs.

    The keyword arguments will be passed along to lrepr for the sequence
    elements."""
    print_level = kwargs["print_level"]
    if isinstance(print_level, int) and print_level < 1:
        return SURPASSED_PRINT_LEVEL

    kwargs = _process_kwargs(**kwargs)

    def entry_reprs():
        for k, v in entries():
            yield "{k} {v}".format(k=lrepr(k, **kwargs), v=lrepr(v, **kwargs))

    trailer = []
    print_dup = kwargs["print_dup"]
    print_length = kwargs["print_length"]
    if not print_dup and isinstance(print_length, int):
        items = seq(entry_reprs()).take(print_length + 1).to_list()
        if len(items) > print_length:
            items.pop()
            trailer.append(SURPASSED_PRINT_LENGTH)
    else:
        items = list(entry_reprs())

    seq_lrepr = PRINT_SEPARATOR.join(items + trailer)

    print_meta = kwargs["print_meta"]
    if print_meta and meta:
        return f"^{lrepr(meta, **kwargs)} {start}{seq_lrepr}{end}"

    return f"{start}{seq_lrepr}{end}"

Produce a Lisp representation of an associative collection bookended with the start and end string supplied . The entries argument must be a callable which will produce tuples of key - value pairs .


def seq_lrepr(
    iterable: Iterable[Any], start: str, end: str, meta=None, **kwargs
) -> str:
    """Produce a Lisp representation of a sequential collection, bookended
    with the start and end string supplied. The keyword arguments will be
    passed along to lrepr for the sequence elements."""
    print_level = kwargs["print_level"]
    if isinstance(print_level, int) and print_level < 1:
        return SURPASSED_PRINT_LEVEL

    kwargs = _process_kwargs(**kwargs)

    trailer = []
    print_dup = kwargs["print_dup"]
    print_length = kwargs["print_length"]
    if not print_dup and isinstance(print_length, int):
        items = seq(iterable).take(print_length + 1).to_list()
        if len(items) > print_length:
            items.pop()
            trailer.append(SURPASSED_PRINT_LENGTH)
    else:
        items = iterable

    items = list(map(lambda o: lrepr(o, **kwargs), items))
    seq_lrepr = PRINT_SEPARATOR.join(items + trailer)

    print_meta = kwargs["print_meta"]
    if print_meta and meta:
        return f"^{lrepr(meta, **kwargs)} {start}{seq_lrepr}{end}"

    return f"{start}{seq_lrepr}{end}"

Produce a Lisp representation of a sequential collection bookended with the start and end string supplied . The keyword arguments will be passed along to lrepr for the sequence elements .


def lrepr(  # pylint: disable=too-many-arguments
    o: Any,
    human_readable: bool = False,
    print_dup: bool = PRINT_DUP,
    print_length: PrintCountSetting = PRINT_LENGTH,
    print_level: PrintCountSetting = PRINT_LEVEL,
    print_meta: bool = PRINT_META,
    print_readably: bool = PRINT_READABLY,
) -> str:
    """Return a string representation of a Lisp object.

    Permissible keyword arguments are:
    - human_readable: if logical True, print strings without quotations or
                      escape sequences (default: false)
    - print_dup: if logical true, print objects in a way that preserves their
                 types (default: false)
    - print_length: the number of items in a collection which will be printed,
                    or no limit if bound to a logical falsey value (default: 50)
    - print_level: the depth of the object graph to print, starting with 0, or
                   no limit if bound to a logical falsey value (default: nil)
    - print_meta: if logical true, print objects meta in a way that can be
                  read back by the reader (default: false)
    - print_readably: if logical false, print strings and characters with
                      non-alphanumeric characters converted to escape sequences
                      (default: true)

    Note that this function is not capable of capturing the values bound at
    runtime to the basilisp.core dynamic variables which correspond to each
    of the keyword arguments to this function. To use a version of lrepr
    which does capture those values, call basilisp.lang.runtime.lrepr directly."""
    if isinstance(o, LispObject):
        return o._lrepr(
            human_readable=human_readable,
            print_dup=print_dup,
            print_length=print_length,
            print_level=print_level,
            print_meta=print_meta,
            print_readably=print_readably,
        )
    else:  # pragma: no cover
        return _lrepr_fallback(
            o,
            human_readable=human_readable,
            print_dup=print_dup,
            print_length=print_length,
            print_level=print_level,
            print_meta=print_meta,
            print_readably=print_readably,
        )

def lrepr ( o : Any , human_readable : bool = False , print_dup : bool = PRINT_DUP , print_length : PrintCountSetting = PRINT_LENGTH , print_level : PrintCountSetting = PRINT_LEVEL , print_meta : bool = PRINT_META , print_readably : bool = PRINT_READABLY , ) -> str : if isinstance ( o , LispObject ) : return o . _lrepr ( human_readable = human_readable , print_dup = print_dup , print_length = print_length , print_level = print_level , print_meta = print_meta , print_readably = print_readably , ) else : return _lrepr_fallback ( o , human_readable = human_readable , print_dup = print_dup , print_length = print_length , print_level = print_level , print_meta = print_meta , print_readably = print_readably , )

Return a string representation of a Lisp object .


def _lrepr_fallback(  # pylint: disable=too-many-arguments
    o: Any,
    human_readable: bool = False,
    print_dup: bool = PRINT_DUP,
    print_length: PrintCountSetting = PRINT_LENGTH,
    print_level: PrintCountSetting = PRINT_LEVEL,
    print_meta: bool = PRINT_META,
    print_readably: bool = PRINT_READABLY,
) -> str:  # pragma: no cover
    """Fallback function for lrepr for subclasses of standard types.

    The singledispatch used for standard lrepr dispatches using an exact
    type match on the first argument, so we will only hit this function
    for subclasses of common Python types like strings or lists."""
    kwargs = {
        "human_readable": human_readable,
        "print_dup": print_dup,
        "print_length": print_length,
        "print_level": print_level,
        "print_meta": print_meta,
        "print_readably": print_readably,
    }
    if isinstance(o, bool):
        return _lrepr_bool(o)
    elif o is None:
        return _lrepr_nil(o)
    elif isinstance(o, str):
        return _lrepr_str(
            o, human_readable=human_readable, print_readably=print_readably
        )
    elif isinstance(o, dict):
        return _lrepr_py_dict(o, **kwargs)
    elif isinstance(o, list):
        return _lrepr_py_list(o, **kwargs)
    elif isinstance(o, set):
        return _lrepr_py_set(o, **kwargs)
    elif isinstance(o, tuple):
        return _lrepr_py_tuple(o, **kwargs)
    elif isinstance(o, complex):
        return _lrepr_complex(o)
    elif isinstance(o, datetime.datetime):
        return _lrepr_datetime(o)
    elif isinstance(o, Decimal):
        return _lrepr_decimal(o, print_dup=print_dup)
    elif isinstance(o, Fraction):
        return _lrepr_fraction(o)
    elif isinstance(o, Pattern):
        return _lrepr_pattern(o)
    elif isinstance(o, uuid.UUID):
        return _lrepr_uuid(o)
    else:
        return repr(o)

def _lrepr_fallback ( o : Any , human_readable : bool = False , print_dup : bool = PRINT_DUP , print_length : PrintCountSetting = PRINT_LENGTH , print_level : PrintCountSetting = PRINT_LEVEL , print_meta : bool = PRINT_META , print_readably : bool = PRINT_READABLY , ) -> str : kwargs = { "human_readable" : human_readable , "print_dup" : print_dup , "print_length" : print_length , "print_level" : print_level , "print_meta" : print_meta , "print_readably" : print_readably , } if isinstance ( o , bool ) : return _lrepr_bool ( o ) elif o is None : return _lrepr_nil ( o ) elif isinstance ( o , str ) : return _lrepr_str ( o , human_readable = human_readable , print_readably = print_readably ) elif isinstance ( o , dict ) : return _lrepr_py_dict ( o , ** kwargs ) elif isinstance ( o , list ) : return _lrepr_py_list ( o , ** kwargs ) elif isinstance ( o , set ) : return _lrepr_py_set ( o , ** kwargs ) elif isinstance ( o , tuple ) : return _lrepr_py_tuple ( o , ** kwargs ) elif isinstance ( o , complex ) : return _lrepr_complex ( o ) elif isinstance ( o , datetime . datetime ) : return _lrepr_datetime ( o ) elif isinstance ( o , Decimal ) : return _lrepr_decimal ( o , print_dup = print_dup ) elif isinstance ( o , Fraction ) : return _lrepr_fraction ( o ) elif isinstance ( o , Pattern ) : return _lrepr_pattern ( o ) elif isinstance ( o , uuid . UUID ) : return _lrepr_uuid ( o ) else : return repr ( o )

Fallback function for lrepr for subclasses of standard types .