Skip to content

Loading…

Tweaks to _AltRecord for possible multiple inheritance #64

Merged
merged 3 commits into from

3 participants

@lennax

A few minor changes to the inheritance pattern of _AltRecord and children. super() needs to be called even for objects that inherit from object to allow multiple inheritance, and every class passing **kwargs allows mixing of subclasses with custom args.

Also made AltRecord into an abstract base class to enforce overloading of `__str_`.

An example of multiple inheritance I can imagine in this context would be, for example, a class UnknownLoc that could be combined with a variety of Alt types. Rough example: https://gist.github.com/3029028

References about use of super:
Praise: http://rhettinger.wordpress.com/2011/05/26/super-considered-super/
Caution: https://fuhm.net/super-harmful/

@lennax

I'll tack on a third commit:

The super() call in Reader still refers to the legacy VCFReader. It appears to work, but I changed it just to be sure. The pre-3 requirement of explicit declaration of the class name and self as args to super() is frustrating...

Also changed method parseALT to _parse_alt for pep8/consistent style.

@jamescasbon jamescasbon merged commit 6e91990 into jamescasbon:master
@superbobry

Maybe a constructor can be removed, since it doesn't have anything else besides a super call?

The constructor passes an arg to the superclass. Also, the rest of the classes in the project use super(), and my goal here was to allow for possible multiple inheritance. I provided some examples and links in pull request 64.

@superbobry

Why CamelCase for keyword arguments, when most of the code uses pythonic under_score?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Jul 1, 2012
  1. @lennax

    Made _AltRecord into ABC.

    lennax committed
  2. @lennax
Commits on Jul 2, 2012
  1. @lennax

    Fix Reader super call; pep8.

    lennax committed
Showing with 18 additions and 14 deletions.
  1. +15 −11 vcf/model.py
  2. +3 −3 vcf/parser.py
View
26 vcf/model.py
@@ -1,3 +1,4 @@
+from abc import ABCMeta, abstractmethod
import collections
import sys
@@ -408,13 +409,16 @@ def is_monomorphic(self):
class _AltRecord(object):
'''An alternative allele record: either replacement string, SV placeholder, or breakend'''
+ __metaclass__ = ABCMeta
- def __init__(self, type):
+ def __init__(self, type, **kwargs):
+ super(_AltRecord, self).__init__(**kwargs)
#: String to describe the type of variant, by default "SNV" or "MNV", but can be extended to any of the types described in the ALT lines of the header (e.g. "DUP", "DEL", "INS"...)
self.type = type
+ @abstractmethod
def __str__(self):
- assert False, "_AltRecord is an abstract class, you should be using a subclass instead"
+ raise NotImplementedError
def __eq__(self, other):
return self.type == other.type
@@ -423,11 +427,11 @@ def __eq__(self, other):
class _Substitution(_AltRecord):
'''A basic ALT record, where a REF sequence is replaced by an ALT sequence'''
- def __init__(self, nucleotides):
+ def __init__(self, nucleotides, **kwargs):
if len(nucleotides) == 1:
- super(_Substitution, self).__init__("SNV")
+ super(_Substitution, self).__init__(type="SNV", **kwargs)
else:
- super(_Substitution, self).__init__("MNV")
+ super(_Substitution, self).__init__(type="MNV", **kwargs)
#: Alternate sequence
self.sequence = str(nucleotides)
@@ -450,8 +454,8 @@ def __eq__(self, other):
class _Breakend(_AltRecord):
'''A breakend which is paired to a remote location on or off the genome'''
- def __init__(self, chr, pos, orientation, remoteOrientation, connectingSequence, withinMainAssembly):
- super(_Breakend, self).__init__("BND")
+ def __init__(self, chr, pos, orientation, remoteOrientation, connectingSequence, withinMainAssembly, **kwargs):
+ super(_Breakend, self).__init__(type="BND", **kwargs)
#: The chromosome of breakend's mate.
self.chr = str(chr)
#: The coordinate of breakend's mate.
@@ -499,15 +503,15 @@ def __eq__(self, other):
class _SingleBreakend(_Breakend):
'''A single breakend'''
- def __init__(self, orientation, connectingSequence):
- super(_SingleBreakend, self).__init__(None, None, orientation, None, connectingSequence, None)
+ def __init__(self, orientation, connectingSequence, **kwargs):
+ super(_SingleBreakend, self).__init__(None, None, orientation, None, connectingSequence, None, **kwargs)
class _SV(_AltRecord):
'''An SV placeholder'''
- def __init__(self, type):
- super(_SV, self).__init__(type)
+ def __init__(self, type, **kwargs):
+ super(_SV, self).__init__(type, **kwargs)
def __str__(self):
return "<" + self.type + ">"
View
6 vcf/parser.py
@@ -179,7 +179,7 @@ def __init__(self, fsock=None, filename=None, compressed=False, prepend_chr=Fals
or files are attempted to be recogized by the file extension, or gzipped
can be forced with ``compressed=True``
"""
- super(VCFReader, self).__init__()
+ super(Reader, self).__init__()
if not (fsock or filename):
raise Exception('You must provide at least fsock or filename')
@@ -405,7 +405,7 @@ def _parse_samples(self, samples, samp_fmt, site):
return samp_data
- def parseALT(self, str):
+ def _parse_alt(self, str):
if re.search('[\[\]]', str) is not None:
# Paired breakend
items = re.split('[\[\]]', str)
@@ -448,7 +448,7 @@ def next(self):
ID = None
ref = row[3]
- alt = self._map(self.parseALT, row[4].split(','))
+ alt = self._map(self._parse_alt, row[4].split(','))
try:
qual = int(row[5])
Something went wrong with that request. Please try again.