# Path: gffutils/create.py
# def create(self):
#     """
#     Calls various methods sequentially in order to fully build the
#     database.
#     """
#     # Calls each of these methods in order.  _populate_from_lines and
#     # _update_relations must be implemented in subclasses.
#     self._init_tables()
#     self._populate_from_lines(self.iterator)
#     self._update_relations()
#     self._finalize()
# 
# Path: gffutils/parser.py
# class Quoter(collections.defaultdict):
#     def __missing__(self, b):
# def _reconstruct(keyvals, dialect, keep_order=False,
#                  sort_attribute_values=False):
#     def sort_key(x):
# def _split_keyvals(keyval_str, dialect=None):
#     def _unquote_quals(quals, dialect):
# 
# Path: gffutils/feature.py
# class Feature(object):
#     def __init__(self, seqid=".", source=".", featuretype=".",
#                  start=".", end=".", score=".", strand=".", frame=".",
#                  attributes=None, extra=None, bin=None, id=None, dialect=None,
#                  file_order=None, keep_order=False,
#                  sort_attribute_values=False):
#     def calc_bin(self, _bin=None):
#     def __repr__(self):
#     def __getitem__(self, key):
#     def __setitem__(self, key, value):
#     def __str__(self):
#     def __unicode__(self):
#     def __hash__(self):
#     def __eq__(self, other):
#     def __ne__(self, other):
#     def __len__(self):
#     def chrom(self):
#     def chrom(self, value):
#     def stop(self):
#     def stop(self, value):
#     def astuple(self, encoding=None):
#     def sequence(self, fasta, use_strand=True):
# def feature_from_line(line, dialect=None, strict=True, keep_order=False):
# 
# Path: gffutils/helpers.py
# def example_filename(fn):
#     """
#     Return the full path of a data file that ships with gffutils.
#     """
#     return os.path.join(HERE, 'test', 'data', fn)


import warnings
import gffutils
import gffutils.helpers as helpers
import gffutils.gffwriter as gffwriter
import gffutils.inspect as inspect
import gffutils.iterators as iterators
import sys
import os
import six
import shutil
import threading
import tempfile
    import socketserver as SocketServer
    import SocketServer
import multiprocessing
import json
import tempfile
import shutil
import glob
import difflib
    import tempfile
from textwrap import dedent
from . import expected
from gffutils import example_filename, create, parser, feature
from textwrap import dedent
from nose.tools import assert_raises
from six.moves import SimpleHTTPServer

    # ought to be one more now . . .
    num_features = len(list(db.all_features()))
    assert num_features == orig_num_features + 1, num_features

    # Now try updating with the same feature, but using merge_strategy="merge",
    # which appends items to attributes ( n=1 --> n=1,2 )
    f = feature.feature_from_line(
        'chr2L . testing 1 10 . + . ID=testing_feature;n=1',
        dialect=db.dialect, strict=False)
    f.keep_order = True
    f.attributes['n'] = ['2']
    db.update([f], merge_strategy='merge')
    x = list(db.features_of_type('testing'))
    assert len(x) == 1

    # Merging does a list(set()) operation, so the order is not guaranteed.
    # Fix it here for testing...
    x = x[0]
    x.attributes['n'].sort()

    assert str(x) == "chr2L	.	testing	1	10	.	+	.	ID=testing_feature;n=1,2", str(x)

    # still should have the same number of features as before (still 2)
    num_features = len(list(db.all_features()))
    assert num_features == orig_num_features + 1, num_features


    # Merging while iterating.  e.g., if you're updating children with gene
    # IDs.

# Path: gffutils/create.py
# def create(self):
#     """
#     Calls various methods sequentially in order to fully build the
#     database.
#     """
#     # Calls each of these methods in order.  _populate_from_lines and
#     # _update_relations must be implemented in subclasses.
#     self._init_tables()
#     self._populate_from_lines(self.iterator)
#     self._update_relations()
#     self._finalize()
# 
# Path: gffutils/parser.py
# class Quoter(collections.defaultdict):
#     def __missing__(self, b):
# def _reconstruct(keyvals, dialect, keep_order=False,
#                  sort_attribute_values=False):
#     def sort_key(x):
# def _split_keyvals(keyval_str, dialect=None):
#     def _unquote_quals(quals, dialect):
# 
# Path: gffutils/feature.py
# class Feature(object):
#     def __init__(self, seqid=".", source=".", featuretype=".",
#                  start=".", end=".", score=".", strand=".", frame=".",
#                  attributes=None, extra=None, bin=None, id=None, dialect=None,
#                  file_order=None, keep_order=False,
#                  sort_attribute_values=False):
#     def calc_bin(self, _bin=None):
#     def __repr__(self):
#     def __getitem__(self, key):
#     def __setitem__(self, key, value):
#     def __str__(self):
#     def __unicode__(self):
#     def __hash__(self):
#     def __eq__(self, other):
#     def __ne__(self, other):
#     def __len__(self):
#     def chrom(self):
#     def chrom(self, value):
#     def stop(self):
#     def stop(self, value):
#     def astuple(self, encoding=None):
#     def sequence(self, fasta, use_strand=True):
# def feature_from_line(line, dialect=None, strict=True, keep_order=False):
# 
# Path: gffutils/helpers.py
# def example_filename(fn):
#     """
#     Return the full path of a data file that ships with gffutils.
#     """
#     return os.path.join(HERE, 'test', 'data', fn)


# Path: gffutils/test/test.py
import warnings
import gffutils
import gffutils.helpers as helpers
import gffutils.gffwriter as gffwriter
import gffutils.inspect as inspect
import gffutils.iterators as iterators
import sys
import os
import six
import shutil
import threading
import tempfile
    import socketserver as SocketServer
    import SocketServer
import multiprocessing
import json
import tempfile
import shutil
import glob
import difflib
    import tempfile
from textwrap import dedent
from . import expected
from gffutils import example_filename, create, parser, feature
from textwrap import dedent
from nose.tools import assert_raises
from six.moves import SimpleHTTPServer


    # ought to be one more now . . .
    num_features = len(list(db.all_features()))
    assert num_features == orig_num_features + 1, num_features

    # Now try updating with the same feature, but using merge_strategy="merge",
    # which appends items to attributes ( n=1 --> n=1,2 )
    f = feature.feature_from_line(
        'chr2L . testing 1 10 . + . ID=testing_feature;n=1',
        dialect=db.dialect, strict=False)
    f.keep_order = True
    f.attributes['n'] = ['2']
    db.update([f], merge_strategy='merge')
    x = list(db.features_of_type('testing'))
    assert len(x) == 1

    # Merging does a list(set()) operation, so the order is not guaranteed.
    # Fix it here for testing...
    x = x[0]
    x.attributes['n'].sort()

    assert str(x) == "chr2L	.	testing	1	10	.	+	.	ID=testing_feature;n=1,2", str(x)

    # still should have the same number of features as before (still 2)
    num_features = len(list(db.all_features()))
    assert num_features == orig_num_features + 1, num_features


    # Merging while iterating.  e.g., if you're updating children with gene
    # IDs.

    db = create.create_db(example_filename('FBgn0031208.gff'), ':memory:',