Re: Configuring an object via a dictionary

2024-03-18 Thread Anders Munch via Python-list
dn wrote:
>Loris Bennett wrote:
>> However, with a view to asking forgiveness rather than
>> permission, is there some simple way just to assign the dictionary
>> elements which do in fact exist to self-variables?
>
>Assuming config is a dict:
>
>   self.__dict__.update( config )

Here's another approach:

config_defaults = dict(
 server_host='localhost',
 server_port=443,
# etc.
)
...
def __init__(self, config):
self.conf = types.SimpleNamespace(**{**config_defaults, **config})

This gives you defaults, simple attribute access, and avoids the risk of name 
collisions that you get when updating __dict__.

Using a dataclass may be better:

@dataclasses.dataclass
class Settings:
 group_base : str
 server_host : str = 'localhost'
 server_port : int = 443
...
def __init__(self, config):
self.conf = Settings(**config)

regards, Anders

-- 
https://mail.python.org/mailman/listinfo/python-list


RE: super().__init__() and bytes

2024-12-03 Thread Anders Munch via Python-list
Roel Schroeven  wrote:
> As a follow-up, it looks like this behavior is because bytes and int are 
> immutable.

Yes.

> But that doesn't tell me why using super().__init__() 
> doesn't work for immutable classes.

bytes.__init__ does work, but it's just an inherited object.__init__, which 
does nothing, and takes no parameters.
 __init__ cannot change the value of the bytes object; the value is set by 
bytes.__new__ and cannot change after that.

Best not to define an __init__ method at all, just use __new__.

Something like:

class BytesSubclass(bytes):
def __new__(cls, whatever, arguments, you, like):
bytesvalue = compute(whatever, arguments, you, like)
ob = bytes.__new__(cls, bytesvalue)
ob.some_other_att = compute_something_else(whatever, arguments, you, 
like)
return ob

regards, 
Anders

-- 
https://mail.python.org/mailman/listinfo/python-list


RE: Module urljoin does not appear to work with scheme Gemini

2025-04-24 Thread Anders Munch via Python-list
Henry S. Thompson wrote:
> Some approach to support future-proofing in general would seem to be in 
> order. 
> Given some other precedents, adding a boolean argument called either 'strict' 
> or 'lax' would be my preference.

An alternative would be to refactor urllib.parse to use strategy objects
for schemes.

parse.py contains a number of lists of scheme names, that act as flags to
control parsing behaviour:
uses_relative, uses_netloc, uses_params, non_hierarchical, uses_query 
and uses_fragment.
(If written today they would be sets, but this is very old code that predates 
sets!)
Group that information by scheme instead of by flag name, in e.g. a dataclass, 
and
you have made yourself a strategy object lookup table:

scheme_options = {
   'https': SchemeOptions(uses_relative=True,  uses_netloc=True, 
uses_params=True),
   'git': SchemeOptions(uses_relative=False,  uses_netloc=True, 
uses_params=False),
   ...
}

Once you have that, you can add the strategy object as an optional argument to
functions.  If the argument is not given, you find a strategy object from
scheme_options to use. If the argument is given, you use that.

The best part of this approach is that you now have a way of saying "treat this
scheme exactly like https":

   from urllib import parse
   parse.urljoin('sptth://...', '../one-level-up', 
options=parse.scheme_options['https'])

Note: I wrote this before I realised that the lists non_hierarchical, uses_query
and uses_fragment are not used.  With only three options instead of six, making
a strategy object is not quite as attractive.  But still worth considering.

regards, Anders 
-- 
https://mail.python.org/mailman/listinfo/python-list