# Path: gffutils/constants.py
# SCHEMA = """
# 
# CREATE TABLE features (
#     id text,
#     seqid text,
#     source text,
#     featuretype text,
#     start int,
#     end int,
#     score text,
#     strand text,
#     frame text,
#     attributes text,
#     extra text,
#     bin int,
#     primary key (id)
#     );
# 
# CREATE TABLE relations (
#     parent text,
#     child text,
#     level int,
#     primary key (parent, child, level)
#     );
# 
# CREATE TABLE meta (
#     dialect text,
#     version text
#     );
# 
# CREATE TABLE directives (
#     directive text
#     );
# 
# CREATE TABLE autoincrements (
#     base text,
#     n int,
#     primary key (base)
#     );
# 
# CREATE TABLE duplicates (
#     idspecid text,
#     newid text,
#     primary key (newid)
#     );
# 
# 
# """
# _SELECT = "SELECT " \
#     + ', '.join(_keys) \
#     + ", features.rowid as file_order FROM features "
# _INSERT = "INSERT INTO features (" \
#     + ', '.join(_keys) + ") VALUES (" + ','.join(list('?' * len(_keys))) + ")"
# _UPDATE = "UPDATE features SET " + _update_clause + " WHERE id = ?"
# INDEXES = []
# 
# Path: gffutils/exceptions.py
# class AttributeStringError(Exception):
#     pass


import re
import copy
import collections
import logging
from six.moves import urllib
from gffutils import constants
from gffutils.exceptions import AttributeStringError
    from gffutils import feature
# function...
def _split_keyvals(keyval_str, dialect=None):
    """
    Given the string attributes field of a GFF-like line, split it into an
    attributes dictionary and a "dialect" dictionary which contains information
    needed to reconstruct the original string.

    Lots of logic here to handle all the corner cases.

    If `dialect` is None, then do all the logic to infer a dialect from this
    attribute string.

    Otherwise, use the provided dialect (and return it at the end).
    """

    def _unquote_quals(quals, dialect):
        """
        Handles the unquoting (decoding) of percent-encoded characters.

        See notes on encoding/decoding above.
        """
        if not constants.ignore_url_escape_characters and dialect['fmt'] == 'gff3':
            for key, vals in quals.items():
                unquoted = [urllib.parse.unquote(v) for v in vals]
                quals[key] = unquoted
        return quals

    infer_dialect = False
    if dialect is None:
        # Make a copy of default dialect so it can be modified as needed

# Path: gffutils/constants.py
# SCHEMA = """
# 
# CREATE TABLE features (
#     id text,
#     seqid text,
#     source text,
#     featuretype text,
#     start int,
#     end int,
#     score text,
#     strand text,
#     frame text,
#     attributes text,
#     extra text,
#     bin int,
#     primary key (id)
#     );
# 
# CREATE TABLE relations (
#     parent text,
#     child text,
#     level int,
#     primary key (parent, child, level)
#     );
# 
# CREATE TABLE meta (
#     dialect text,
#     version text
#     );
# 
# CREATE TABLE directives (
#     directive text
#     );
# 
# CREATE TABLE autoincrements (
#     base text,
#     n int,
#     primary key (base)
#     );
# 
# CREATE TABLE duplicates (
#     idspecid text,
#     newid text,
#     primary key (newid)
#     );
# 
# 
# """
# _SELECT = "SELECT " \
#     + ', '.join(_keys) \
#     + ", features.rowid as file_order FROM features "
# _INSERT = "INSERT INTO features (" \
#     + ', '.join(_keys) + ") VALUES (" + ','.join(list('?' * len(_keys))) + ")"
# _UPDATE = "UPDATE features SET " + _update_clause + " WHERE id = ?"
# INDEXES = []
# 
# Path: gffutils/exceptions.py
# class AttributeStringError(Exception):
#     pass


# Path: gffutils/parser.py
import re
import copy
import collections
import logging
from six.moves import urllib
from gffutils import constants
from gffutils.exceptions import AttributeStringError
    from gffutils import feature

# function...
def _split_keyvals(keyval_str, dialect=None):
    """
    Given the string attributes field of a GFF-like line, split it into an
    attributes dictionary and a "dialect" dictionary which contains information
    needed to reconstruct the original string.

    Lots of logic here to handle all the corner cases.

    If `dialect` is None, then do all the logic to infer a dialect from this
    attribute string.

    Otherwise, use the provided dialect (and return it at the end).
    """

    def _unquote_quals(quals, dialect):
        """
        Handles the unquoting (decoding) of percent-encoded characters.

        See notes on encoding/decoding above.
        """
        if not constants.ignore_url_escape_characters and dialect['fmt'] == 'gff3':
            for key, vals in quals.items():
                unquoted = [urllib.parse.unquote(v) for v in vals]
                quals[key] = unquoted
        return quals

    infer_dialect = False
    if dialect is None:
        # Make a copy of default dialect so it can be modified as needed

        dialect = copy.copy(constants.dialect)