Skip to content

Commit

Permalink
implement new constant metaclass and test it, too! close: #89
Browse files Browse the repository at this point in the history
  • Loading branch information
examachine committed Feb 22, 2017
1 parent 3545487 commit 46624c9
Show file tree
Hide file tree
Showing 3 changed files with 74 additions and 9 deletions.
6 changes: 4 additions & 2 deletions pisi/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,11 @@
# Author: Baris Metin <[email protected]

"""PISI constants.
If you have a "magic" constant value this is where it should be
If you have a 'magic' constant value this is where it should be
defined."""

#TODO: FIXME: this singleton pattern looks awful on the eyes

import gettext
__trans = gettext.translation('pisi', fallback=True)
_ = __trans.ugettext
Expand All @@ -41,7 +43,7 @@ def __delattr__(self, name):
raise NameError, name

class Constants:
"Pisi Constants Singleton"
"PISI Constants Singleton"

__c = _constant()

Expand Down
63 changes: 56 additions & 7 deletions pisi/oo.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,25 @@
# -*- coding: utf-8 -*-
#
# This program is free software; you can redistribute it and/or modify it under
# the terms of the GNU General Public License as published by the Free
# Software Foundation; either version 3 of the License, or (at your option)
# any later version.
#
# Please read the COPYING file.
#
# Author: Eray Ozkural <[email protected]>
#
"""Guido's cool metaclass examples. Fair use. Ahahah.
Hacked a little based on stuff I saw elsewhere.
I find these quite handy. Use them :) -- Eray Ozkural"""

# Guido's cool metaclass examples. fair use. ahahah.
# I find these quite handy. Use them :)
import gettext
__trans = gettext.translation('pisi', fallback=True)
_ = __trans.ugettext

class autoprop(type):
'''A metaclass for automatic property creation based on
accessor/modifier methods'''
def __init__(cls, name, bases, dict):
super(autoprop, cls).__init__(name, bases, dict)
props = {}
Expand All @@ -18,23 +32,58 @@ def __init__(cls, name, bases, dict):
setattr(cls, name, property(fget, fset))

class autosuper(type):
'''A metaclass that gives you an automatic attribute of self.super'''
def __init__(cls, name, bases, dict):
super(autosuper, cls).__init__(name, bases, dict)
setattr(cls, "_%s__super" % name, super(cls))

class autosuprop(autosuper, autoprop):
'''A metaclass that combines the autosuper and autoprop classes'''
pass

class autoeq(type):
"useful for structures"
'''A metaclass that gives an automatic comparison operator that
may be useful when hacking data structures'''
def __init__(cls, name, bases, dict):
super(autoeq, cls).__init__(name, bases, dict)
def equal(self, other):
return self.__dict__ == other.__dict__
cls.__eq__ = equal

class Struct:
__metaclass__ = autoeq
#class Struct:
# __metaclass__ = autoeq
#
# def __init__(self, **entries):
# self.__dict__.update(entries)

# Snippet by Peter Mortensen
class singleton(type):
"A metaclass for a perfect implementation of the singleton design pattern, there is a single global instance, and no new instances are ever created."
_instances = {}
def __call__(cls, *args, **kwargs):
if cls not in cls._instances:
cls._instances[cls] = super(Singleton, cls).__call__(*args, **kwargs)
return cls._instances[cls]


class ConstError(TypeError):
pass

class constant(type):
"Constant attribute metaclass"

def __init__(self, **entries):
self.__dict__.update(entries)
def __init__(cls, name, bases, dict):
super(constant, cls).__init__(name, bases, dict)
def __setattr__(self, name, value):
if self.__dict__.has_key(name):
raise ConstError, _("Can't rebind constant: %s") % name
# Binding an attribute once to a const is available
self.__dict__[name] = value
cls.__setattr__ = __setattr__

def __delattr__(self, name):
if self.__dict__.has_key(name):
raise ConstError, _("Can't unbind constant: %s") % name
# we don't have an attribute by this name
raise NameError, name
cls.__delattr__ = __delattr__
14 changes: 14 additions & 0 deletions tests/ootests.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,5 +36,19 @@ def meth(self):

self.assert_( D().meth() == "DCBA" )

def testautoconstant(self):
class A:
__metaclass__ = constant
def __init__(self):
self.a = 1
self.b = 2
mya = A()
try:
passed = False
mya.a = 0
except ConstError, e:
passed = True
self.assert_(passed)

suite = unittest.makeSuite(OOTestCase)

0 comments on commit 46624c9

Please sign in to comment.