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).

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(

Genome.sizes is not populated?
```
In [4]: import genomepy

In [5]: g = genomepy.Genome("hg38")

In [6]: g.sizes
Out[6]: {}
```


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"]
 
 

environment.yml
pip install -e .
parse_log_pytest
environment.yml
pytest
3.9
pytest --no-header -rA --tb=line --color=no -p no:cacheprovider -W ignore::DeprecationWarning
appdirs @ file:///home/conda/feedstock_root/build_artifacts/appdirs_1733753955715/work
attrs @ file:///home/conda/feedstock_root/build_artifacts/attrs_1741918516150/work
biopython @ file:///home/conda/feedstock_root/build_artifacts/biopython_1737241701628/work
black @ file:///home/conda/feedstock_root/build_artifacts/black-recipe_1742502760723/work
boltons @ file:///home/conda/feedstock_root/build_artifacts/boltons_1733827268945/work
Brotli @ file:///home/conda/feedstock_root/build_artifacts/brotli-split_1725267488082/work
BucketCache @ file:///home/conda/feedstock_root/build_artifacts/bucketcache_1602590044934/work
certifi @ file:///home/conda/feedstock_root/build_artifacts/certifi_1739515848642/work/certifi
cffi @ file:///home/conda/feedstock_root/build_artifacts/cffi_1725571112467/work
charset-normalizer @ file:///home/conda/feedstock_root/build_artifacts/charset-normalizer_1735929714516/work
click @ file:///home/conda/feedstock_root/build_artifacts/click_1734858813237/work
colorama @ file:///home/conda/feedstock_root/build_artifacts/colorama_1733218098505/work
coverage @ file:///home/conda/feedstock_root/build_artifacts/coverage_1743381224823/work
decorator @ file:///home/conda/feedstock_root/build_artifacts/decorator_1740384970518/work
exceptiongroup @ file:///home/conda/feedstock_root/build_artifacts/exceptiongroup_1733208806608/work
flake8 @ file:///home/conda/feedstock_root/build_artifacts/flake8_1739898391164/work
flake8-bugbear @ file:///home/conda/feedstock_root/build_artifacts/flake8-bugbear_1734116211316/work
-e git+https://github.com/vanheeringen-lab/genomepy.git@ea1cff778edada4b90b286280151c9bd385a5778#egg=genomepy
h2 @ file:///home/conda/feedstock_root/build_artifacts/h2_1738578511449/work
hpack @ file:///home/conda/feedstock_root/build_artifacts/hpack_1737618293087/work
hyperframe @ file:///home/conda/feedstock_root/build_artifacts/hyperframe_1737618333194/work
idna @ file:///home/conda/feedstock_root/build_artifacts/idna_1733211830134/work
importlib_metadata @ file:///home/conda/feedstock_root/build_artifacts/importlib-metadata_1737420181517/work
iniconfig @ file:///home/conda/feedstock_root/build_artifacts/iniconfig_1733223141826/work
Logbook @ file:///home/conda/feedstock_root/build_artifacts/logbook_1742488078739/work
mccabe @ file:///home/conda/feedstock_root/build_artifacts/mccabe_1733216466933/work
mypy_extensions @ file:///home/conda/feedstock_root/build_artifacts/mypy_extensions_1733230897951/work
norns==0.1.6
nose @ file:///home/conda/feedstock_root/build_artifacts/nose_1602434998960/work
numpy @ file:///home/conda/feedstock_root/build_artifacts/numpy_1732314280888/work/dist/numpy-2.0.2-cp39-cp39-linux_x86_64.whl#sha256=62d98eb3da9f13e6b227c430d01026b7427f341b3fdcb838430f2a9e520417b1
packaging @ file:///home/conda/feedstock_root/build_artifacts/packaging_1733203243479/work
pathspec @ file:///home/conda/feedstock_root/build_artifacts/pathspec_1733233363808/work
platformdirs @ file:///home/conda/feedstock_root/build_artifacts/bld/rattler-build_platformdirs_1742485085/work
pluggy @ file:///home/conda/feedstock_root/build_artifacts/pluggy_1733222765875/work
psutil @ file:///home/conda/feedstock_root/build_artifacts/psutil_1740663125313/work
pycodestyle @ file:///home/conda/feedstock_root/build_artifacts/pycodestyle_1733216196861/work
pycparser @ file:///home/conda/feedstock_root/build_artifacts/bld/rattler-build_pycparser_1733195786/work
pyfaidx @ file:///opt/conda/conda-bld/pyfaidx_1728570107633/work
pyflakes @ file:///home/conda/feedstock_root/build_artifacts/pyflakes_1733216066937/work
PySocks @ file:///home/conda/feedstock_root/build_artifacts/pysocks_1733217236728/work
pytest @ file:///home/conda/feedstock_root/build_artifacts/pytest_1740946542080/work
pytest-cov @ file:///home/conda/feedstock_root/build_artifacts/pytest-cov_1733223023082/work
python-dateutil @ file:///home/conda/feedstock_root/build_artifacts/python-dateutil_1733215673016/work
PyVCF3 @ file:///opt/conda/conda-bld/pyvcf3_1650931562118/work
PyYAML @ file:///home/conda/feedstock_root/build_artifacts/pyyaml_1737454647378/work
Represent==1.5.1
requests @ file:///home/conda/feedstock_root/build_artifacts/requests_1733217035951/work
six @ file:///home/conda/feedstock_root/build_artifacts/six_1733380938961/work
toml @ file:///home/conda/feedstock_root/build_artifacts/toml_1734091811753/work
tomli @ file:///home/conda/feedstock_root/build_artifacts/tomli_1733256695513/work
typing_extensions @ file:///home/conda/feedstock_root/build_artifacts/bld/rattler-build_typing_extensions_1743201626/work
urllib3 @ file:///home/conda/feedstock_root/build_artifacts/urllib3_1734859416348/work
zipp @ file:///home/conda/feedstock_root/build_artifacts/zipp_1732827521216/work
zstandard==0.23.0

name: genomepy
channels:
  - bioconda
  - https://repo.anaconda.com/pkgs/main
  - https://repo.anaconda.com/pkgs/r
  - conda-forge
dependencies:
  - _libgcc_mutex=0.1=conda_forge
  - _openmp_mutex=4.5=2_gnu
  - appdirs=1.4.4=pyhd8ed1ab_1
  - attrs=25.3.0=pyh71513ae_0
  - biopython=1.85=py39h8cd3c5a_1
  - black=25.1.0=pyha5154f8_0
  - boltons=24.0.0=pyhd8ed1ab_1
  - bowtie2=2.5.4=he96a11b_5
  - brotli-python=1.1.0=py39hf88036b_2
  - bucketcache=0.12.1=py39hde42818_2
  - bwa=0.7.19=h577a1d6_0
  - bzip2=1.0.8=h4bc722e_7
  - c-ares=1.34.4=hb9d3cd8_0
  - ca-certificates=2025.1.31=hbcca054_0
  - certifi=2025.1.31=pyhd8ed1ab_0
  - cffi=1.17.1=py39h15c3d72_0
  - charset-normalizer=3.4.1=pyhd8ed1ab_0
  - click=8.1.8=pyh707e725_0
  - colorama=0.4.6=pyhd8ed1ab_1
  - coverage=7.8.0=py39h9399b63_0
  - decorator=5.2.1=pyhd8ed1ab_0
  - exceptiongroup=1.2.2=pyhd8ed1ab_1
  - flake8=7.1.2=pyhd8ed1ab_0
  - flake8-bugbear=24.12.12=pyhd8ed1ab_0
  - gmap=2024.11.20=pl5321hb1d24b7_2
  - h2=4.2.0=pyhd8ed1ab_0
  - hisat2=2.2.1=h503566f_8
  - hpack=4.1.0=pyhd8ed1ab_0
  - htslib=1.21=h566b1c6_1
  - hyperframe=6.1.0=pyhd8ed1ab_0
  - idna=3.10=pyhd8ed1ab_1
  - importlib-metadata=8.6.1=pyha770c72_0
  - iniconfig=2.0.0=pyhd8ed1ab_1
  - keyutils=1.6.1=h166bdaf_0
  - krb5=1.21.3=h659f571_0
  - ld_impl_linux-64=2.43=h712a8e2_4
  - libblas=3.9.0=31_h59b9bed_openblas
  - libcblas=3.9.0=31_he106b2a_openblas
  - libcurl=8.12.1=h332b0f4_0
  - libdeflate=1.23=h4ddbbb0_0
  - libedit=3.1.20250104=pl5321h7949ede_0
  - libev=4.33=hd590300_2
  - libffi=3.4.6=h2dba641_0
  - libgcc=14.2.0=h767d61c_2
  - libgcc-ng=14.2.0=h69a702a_2
  - libgfortran=14.2.0=h69a702a_2
  - libgfortran5=14.2.0=hf1ad2bd_2
  - libgomp=14.2.0=h767d61c_2
  - liblapack=3.9.0=31_h7ac8fdf_openblas
  - liblzma=5.6.4=hb9d3cd8_0
  - libnghttp2=1.64.0=h161d5f1_0
  - libnsl=2.0.1=hd590300_0
  - libopenblas=0.3.29=pthreads_h94d23a6_0
  - libopenssl-static=3.4.1=hb9d3cd8_0
  - libpng=1.6.47=h943b412_0
  - libsqlite=3.49.1=hee588c1_2
  - libssh2=1.11.1=hf672d98_0
  - libstdcxx=14.2.0=h8f9b012_2
  - libstdcxx-ng=14.2.0=h4852527_2
  - libuuid=2.38.1=h0b41bf4_0
  - libxcrypt=4.4.36=hd590300_1
  - libzlib=1.3.1=hb9d3cd8_2
  - logbook=1.8.1=py39h8cd3c5a_0
  - mccabe=0.7.0=pyhd8ed1ab_1
  - minimap2=2.1.1=0
  - mypy_extensions=1.0.0=pyha770c72_1
  - mysql-connector-c=6.1.11=h659d440_1008
  - ncurses=6.5=h2d0b736_3
  - nose=1.3.7=py_1006
  - numpy=2.0.2=py39h9cb892a_1
  - openssl=3.4.1=h7b32b05_0
  - packaging=24.2=pyhd8ed1ab_2
  - pathlib=1.0.1=py39hf3d152e_7
  - pathspec=0.12.1=pyhd8ed1ab_1
  - perl=5.32.1=7_hd590300_perl5
  - perl-constant=1.33=pl5321hdfd78af_2
  - perl-exporter=5.72=pl5321hdfd78af_2
  - perl-file-util=4.201720=pl5321hdfd78af_0
  - perl-lib=0.63=pl5321hdfd78af_2
  - pip=25.0.1=pyh8b19718_0
  - platformdirs=4.3.7=pyh29332c3_0
  - pluggy=1.5.0=pyhd8ed1ab_1
  - psutil=7.0.0=py39h8cd3c5a_0
  - pycodestyle=2.12.1=pyhd8ed1ab_1
  - pycparser=2.22=pyh29332c3_1
  - pyfaidx=0.8.1.3=pyhdfd78af_0
  - pyflakes=3.2.0=pyhd8ed1ab_1
  - pysocks=1.7.1=pyha55dd90_7
  - pytest=8.3.5=pyhd8ed1ab_0
  - pytest-cov=6.0.0=pyhd8ed1ab_1
  - python=3.9.21=h9c0c6dc_1_cpython
  - python-dateutil=2.9.0.post0=pyhff2d567_1
  - python_abi=3.9=5_cp39
  - pyvcf3=1.0.3=pyhdfd78af_0
  - pyyaml=6.0.2=py39h9399b63_2
  - readline=8.2=h8c095d6_2
  - represent=1.5.1=py_2
  - requests=2.32.3=pyhd8ed1ab_1
  - setuptools=75.8.2=pyhff2d567_0
  - six=1.17.0=pyhd8ed1ab_0
  - star=2.7.11b=h5ca1c30_5
  - tabix=1.11=hdfd78af_0
  - tk=8.6.13=noxft_h4845f30_101
  - toml=0.10.2=pyhd8ed1ab_1
  - tomli=2.2.1=pyhd8ed1ab_1
  - typing_extensions=4.13.0=pyh29332c3_1
  - tzdata=2025b=h78e105d_0
  - ucsc-bedtogenepred=469=h664eb37_1
  - ucsc-genepredtobed=469=h664eb37_1
  - ucsc-genepredtogtf=469=h664eb37_1
  - ucsc-gff3togenepred=469=h664eb37_1
  - ucsc-gtftogenepred=469=h664eb37_1
  - urllib3=2.3.0=pyhd8ed1ab_0
  - wheel=0.45.1=pyhd8ed1ab_1
  - yaml=0.2.5=h7f98852_2
  - zipp=3.21.0=pyhd8ed1ab_1
  - zlib=1.3.1=hb9d3cd8_2
  - zstandard=0.23.0=py39h8cd3c5a_1
  - zstd=1.5.7=hb8e6e7a_2
  - pip:
      - norns==0.1.6
prefix: /opt/conda/envs/genomepy

tests/04_genome_test.py::test_sizes tests/04_genome_test.py::test_gaps
tests/04_genome_test.py::test__read_metadata
tests/04_genome_test.py::test_genome__init__ tests/04_genome_test.py::test__parse_name tests/04_genome_test.py::test__parse_filename tests/04_genome_test.py::test_check_annotation_file tests/04_genome_test.py::test__update_provider tests/04_genome_test.py::test__update_tax_id tests/04_genome_test.py::test__update_assembly_accession tests/04_genome_test.py::test__update_metadata tests/04_genome_test.py::test__bed_to_seqs tests/04_genome_test.py::test__region_to_seq tests/04_genome_test.py::test__regions_to_seqs tests/04_genome_test.py::test_get_track_type tests/04_genome_test.py::test_track2fasta tests/04_genome_test.py::test__weighted_selection tests/04_genome_test.py::test_get_random_sequences tests/04_genome_test.py::test_delete_test_files
genomepy/genome.py
genomepy/genome.py