Package: recordclass
Recordclass libraryRecordclassisMIT Licensedpython library.
It was started as a "proof of concept" for the problem of fast "mutable"
alternative ofnamedtuple(seequestiononstackoverflow).
It was evolved further in order to provide more memory saving, fast and flexible types.Recordclasslibrary provide record/data-like classes that do not participate in cyclicgarbage collection(GC) mechanism by default, but support onlyreference countingfor garbage collection.
The instances of such classes havn'tPyGC_Headprefix in the memory, which decrease their size and have a little faster path for the instance creation and deallocation.
This may make sense in cases where it is necessary to limit the size of the objects as much as possible, provided that they will never be part of references cycles in the application.
For example, when an object represents a record with fields with values of simple types by convention (int,float,str,date/time/datetime,timedelta, etc.).In order to illustrate this, consider a simple class with type hints:class Point:
    x: int
    y: intBy tacit agreement instances of the classPointis supposed to have attributesxandywith values ofinttype. Assigning other types of values, which are not subclass ofint, should be considered as a violation of the agreement.Other examples are non-recursive data structures in which all leaf elements represent a value of an atomic type.
Of course, in python, nothing prevent you from “shooting yourself in the foot" by creating the reference cycle in the script or application code.
But in many cases, this can still be avoided provided that the developer understands what he is doing and uses such classes in the codebase with care.
Another option is to use static code analyzers along with type annotations to monitor compliance with typehints.The library is built on top of the base classdataobject. The type ofdataobjectis special metaclassdatatype.
It control creation  of subclasses, which  will not participate in cyclic GC and do not containPyGC_Head-prefix,__dict__and__weakref__by default.
As the result the instance of such class need less memory.
It's memory footprint is similar to memory footprint of instances of the classes with__slots__but withoutPyGC_Head. So the difference in memory size is equal to the size ofPyGC_Head.
It also tunesbasicsizeof the instances, creates descriptors for the fields and etc.
All subclasses ofdataobjectcreated byclass statementsupportattrs/dataclasses-like API.
For example:from recordclass import dataobject, astuple, asdict
    class Point(dataobject):
        x:int
        y:int

    >>> p = Point(1, 2)
    >>> astuple(p)
    (1, 2)
    >>> asdict(p)
    {'x':1, 'y':2}Therecordclassfactory create dataobject-based subclass with specified fields and the support ofnamedtuple-like API.
By default it will not participate in cyclic GC too.>>> from recordclass import recordclass
    >>> Point = recordclass('Point', 'x y')
    >>> p = Point(1, 2)
    >>> p.y = -1
    >>> print(p._astuple)
    (1, -1)
    >>> x, y = p
    >>> print(p._asdict)
    {'x':1, 'y':-1}It also provide a factory functionmake_dataclassfor creation of subclasses ofdataobjectwith the specified field names.
These subclasses supportattrs/dataclasses-like API. It's equivalent to creating subclasses of dataobject usingclass statement.
For example:>>> Point = make_dataclass('Point', 'x y')
    >>> p = Point(1, 2)
    >>> p.y = -1
    >>> print(p.x, p.y)
    1 -1If one want to use some sequence for initialization then:>>> p = Point(*sequence)There is also a factory functionmake_arrayclassfor creation of the subclass ofdataobject, which can be considered as a compact array of simple objects.
For example:>>> Pair = make_arrayclass(2)
    >>> p = Pair(2, 3)
    >>> p[1] = -1
    >>> print(p)
    Pair(2, -1)The library provide in addition the classeslightlist(immutable) andlitetuple, which considers as list-like and tuple-likelightcontainers in order to save memory. They do not supposed to participate in cyclic GC too. Mutable variant of litetuple is called bymutabletuple.
For example:>>> lt = litetuple(1, 2, 3)
    >>> mt = mutabletuple(1, 2, 3)
    >>> lt == mt
    True
    >>> mt[-1] = -3
    >>> lt == mt
    False
    >>> print(sys.getsizeof((1,2,3)), sys.getsizeof(litetuple(1,2,3)))
    64 48Note if one like createlitetupleormutabletuplefrom some iterable then:>>> seq = [1,2,3]
    >>> lt = litetuple(*seq)
    >>> mt = mutabletuple(*seq)Memory footprintThe following table explain memory footprints of thedataobject-based objects and litetuples:tuple/namedtupleclass with __slots__recordclass/dataobjectlitetuple/mutabletupleg+b+s+n×pg+b+n×pb+n×pb+s+n×pwhere:b = sizeof(PyObject)s = sizeof(Py_ssize_t)n = number of itemsp = sizeof(PyObject*)g = sizeof(PyGC_Head)This is useful in that case when you absolutely sure that reference cycle isn't supposed.
For example, when all field values are instances of atomic types.
As a result the size of the instance is decreased by 24-32 bytes for cpython 3.4-3.7 and by 16 bytes for cpython >=3.8.Performance countersHere is the table with performance counters, which was measured usingtools/perfcounts.pyscript:recordclass 0.21, python 3.10, debian/testing linux, x86-64:idsizenewgetattrsetattrgetitemsetitemgetkeysetkeyiteratecopylitetuple480.180.20.330.19mutabletuple480.180.210.210.330.18tuple640.240.210.370.16namedtuple640.750.230.210.330.21class+slots560.680.290.33dataobject400.250.230.290.20.220.330.2dataobject+gc560.270.220.290.190.210.350.22dict2320.320.20.240.350.25dataobject+map400.250.230.30.290.290.320.2recordclass 0.21, python 3.11, debian/testing linux, x86-64:idsizenewgetattrsetattrgetitemsetitemgetkeysetkeyiteratecopylitetuple480.110.110.180.09mutabletuple480.110.110.120.180.08tuple640.10.080.170.1namedtuple640.490.130.110.170.13class+slots560.310.060.06dataobject400.130.060.060.110.120.160.12dataobject+gc560.140.060.060.10.120.160.14dict1840.20.120.130.190.13dataobject+map400.120.070.060.150.160.160.12class560.350.060.06recordclas 0.21, python3.12, debian/testing linux, x86-64:idsizenewgetattrsetattrgetitemsetitemgetkeysetkeyiteratecopylitetuple480.130.120.190.09mutabletuple480.130.110.120.180.09tuple640.110.090.160.09namedtuple640.520.130.110.160.12class+slots560.340.080.07dataobject400.140.080.080.110.120.170.12dataobject+gc560.150.080.070.120.120.170.13dict1840.190.110.140.20.12dataobject+map400.140.080.080.160.170.170.12class480.410.080.08Main repository forrecordclassis ongithub.Here is also a simpleexample.More examples can be found in the folderexamples.Quick startInstallationInstallation from directory with sourcesInstall:>>> python3 setup.py installRun tests:>>> python3 test_all.pyInstallation from PyPIInstall:>>> pip3 install recordclassRun tests:>>> python3 -c "from recordclass.test import *; test_all()"Quick start with dataobjectDataobjectis the base class for creation of data classes with fast instance creation and small memory footprint. They providedataclass-like API.First load inventory:>>> from recordclass import dataobject, asdict, astuple, as_dataclass, as_recordDefine class one of the ways:class Point(dataobject):
    x: int
    y: intor@as_dataclass()
class Point:
    x: int
    y: intor@as_record
def Point(x:int, y:int): passor>>> Point = make_dataclass("Point", [("x",int), ("y",int)])or>>> Point = make_dataclass("Point", {"x":int, "y",int})Annotations of the fields are defined as a dict in__annotations__:>>> print(Point.__annotations__)
{'x': <class 'int'>, 'y': <class 'int'>}There is default text representation:>>> p = Point(1, 2)
>>> print(p)
Point(x=1, y=2)The instances has a minimum memory footprint that is possible for CPython object, which contain only Python objects:>>> sys.getsizeof(p) # the output below for python 3.8+ (64bit)
40
>>> p.__sizeof__() == sys.getsizeof(p) # no additional space for cyclic GC support
TrueThe instance is mutable by default:>>> p_id = id(p)
>>> p.x, p.y = 10, 20
>>> id(p) == p_id
True
>>> print(p)
Point(x=10, y=20)There are functionsasdictandastuplefor converting todictand totuple:>>> asdict(p)
{'x':10, 'y':20}
>>> astuple(p)
(10, 20)By default subclasses of dataobject are mutable. If one want make it immutable then there is the optionreadonly=True:class Point(dataobject, readonly=True):
    x: int
    y: int

>>> p = Point(1,2)
>>> p.x = -1
. . . . . . . . . . . . .
TypeError: item is readonlyBy default subclasses of dataobject are not iterable by default.
If one want make it iterable then there is the optioniterable=True:class Point(dataobject, iterable=True):
    x: int
    y: int

>>> p = Point(1,2)
>>> for x in p: print(x)
1
2Default values are also supported::class CPoint(dataobject):
    x: int
    y: int
    color: str = 'white'or>>> CPoint = make_dataclass("CPoint", [("x",int), ("y",int), ("color",str)], defaults=("white",))

>>> p = CPoint(1,2)
>>> print(p)
Point(x=1, y=2, color='white')Butclass PointInvalidDefaults(dataobject):
    x:int = 0
    y:intis not allowed. A fields without default value may not appear after a field with default value.There is an optioncopy_default(starting from 0.21) in order to assign a copy of the default value when creating an instance:class Polygon(dataobject, copy_default=True):
    points: list = []

>>> pg1 = Polygon()
>>> pg2 = Polygon()
>>> assert pg1.points == pg2.points
True
>>> assert id(pg1.points) != id(pg2.points)
TrueAFactory(starting from 0.21) allows you to setup a factory function to calculate the default value:from recordclass import Factory

class A(dataobject, copy_default=True):
    x: tuple = Factory( lambda: (list(), dict()) )

>>> a = A()
>>> b = A()
>>> assert a.x == b.x
True
>>> assert id(a.x[0]) != id(b.x[0])
True
>>> assert id(a.x[1]) != id(b.x[1])
TrueIf someone wants to define a class attribute, then there is aClassVartrick:class Point(dataobject):
    x:int
    y:int
    color:ClassVar[int] = 0

>>> print(Point.__fields__)
('x', 'y')
>>> print(Point.color)
0If the default value for theClassVar-attribute is not specified,
it will just be excluded from the__fields___.Starting with python 3.10__match_args__is specified by default so that__match_args__==__fields.
User can define it's own during definition:class User(dataobject):
    first_name: str
    last_name: str
    age: int
    __match_args__ = 'first_name', 'last_name'orfrom recordclass import MATCH
class User(dataobject):
    first_name: str
    last_name: str
    _: MATCH
    age: intorUser = make_dataclass("User", "first_name last_name * age")Quick start with recordclassTherecordclassfactory function is designed to create classes that supportnamedtuple's API, can be mutable and immutable, provide fast creation of the instances and have a minimum memory footprint.First load inventory:>>> from recordclass import recordclassExample withrecordclass:>>> Point = recordclass('Point', 'x y')
>>> p = Point(1,2)
>>> print(p)
Point(1, 2)
>>> print(p.x, p.y)
1 2
>>> p.x, p.y = 1, 2
>>> print(p)
Point(1, 2)
>>> sys.getsizeof(p) # the output below is for 64bit cpython3.8+
32Example with class statement and typehints:>>> from recordclass import RecordClass

class Point(RecordClass):
   x: int
   y: int

>>> print(Point.__annotations__)
{'x': <class 'int'>, 'y': <class 'int'>}
>>> p = Point(1, 2)
>>> print(p)
Point(1, 2)
>>> print(p.x, p.y)
1 2
>>> p.x, p.y = 1, 2
>>> print(p)
Point(1, 2)By defaultrecordclass-based class instances doesn't participate in cyclic GC and therefore they are smaller thannamedtuple-based ones. If one want to use it in scenarios with reference cycles then one have to use optiongc=True(gc=Falseby default):>>> Node = recordclass('Node', 'root children', gc=True)orclass Node(RecordClass, gc=True):
     root: 'Node'
     chilren: listTherecordclassfactory can also specify type of the fields:>>> Point = recordclass('Point', [('x',int), ('y',int)])or>>> Point = recordclass('Point', {'x':int, 'y':int})Using dataobject-based classes with mapping protocolclass FastMapingPoint(dataobject, mapping=True):
    x: int
    y: intorFastMapingPoint = make_dataclass("FastMapingPoint", [("x", int), ("y", int)], mapping=True)

>>> p = FastMappingPoint(1,2)
>>> print(p['x'], p['y'])
1 2
>>> sys.getsizeof(p) # the output below for python 3.10 (64bit)
32Using dataobject-based classes for recursive data without reference cyclesThere is the optiondeep_dealloc(default value isFalse) for deallocation of recursive datastructures.
Let consider simple example:class LinkedItem(dataobject):
    val: object
    next: 'LinkedItem'

class LinkedList(dataobject, deep_dealloc=True):
    start: LinkedItem = None
    end: LinkedItem = None

    def append(self, val):
        link = LinkedItem(val, None)
        if self.start is None:
            self.start = link
        else:
            self.end.next = link
        self.end = linkWithoutdeep_dealloc=Truedeallocation of the instance ofLinkedListwill be failed if the length of the linked list is too large.
But it can be resolved with__del__method for clearing the linked list:def __del__(self):
    curr = self.start
    while curr is not None:
        next = curr.next
        curr.next = None
        curr = nextThere is builtin more fast deallocation method using finalization mechanizm whendeep_dealloc=True. In such case one don't need__del__method for clearing the linked list.Note that for classes withgc=Truethis method is disabled: the python's cyclic GC is used in these cases.For more details see notebookexample_datatypes.Changes:0.21.1Allow to specify__match_args__. For example,class User(dataobject):
       first_name: str
       last_name: str
       age: int
       __match_args__ = 'first_name', 'last_name'orUser = make_dataclass("User", "first_name last_name * age")Add@as_recordadapter fordef-style decalarations of dataclasses
that are considered as just a struct. For example:@as_record()
  def Point(x:float, y:float, meta=None): pass

  >>> p = Point(1,2)
  >>> print(p)
  Point(x=1, y=2, meta=None)It's almost equivalent to:Point = make_dataclass('Point', [('x':float), ('y',float),'meta'], (None,))The optionfast_newwill be removed in 0.22. It will be always asfast_new=Trueby creation.class Point(dataobject):
      x:int
      y:int

      def __new__(cls, x=0, y=0):
           return dataobject.__new__(cls, x, y)Fix issues with_PyUnicodeWriterfor python3.13.0.21Add a new optioncopy_default(defaultFalse) to allow assigning a copy of the default
value for the field. For example:class A(dataobject, copy_default=True):
      l: list = []

 a = A()
 b = A()
 assert(a.l == b.l)
 assert(id(a.l) != id(b.l))Allow to inherit the options:copy_default,gc,iterable. For example:class Base(dataobject, copy_default=True):
    pass

class A(Base):
      l: list = []

 a = A()
 b = A()
 assert a.l == b.l
 assert id(a.l) != id(b.l)AddFactoryto specify factory function for default values. For example:from recordclass import Factory
  class A(dataobject):
      x: tuple = Factory(lambda: (list(), dict()))

  a = A()
  b = A()
  assert a.x == ([],{})
  assert id(a.x) != id(b.x)
  assert id(a.x[0]) != id(b.x[0])
  assert id(a.x[1]) != id(b.x[1])

  from recordclass import Factory
  class A(dataobject, copy_default=True):
      l: list = []
      x: tuple = Factory(lambda: (list(), dict()))

  a = A()
  b = A()
  assert a.x == ([],{})
  assert id(a.x) != id(b.x)
  assert a.l == []
  assert id(a.l) != id(b.l)Recordclass supports python 3.12 (tested on linux/debian 11/12 and windows via appveyor).0.20.1Improve row_factory forsqliteon the ground ofdataobject-based classes.Move recordclass repository togithubfrombitbucket.0.20Library codebase is compatible with python 3.12
(tested for linux only, windows until python3.12 support on appveyor).Fix error with update of readonly attribute viaupdatefunction.0.19.2Exception message for Cls(**kwargs) with invalid kweyword argument is more precise (#37).Add parameterimmutable_typefor python >= 3.11. Ifimmutable_type=Truethen a generated class
(not an instance) will be immutable. If class do not contain user defuned__init__and__new__then instance creation will be faster (via vectorcall protocol).0.19.1Fix regression withC.attr=value(with immutable class by default).0.19Add vectorcall protocal tolitetupleandmutabletuple.Add vectorcall protocal todataobject.Now dataobject'sop.__hash__returnid(op)by default.
The optionhashable=Truemake dataobject hashably by value.Nowdataobject-based classes,litetupleandmutabletupleare support
bytecode specializations since Python 3.11 for instance creation and for getattr/setattr.Fixmakefunction for cases, when subclass have nontrivial__init__.Note fordataobject-based subclasses with non-trivial__init__one may want define also__reduce__.
For example:def __reduce__(self):
  from recordclass import dataobject, make
  tp, args = dataobject.__reduce__(self)
  return make, (tp, args)0.18.4Fix a bug #35 with duplicating the field name during inheritance and mixing it with class level attributes.Allow use of ClassVar to define class level field.0.18.3Fix bug with a tuple as default value of the field.Fix defaults propagtion to subclasses.Fix some issues with pickling in the context of dill.0.18.2Slightly improve performance in the default__init__when fields have default values or kwargs.Remove experimental pypy support: slow and difficult to predict memory footprint.Exclude experimental cython modules.0.18.1.1Repackage 0.18.1 withuse_cython=00.18.1Allow to initialize fields in the user defined__init__method instead of__new__(issue 29).
If__init__is defined by user then it's responsible for initialization of all fields.
Note that this feature only work for mutable fields.
Instances of the class withreadonly=Truemust be initialized only in the default__new__.
For example:class A(dataobject):
        x:int
        y:int

        def __init__(self, x, y):
            self.x = x
            self.y = yfast_new=Trueby default.Addmake_row_factoryforsqlite3:class Planet(dataobject):
      name:str
      radius:int

  >>> con = sql.connect(":memory:")
  >>> cur = con.execute("SELECT 'Earth' AS name, 6378 AS radius")
  >>> cur.row_factory = make_row_factory(Planet)
  >>> row = cur.fetchone()
  >>> print(row)
  Planet(name='Earth', radius=6378)0.18.0.1Exclude test_dataobject_match.py (for testingmatchstatement) for python < 3.10.0.18Python 3.11 support.Adapt data object to take benefit from bytecode specialization in 3.11.Fix issue for argument with default value in__new__, which havn't__repr__that can be interpreted as valid python expression
for creation of the default value.Add support for typing.ClassVar.AddPy_TPFLAGS_SEQUENCEandPy_TPFLAGS_MAPPING.Add__match_args__to support match protocol for dataobject-based subclasses.0.17.5Make to compile, to build and to test successfully for python 3.11.0.17.4Fixed error with missing_PyObject_GC_Mallocin 3.11.0.17.3Fix compatibility issue: restore gnu98 C-syntax.Fix remained issues with use of "Py_SIZE(op)" and "Py_TYPE(op)" as l-value.0.17.2Add support for python 3.10.There are no use of "Py_SIZE(op)" and "Py_TYPE(op)" as l-value.0.17.1Fix packaging issue with cython=1 in setup.py0.17Now recordclass library may be compiled for pypy3, but there is still no complete runtime compatibility with pypy3.Slighly imporove performance oflitetuple/mutabletuple.Slighly imporove performance ofdataobject-based subclasses.Add adapteras_dataclass. For example:@as_dataclass()
  class Point:
      x:int
      y:intModule _litelist is implemented in pure C.Make dataobject.copyfaster.0.16.3Add possibility for recordclasses to assighn values by key:A = recordclass("A", "x y", mapping=True)
  a = A(1,2)
  a['x'] = 100
  a['y'] = 2000.16.2Fix the packaging bug in 0.16.1.0.16.1Adddictclassfactory function to generate class withdict-likeAPI and without attribute access to the fields.
Features: fast instance creation, small memory footprint.0.16RecordClassstarted to be a direct subclass of dataobject withsequence=Trueand support
ofnamedtuple-like API.
Insted ofRecordClass(name, fields, **kw)for class creation
use factory functionrecordclass(name, fields, **kw)(it allows to specify types).Add option api='dict'  tomake_dataclassfor creating class that support dict-like API.Now one can't remove dataobject's property from it's class using del or builting delattr.
For example:>>> Point = make_dataclass("Point", "x y")
  >>> del Point.x
  ...........
  AttributeError: Attribute x of the class Point can't be deletedNow one can't delete field's value using del or builting delattr.
For example:>>> p = Point(1, 2)
  >>> del p.x
  ...........
  AttributeError: The value can't be deleted"Insted one can use assighnment to None:>>> p = Point(1, 2)
  >>> p.x = NoneSlightly improve performance of the access by index of dataobject-based classes with optionsequence=True.0.15.1Optionsreadonlyanditerablenow can be sspecified via keyword arguments in class statement.
For example:class Point(dataobject, readonly=True, iterable=True):
       x:int
       y:intAddupdate(cls, **kwargs)function to update attribute values.`0.15Now library supports only Python >= 3.6'gc' and 'fast_new' options now can be specified as kwargs in class statement.Add a functionastuple(ob)for transformation dataobject instanceobto a tuple.Drop datatuple based classes.Add functionmake(cls, args, **kwargs)to create instance of the classcls.Add functionclone(ob, **kwargs)to clone dataobject instanceob.Make structclass as alias of make_dataclass.Add option 'deep_dealloc' (@clsconfig(deep_dealloc=True)) for deallocation
instances of dataobject-based recursive subclasses.0.14.3:Subclasses ofdataobjectnow support iterable and hashable protocols by default.0.14.2:Fix compilation issue for python 3.9.0.14.1:Fix issue withhashwhen subclassing recordclass-based classes.0.14:Adddocto generateddataobject-based class in order to supportinspect.signature.Addfast_newargument/option for fast instance creation.Fix refleak inlitelist.Fix sequence protocol ability fordataobject/datatuple.Fix typed interface forStructClass.0.13.2Fix issue #14 with deepcopy of dataobjects.0.13.1Restore ``join_classesand add new functionjoin_dataclasses`.0.13.0.1Remove redundant debug code.0.13Makerecordclasscompiled and work with cpython 3.8.Move repository togitinstead of mercurial since bitbucket will drop support of mercurial repositories.Fix some potential reference leaks.0.12.0.1Fix missing .h files.0.12clsconfignow become the main decorator for tuning dataobject-based classes.Fix concatenation of mutabletuples (issue#10).0.11.1:dataobjectinstances may be deallocated faster now.0.11:Renamememoryslotstomutabletuple.mutabletupleandimmutabletupledosn't participate in cyclic garbage collection.Addlitelisttype for list-like objects, which doesn't participate in cyglic garbage collection.0.10.3:Introduce DataclassStorage and RecordclassStorage.
They allow cache classes and used them without creation of new one.Additerabledecorator and argument. Now dataobject with fields isn't iterable by default.Moveastupletodataobject.c.0.10.2Fix error with dataobject's__copy__.Fix error with pickling of recordclasses and structclasses, which was appeared since 0.8.5
(Thanks to Connor Wolf).0.10.1Now by default sequence protocol is not supported by default if dataobject has fields,
but iteration is supported.By default argsonly=False for usability reasons.0.10Invent new factory functionmake_classfor creation of different kind of dataobject classes
without GC support by default.Invent new metaclassdatatypeand new base classdataobjectfor creation dataobject class usingclassstatement.
It have disabled GC support, but could be enabled by decoratordataobject.enable_gc.
It support type hints (for python >= 3.6) and default values.
It may not specify sequence of field names in__fields__when type hints are applied to all
data attributes (for python >= 3.6).Nowrecordclass-based classes may not support cyclic garbage collection too.
This reduces the memory footprint by the size ofPyGC_Head.
Now by default recordclass-based classes doesn't support cyclic garbage collection.0.9Change version to 0.9 to indicate a step forward.Cleanupdataobject.__cinit__.0.8.5Makearrayclass-based objects support setitem/getitem andstructclass-based objects able
to not support them. By default, as beforestructclass-based objects support setitem/getitem protocol.Now only instances ofdataobjectare comparable to 'arrayclass'-based andstructclass-based instances.Now generated classes can be hashable.0.8.4Improve support for readonly mode for structclass and arrayclass.Add tests for arrayclass.0.8.3Add typehints support to structclass-based classes.0.8.2Removeusedict,gc,weaklistfrom the class__dict__.0.8.1Remove Cython dependence by default for buildingrecordclassfrom the sources [Issue #7].0.8Addstructclassfactory function. It's analog ofrecordclassbut with less memory
footprint for it's instances (same as for instances of classes with__slots__) in the camparison
withrecordclassandnamedtuple(it currently implemented withCython).Addarrayclassfactory function which produce a class for creation fixed size array.
The benefit of such approach is also less memory footprint
(it currently currently implemented withCython).structclassfactory has argumentgcnow. Ifgc=False(by default) support of cyclic garbage collection
will switched off for instances of the created class.Add functionjoin(C1, C2)in order to join twostructclass-based classes C1 and C2.Addsequenceproxyfunction for creation of immutable and hashable proxy object from class instances,
which implement access by index
(it currently currently implemented withCython).Add support for access to recordclass object attributes by idiom:ob['attrname'](Issue #5).Add argumentreadonlyto recordclass factory to produce immutable namedtuple.
In contrast tocollection.namedtupleit use same descriptors as for
regular recordclasses for performance increasing.0.7Make mutabletuple objects creation faster. As a side effect: when number of fields >= 8
recordclass instance creation time is not biger than creation time of instaces of
dataclasses with__slots__.Recordclass factory function now create new recordclass classes in the same way as namedtuple in 3.7
(there is no compilation of generated python source of class).0.6Add support for default values in recordclass factory function in correspondence
to same addition to namedtuple in python 3.7.0.5Change version to 0.50.4.4Add support for default values in RecordClass (patches from Pedro von Hertwig)Add tests for RecorClass (adopted from python tests for NamedTuple)0.4.3Add support for typing for python 3.6 (patches from Vladimir Bolshakov).Resolve memory leak issue.0.4.2Fix memory leak in property getter/setter