Coverage for sources/frigid/namespaces.py: 100%
22 statements
« prev ^ index » next coverage.py v7.6.12, created at 2025-03-05 03:33 +0000
« prev ^ index » next coverage.py v7.6.12, created at 2025-03-05 03:33 +0000
1# vim: set filetype=python fileencoding=utf-8:
2# -*- coding: utf-8 -*-
4#============================================================================#
5# #
6# Licensed under the Apache License, Version 2.0 (the "License"); #
7# you may not use this file except in compliance with the License. #
8# You may obtain a copy of the License at #
9# #
10# http://www.apache.org/licenses/LICENSE-2.0 #
11# #
12# Unless required by applicable law or agreed to in writing, software #
13# distributed under the License is distributed on an "AS IS" BASIS, #
14# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. #
15# See the License for the specific language governing permissions and #
16# limitations under the License. #
17# #
18#============================================================================#
21# pylint: disable=line-too-long
22''' Immutable namespaces.
24 Provides a namespace type with immutable attributes. Similar to
25 :py:class:`types.SimpleNamespace`, but attributes cannot be modified or
26 deleted after initialization.
28 The namespace implementation is modeled after
29 :py:class:`types.SimpleNamespace` but adds immutability. Like
30 :py:class:`types.SimpleNamespace`, it provides a simple ``__repr__`` which
31 lists all attributes.
33 >>> from frigid import Namespace
34 >>> ns = Namespace( x = 1, y = 2 )
35 >>> ns.z = 3 # Attempt to add attribute
36 Traceback (most recent call last):
37 ...
38 frigid.exceptions.AttributeImmutabilityError: Cannot assign or delete attribute 'z'.
39 >>> ns.x = 4 # Attempt modification
40 Traceback (most recent call last):
41 ...
42 frigid.exceptions.AttributeImmutabilityError: Cannot assign or delete attribute 'x'.
43 >>> ns
44 frigid.namespaces.Namespace( x = 1, y = 2 )
45'''
46# pylint: enable=line-too-long
49from . import __
50from . import objects as _objects
53class Namespace( _objects.Object ): # pylint: disable=eq-without-hash
54 ''' Immutable namespaces. '''
56 def __init__(
57 self,
58 *iterables: __.DictionaryPositionalArgument[ __.H, __.V ],
59 **attributes: __.DictionaryNominativeArgument[ __.V ],
60 ) -> None:
61 self.__dict__.update(
62 __.ImmutableDictionary( *iterables, **attributes ) ) # type: ignore
63 super( ).__init__( )
65 def __repr__( self ) -> str:
66 attributes = ', '.join(
67 f"{key} = {value!r}" for key, value
68 in super( ).__getattribute__( '__dict__' ).items( ) )
69 fqname = __.calculate_fqname( self )
70 if not attributes: return f"{fqname}( )"
71 return f"{fqname}( {attributes} )"
73 def __eq__( self, other: __.typx.Any ) -> __.ComparisonResult:
74 mydict = super( ).__getattribute__( '__dict__' )
75 if isinstance( other, ( Namespace, __.types.SimpleNamespace ) ):
76 return mydict == other.__dict__
77 return NotImplemented
79 def __ne__( self, other: __.typx.Any ) -> __.ComparisonResult:
80 mydict = super( ).__getattribute__( '__dict__' )
81 if isinstance( other, ( Namespace, __.types.SimpleNamespace ) ):
82 return mydict != other.__dict__
83 return NotImplemented
85Namespace.__doc__ = __.generate_docstring(
86 Namespace, 'description of namespace', 'instance attributes immutability' )