Repository: vanheeringen-lab/genomepy

Issue:
Genome.sizes is not populated?
```
In [4]: import genomepy

In [5]: g = genomepy.Genome("hg38")

In [6]: g.sizes
Out[6]: {}
```



Discussion:
codeclimate[bot]: Code Climate has analyzed commit ac0c9b6e and detected **0 issues** on this pull request.

The test coverage on the diff in this pull request is **92.0%** (**50%** is the threshold).

This pull request will bring the total coverage in the repository to **94.0%** (**0.0%** change).

View more on [Code Climate](https://codeclimate.com/github/vanheeringen-lab/genomepy/pull/100).


Patch:
diff --git a/genomepy/genome.py b/genomepy/genome.py
index 2c96252..c9bcd63 100644
--- a/genomepy/genome.py
+++ b/genomepy/genome.py
@@ -55,8 +55,8 @@ class Genome(Fasta):
         self.readme_file = os.path.join(self.genome_dir, "README.txt")
 
         # genome attributes
-        self.sizes = {}  # populate using contig_sizes
-        self.gaps = {}  # populate using gaps_sizes
+        self.sizes = {}
+        self.gaps = {}
         metadata = self._read_metadata()
         self.tax_id = metadata.get("tax_id")
         self.assembly_accession = metadata.get("assembly_accession")
@@ -67,20 +67,72 @@ class Genome(Fasta):
 
     @sizes_file.setter
     def sizes_file(self, fname):
+        """generate the sizes_file when the class is initiated"""
         if not os.path.exists(fname):
             generate_fa_sizes(self.genome_file, fname)
         self.__sizes_file = fname
 
+    @property
+    def sizes(self):
+        return self.__sizes
+
+    @sizes.setter
+    def sizes(self, contig_sizes):
+        self.__sizes = contig_sizes
+
+    @sizes.getter
+    def sizes(self):
+        """Return sizes per contig when requested
+
+        Returns
+        -------
+        contig_sizes : dict
+            a dictionary with contigs as key and their lengths as values
+        """
+        if self.__sizes == {}:
+            with open(self.sizes_file) as f:
+                for line in f:
+                    contig, length = line.strip().split("\t")
+                    self.__sizes[contig] = length
+        return self.__sizes
+
     @property
     def gaps_file(self):
         return self.__gaps_file
 
     @gaps_file.setter
     def gaps_file(self, fname):
+        """generate the gaps_file when the class is initiated"""
         if not os.path.exists(fname):
             generate_gap_bed(self.genome_file, fname)
         self.__gaps_file = fname
 
+    @property
+    def gaps(self):
+        return self.__gaps
+
+    @gaps.setter
+    def gaps(self, gap_sizes):
+        self.__gaps = gap_sizes
+
+    @gaps.getter
+    def gaps(self):
+        """Return gap sizes per chromosome when requested
+
+        Returns
+        -------
+        gap_sizes : dict
+            a dictionary with chromosomes as key and the total number of
+            Ns as values
+        """
+        if self.__gaps == {}:
+            with open(self.gaps_file) as f:
+                for line in f:
+                    chrom, start, end = line.strip().split("\t")
+                    start, end = int(start), int(end)
+                    self.__gaps[chrom] = self.__gaps.get(chrom, 0) + end - start
+        return self.__gaps
+
     @property
     def plugin(self):
         """dict of all active plugins and their properties"""
@@ -323,36 +375,6 @@ class Genome(Fasta):
         else:
             return [seq for seq in seqqer]
 
-    def contig_sizes(self):
-        """Return sizes per contig.
-
-        Returns
-        -------
-        contig_sizes : dict
-            a dictionary with contigs as key and their lengths as values
-        """
-        with open(self.sizes_file) as f:
-            for line in f:
-                contig, length = line.strip().split("\t")
-                self.sizes[contig] = length
-        return self.sizes
-
-    def gap_sizes(self):
-        """Return gap sizes per chromosome.
-
-        Returns
-        -------
-        gap_sizes : dict
-            a dictionary with chromosomes as key and the total number of
-            Ns as values
-        """
-        with open(self.gaps_file) as f:
-            for line in f:
-                chrom, start, end = line.strip().split("\t")
-                start, end = int(start), int(end)
-                self.gaps[chrom] = self.gaps.get(chrom, 0) + end - start
-        return self.gaps
-
     @staticmethod
     def _weighted_selection(list_of_tuples, n):
         """
@@ -401,8 +423,6 @@ class Genome(Fasta):
         """
         if not chroms:
             chroms = self.keys()
-        if self.gaps is None:
-            self.gap_sizes()
 
         # dict of chromosome sizes after subtracting the number of Ns
         sizes = dict(


Test patch:
diff --git a/tests/04_genome_test.py b/tests/04_genome_test.py
index 68fd780..d7a3547 100644
--- a/tests/04_genome_test.py
+++ b/tests/04_genome_test.py
@@ -300,13 +300,27 @@ def test_track2fasta(genome="tests/data/small_genome.fa.gz"):
 
 def test_sizes(genome="tests/data/gap.fa"):
     g = genomepy.Genome(genome)
-    g.contig_sizes()
+    assert list(g.sizes.keys()) == ["chr1", "chr2", "chr3"]
+
+    # does not overwrite user-set sizes
+    g.sizes = {"asd": 1}
+    assert g.sizes == {"asd": 1}
+
+    # repopulates empty dicts
+    g.sizes = {}
     assert list(g.sizes.keys()) == ["chr1", "chr2", "chr3"]
 
 
 def test_gaps(genome="tests/data/gap.fa"):
     g = genomepy.Genome(genome)
-    g.gap_sizes()
+    assert list(g.gaps.keys()) == ["chr1", "chr3"]
+
+    # does not overwrite user-set gaps
+    g.gaps = {"asd": 1}
+    assert g.gaps == {"asd": 1}
+
+    # repopulates empty dicts
+    g.gaps = {}
     assert list(g.gaps.keys()) == ["chr1", "chr3"]