Mailing List Archive

for a 'good python'
Hi everyone,
some time ago I wrote a class to determine if an ipv4 address belonged
to a subnet. Seldom using python I'm pretty sure it's not written in
'good python' nor too portable. Could you give me some advice to make it
better?

class calcip:
def __init__(self, psubnet: str):
ssubnet, scidr = psubnet.replace(' ', '').split('/')
subnet = int.from_bytes(tuple(
map(lambda n: (int(n)),
ssubnet.split('.'))),
'big')
cidr = int(scidr)
mask = ((2 ** cidr) - 1) << (32 - cidr)
self.__network = subnet & mask
self.__wildcard = ~mask & 0xffffffff
self.__broadcast = (subnet | self.__wildcard) & 0xffffffff
self.__tsubnet = tuple(subnet.to_bytes(4, 'big'))
self.__tnetwork = tuple(self.__network.to_bytes(4, 'big'))
self.__tbroadcast = tuple(self.__broadcast.to_bytes(4, 'big'))
self.__tmask = tuple(mask.to_bytes(4, 'big'))
self.__twildcard = tuple(self.__wildcard.to_bytes(4, 'big'))
self.__host_min = tuple((self.__network + 1).to_bytes(4, 'big'))
self.__host_max = tuple((self.__broadcast - 1).to_bytes(4, 'big'))

@staticmethod
def __to_str(val: tuple):
return '.'.join(str(v) for v in val)

@property
def subnet(self):
return self.__to_str(self.__tsubnet)

@property
def network(self):
return self.__to_str(self.__tnetwork)

@property
def broadcast(self):
return self.__to_str(self.__tbroadcast)

@property
def mask(self):
return self.__to_str(self.__tmask)

@property
def wildcard(self):
return self.__to_str(self.__twildcard)

@property
def host_min(self):
return self.__to_str(self.__host_min)

@property
def host_max(self):
return self.__to_str(self.__host_max)

@property
def hosts_num(self):
return self.__wildcard - 1

@property
def net_class(self):
tst = (self.__tnetwork[0] & 0xf0) >> 4
if (tst & 0x8) == 0:
clx = 'A'
elif (tst & 0xc) == 0x8:
clx = 'B'
elif (tst & 0xe) == 0xc:
clx = 'C'
elif (tst & 0xf) == 0xe:
clx = 'D'
elif (tst & 0xf) == 0xf:
clx = 'E'
return clx

def __contains__(self, item):
ret = True
row_hdr = None
try:
row_hdr = int.from_bytes(tuple(map(lambda n: (int(n)),
item.split('.'))), 'big')
except:
ret = False
if ret:
if not self.__network < row_hdr < self.__broadcast:
ret = False
return ret


def main():
sn = calcip('10.0.0.0/26')

print(f"subnet: {sn.subnet}")
print(f"network: {sn.network}")
print(f"broadcast: {sn.broadcast}")
print(f"mask: {sn.mask}")
print(f"wildcard: {sn.wildcard}")
print(f"host_min: {sn.host_min}")
print(f"host_max: {sn.host_max}")
print(f"Avaible hosts: {sn.hosts_num}")
print(f"Class: {sn.net_class}")

tst_hdr = '10.0.0.31'
is_not = 'is '
if not tst_hdr in sn:
is_not = 'is NOT '
print("hdr %s %sin range %s - %s" %
(tst_hdr, is_not, sn.host_min, sn.host_max))

if __name__ == '__main__':
main()
--
https://mail.python.org/mailman/listinfo/python-list
Re: for a 'good python' [ In reply to ]
Stefan Ram ha scritto:
> jak <nospam@please.ty> writes:
>> @property
>> def subnet(self):
>> return self.__to_str(self.__tsubnet)
>
> Maybe each of those attributes should be an object of a
> special class where your "__to_str" is "__str__"? E.g.,
>
> # code in "calcip.__init__"
> self.tsubnet = ip_address_class.from_int( subnet )
>
> where "ip_address_class" is as in:
>
> import collections
> import random
>
> class ip_address_class( collections.UserList ):
> def __init__( self, bytes_address ):
> super().__init__( bytes_address )
> @classmethod
> def from_int( cls, int_address ):
> return cls( int_address.to_bytes( 4, 'big' ))
> def __str__( self ):
> return '.'.join( str( byte_ )for byte_ in self.data )
>
> if __name__ == '__main__':
> ip_address = \
> ip_address_class.from_int( random.randint( 0, 4294967295 ))
> print( ip_address[ 0 ])
> print( ip_address )
>
> . Now the client can access each byte individually and also
> get a "nice" string representation.
>
> (You may add more "from_..." methods for all the various
> formats you create addresses from.)
>
> But you should also research the standard library to see
> if something like this doesn't already exist ready-made
> specifically for IP addresses in the standard library.
>
>
ok. thanks a lot. now i try to do that.


--
https://mail.python.org/mailman/listinfo/python-list
Re: for a 'good python' [ In reply to ]
?


> On 12 Apr 2023, at 18:10, jak <nospam@please.ty> wrote:
> ?Hi everyone,
> some time ago I wrote a class to determine if an ipv4 address belonged
> to a subnet. Seldom using python I'm pretty sure it's not written in
> 'good python' nor too portable. Could you give me some advice to make it
> better?
>
> class calcip:
> def __init__(self, psubnet: str):
> ssubnet, scidr = psubnet.replace(' ', '').split('/')
> subnet = int.from_bytes(tuple(
> map(lambda n: (int(n)), ssubnet.split('.'))),
> 'big')
> cidr = int(scidr)
> mask = ((2 ** cidr) - 1) << (32 - cidr)
> self.__network = subnet & mask
> self.__wildcard = ~mask & 0xffffffff
> self.__broadcast = (subnet | self.__wildcard) & 0xffffffff
> self.__tsubnet = tuple(subnet.to_bytes(4, 'big'))
> self.__tnetwork = tuple(self.__network.to_bytes(4, 'big'))
> self.__tbroadcast = tuple(self.__broadcast.to_bytes(4, 'big'))
> self.__tmask = tuple(mask.to_bytes(4, 'big'))
> self.__twildcard = tuple(self.__wildcard.to_bytes(4, 'big'))
> self.__host_min = tuple((self.__network + 1).to_bytes(4, 'big'))
> self.__host_max = tuple((self.__broadcast - 1).to_bytes(4, 'big'))
>
> @staticmethod
> def __to_str(val: tuple):
> return '.'.join(str(v) for v in val)
>
> @property
> def subnet(self):
> return self.__to_str(self.__tsubnet)
>
> @property
> def network(self):
> return self.__to_str(self.__tnetwork)
>
> @property
> def broadcast(self):
> return self.__to_str(self.__tbroadcast)
>
> @property
> def mask(self):
> return self.__to_str(self.__tmask)
>
> @property
> def wildcard(self):
> return self.__to_str(self.__twildcard)
>
> @property
> def host_min(self):
> return self.__to_str(self.__host_min)
>
> @property
> def host_max(self):
> return self.__to_str(self.__host_max)
>
> @property
> def hosts_num(self):
> return self.__wildcard - 1
>
> @property
> def net_class(self):
> tst = (self.__tnetwork[0] & 0xf0) >> 4
> if (tst & 0x8) == 0:
> clx = 'A'
> elif (tst & 0xc) == 0x8:
> clx = 'B'
> elif (tst & 0xe) == 0xc:
> clx = 'C'
> elif (tst & 0xf) == 0xe:
> clx = 'D'
> elif (tst & 0xf) == 0xf:
> clx = 'E'
> return clx
>
> def __contains__(self, item):
> ret = True
> row_hdr = None
> try:
> row_hdr = int.from_bytes(tuple(map(lambda n: (int(n)), item.split('.'))), 'big')
> except:
> ret = False
> if ret:
> if not self.__network < row_hdr < self.__broadcast:
> ret = False
> return ret
>
>
> def main():
> sn = calcip('10.0.0.0/26')
>
> print(f"subnet: {sn.subnet}")
> print(f"network: {sn.network}")
> print(f"broadcast: {sn.broadcast}")
> print(f"mask: {sn.mask}")
> print(f"wildcard: {sn.wildcard}")
> print(f"host_min: {sn.host_min}")
> print(f"host_max: {sn.host_max}")
> print(f"Avaible hosts: {sn.hosts_num}")
> print(f"Class: {sn.net_class}")
>
> tst_hdr = '10.0.0.31'
> is_not = 'is '
> if not tst_hdr in sn:
> is_not = 'is NOT '
> print("hdr %s %sin range %s - %s" %
> (tst_hdr, is_not, sn.host_min, sn.host_max))
>
> if __name__ == '__main__':
> main()

There is this https://docs.python.org/3/howto/ipaddress.html if you just want a solution.

Or are you after code review feedback?

Barry

> --
> https://mail.python.org/mailman/listinfo/python-list
--
https://mail.python.org/mailman/listinfo/python-list
Re: for a 'good python' [ In reply to ]
Barry ha scritto:
> ?
>
>
>> On 12 Apr 2023, at 18:10, jak <nospam@please.ty> wrote:
>> ?Hi everyone,
>> some time ago I wrote a class to determine if an ipv4 address belonged
>> to a subnet. Seldom using python I'm pretty sure it's not written in
>> 'good python' nor too portable. Could you give me some advice to make it
>> better?
>>
>> class calcip:
>> def __init__(self, psubnet: str):
>> ssubnet, scidr = psubnet.replace(' ', '').split('/')
>> subnet = int.from_bytes(tuple(
>> map(lambda n: (int(n)), ssubnet.split('.'))),
>> 'big')
>> cidr = int(scidr)
>> mask = ((2 ** cidr) - 1) << (32 - cidr)
>> self.__network = subnet & mask
>> self.__wildcard = ~mask & 0xffffffff
>> self.__broadcast = (subnet | self.__wildcard) & 0xffffffff
>> self.__tsubnet = tuple(subnet.to_bytes(4, 'big'))
>> self.__tnetwork = tuple(self.__network.to_bytes(4, 'big'))
>> self.__tbroadcast = tuple(self.__broadcast.to_bytes(4, 'big'))
>> self.__tmask = tuple(mask.to_bytes(4, 'big'))
>> self.__twildcard = tuple(self.__wildcard.to_bytes(4, 'big'))
>> self.__host_min = tuple((self.__network + 1).to_bytes(4, 'big'))
>> self.__host_max = tuple((self.__broadcast - 1).to_bytes(4, 'big'))
>>
>> @staticmethod
>> def __to_str(val: tuple):
>> return '.'.join(str(v) for v in val)
>>
>> @property
>> def subnet(self):
>> return self.__to_str(self.__tsubnet)
>>
>> @property
>> def network(self):
>> return self.__to_str(self.__tnetwork)
>>
>> @property
>> def broadcast(self):
>> return self.__to_str(self.__tbroadcast)
>>
>> @property
>> def mask(self):
>> return self.__to_str(self.__tmask)
>>
>> @property
>> def wildcard(self):
>> return self.__to_str(self.__twildcard)
>>
>> @property
>> def host_min(self):
>> return self.__to_str(self.__host_min)
>>
>> @property
>> def host_max(self):
>> return self.__to_str(self.__host_max)
>>
>> @property
>> def hosts_num(self):
>> return self.__wildcard - 1
>>
>> @property
>> def net_class(self):
>> tst = (self.__tnetwork[0] & 0xf0) >> 4
>> if (tst & 0x8) == 0:
>> clx = 'A'
>> elif (tst & 0xc) == 0x8:
>> clx = 'B'
>> elif (tst & 0xe) == 0xc:
>> clx = 'C'
>> elif (tst & 0xf) == 0xe:
>> clx = 'D'
>> elif (tst & 0xf) == 0xf:
>> clx = 'E'
>> return clx
>>
>> def __contains__(self, item):
>> ret = True
>> row_hdr = None
>> try:
>> row_hdr = int.from_bytes(tuple(map(lambda n: (int(n)), item.split('.'))), 'big')
>> except:
>> ret = False
>> if ret:
>> if not self.__network < row_hdr < self.__broadcast:
>> ret = False
>> return ret
>>
>>
>> def main():
>> sn = calcip('10.0.0.0/26')
>>
>> print(f"subnet: {sn.subnet}")
>> print(f"network: {sn.network}")
>> print(f"broadcast: {sn.broadcast}")
>> print(f"mask: {sn.mask}")
>> print(f"wildcard: {sn.wildcard}")
>> print(f"host_min: {sn.host_min}")
>> print(f"host_max: {sn.host_max}")
>> print(f"Avaible hosts: {sn.hosts_num}")
>> print(f"Class: {sn.net_class}")
>>
>> tst_hdr = '10.0.0.31'
>> is_not = 'is '
>> if not tst_hdr in sn:
>> is_not = 'is NOT '
>> print("hdr %s %sin range %s - %s" %
>> (tst_hdr, is_not, sn.host_min, sn.host_max))
>>
>> if __name__ == '__main__':
>> main()
>
> There is this https://docs.python.org/3/howto/ipaddress.html if you just want a solution.
>
> Or are you after code review feedback?
>
> Barry
>
>> --
>> https://mail.python.org/mailman/listinfo/python-list


Thank you too. I had seen this library but I always try not to use
libraries outside the standard ones. Now I don't remember why I was
convinced that this wasn't part of it, perhaps because it was like that
at the time or because I got confused. Only now I realized that it is
not necessary to install it. Now I'm considering whether to use
'ipaddress' or 'socket'. What is certain is that this one you have
suggested is really comfortable. Thanks again for the report.

--
https://mail.python.org/mailman/listinfo/python-list
Re: for a 'good python' [ In reply to ]
On Thu, 13 Apr 2023 00:21:58 +0200, jak <nospam@please.ty> declaimed the
following:


>Thank you too. I had seen this library but I always try not to use
>libraries outside the standard ones. Now I don't remember why I was
>convinced that this wasn't part of it, perhaps because it was like that
>at the time or because I got confused. Only now I realized that it is
>not necessary to install it. Now I'm considering whether to use
>'ipaddress' or 'socket'. What is certain is that this one you have
>suggested is really comfortable. Thanks again for the report.

It is useful to skim the contents of the standard library documentation
every couple of releases. ipaddress came in with Python 3.3

https://docs.python.org/3.10/library/index.html (I dropped down to 3.10
just as that is the version I have installed; some 3rd party modules
weren't ready when I tried to install on 3.11)
--
https://mail.python.org/mailman/listinfo/python-list
Re: for a 'good python' [ In reply to ]
Dennis Lee Bieber ha scritto:
> On Thu, 13 Apr 2023 00:21:58 +0200, jak <nospam@please.ty> declaimed the
> following:
>
>
>> Thank you too. I had seen this library but I always try not to use
>> libraries outside the standard ones. Now I don't remember why I was
>> convinced that this wasn't part of it, perhaps because it was like that
>> at the time or because I got confused. Only now I realized that it is
>> not necessary to install it. Now I'm considering whether to use
>> 'ipaddress' or 'socket'. What is certain is that this one you have
>> suggested is really comfortable. Thanks again for the report.
>
> It is useful to skim the contents of the standard library documentation
> every couple of releases. ipaddress came in with Python 3.3
>
> https://docs.python.org/3.10/library/index.html (I dropped down to 3.10
> just as that is the version I have installed; some 3rd party modules
> weren't ready when I tried to install on 3.11)
>

Then it was my fault. The version was 3.8.6
--
https://mail.python.org/mailman/listinfo/python-list
Re: for a 'good python' [ In reply to ]
Lars Liedtke
Software Entwickler

[Tel.] +49 721 98993-
[Fax] +49 721 98993-
[E-Mail] lal@solute.de<mailto:lal@solute.de>


solute GmbH
Zeppelinstraße 15
76185 Karlsruhe
Germany


[Logo Solute]


Marken der solute GmbH | brands of solute GmbH
[Marken]
[Advertising Partner]

Geschäftsführer | Managing Director: Dr. Thilo Gans, Bernd Vermaaten
Webseite | www.solute.de <http://www.solute.de/>
Sitz | Registered Office: Karlsruhe
Registergericht | Register Court: Amtsgericht Mannheim
Registernummer | Register No.: HRB 110579
USt-ID | VAT ID: DE234663798



Informationen zum Datenschutz | Information about privacy policy
https://www.solute.de/ger/datenschutz/grundsaetze-der-datenverarbeitung.php




Am 13.04.23 um 00:21 schrieb jak:
Barry ha scritto:
?


On 12 Apr 2023, at 18:10, jak <nospam@please.ty><mailto:nospam@please.ty> wrote:
?Hi everyone,
some time ago I wrote a class to determine if an ipv4 address belonged
to a subnet. Seldom using python I'm pretty sure it's not written in
'good python' nor too portable. Could you give me some advice to make it
better?

class calcip:
def __init__(self, psubnet: str):
ssubnet, scidr = psubnet.replace(' ', '').split('/')
subnet = int.from_bytes(tuple(
map(lambda n: (int(n)), ssubnet.split('.'))),
'big')
cidr = int(scidr)
mask = ((2 ** cidr) - 1) << (32 - cidr)
self.__network = subnet & mask
self.__wildcard = ~mask & 0xffffffff
self.__broadcast = (subnet | self.__wildcard) & 0xffffffff
self.__tsubnet = tuple(subnet.to_bytes(4, 'big'))
self.__tnetwork = tuple(self.__network.to_bytes(4, 'big'))
self.__tbroadcast = tuple(self.__broadcast.to_bytes(4, 'big'))
self.__tmask = tuple(mask.to_bytes(4, 'big'))
self.__twildcard = tuple(self.__wildcard.to_bytes(4, 'big'))
self.__host_min = tuple((self.__network + 1).to_bytes(4, 'big'))
self.__host_max = tuple((self.__broadcast - 1).to_bytes(4, 'big'))

@staticmethod
def __to_str(val: tuple):
return '.'.join(str(v) for v in val)

@property
def subnet(self):
return self.__to_str(self.__tsubnet)

@property
def network(self):
return self.__to_str(self.__tnetwork)

@property
def broadcast(self):
return self.__to_str(self.__tbroadcast)

@property
def mask(self):
return self.__to_str(self.__tmask)

@property
def wildcard(self):
return self.__to_str(self.__twildcard)

@property
def host_min(self):
return self.__to_str(self.__host_min)

@property
def host_max(self):
return self.__to_str(self.__host_max)

@property
def hosts_num(self):
return self.__wildcard - 1

@property
def net_class(self):
tst = (self.__tnetwork[0] & 0xf0) >> 4
if (tst & 0x8) == 0:
clx = 'A'
elif (tst & 0xc) == 0x8:
clx = 'B'
elif (tst & 0xe) == 0xc:
clx = 'C'
elif (tst & 0xf) == 0xe:
clx = 'D'
elif (tst & 0xf) == 0xf:
clx = 'E'
return clx

def __contains__(self, item):
ret = True
row_hdr = None
try:
row_hdr = int.from_bytes(tuple(map(lambda n: (int(n)), item.split('.'))), 'big')
except:
ret = False
if ret:
if not self.__network < row_hdr < self.__broadcast:
ret = False
return ret


def main():
sn = calcip('10.0.0.0/26')

print(f"subnet: {sn.subnet}")
print(f"network: {sn.network}")
print(f"broadcast: {sn.broadcast}")
print(f"mask: {sn.mask}")
print(f"wildcard: {sn.wildcard}")
print(f"host_min: {sn.host_min}")
print(f"host_max: {sn.host_max}")
print(f"Avaible hosts: {sn.hosts_num}")
print(f"Class: {sn.net_class}")

tst_hdr = '10.0.0.31'
is_not = 'is '
if not tst_hdr in sn:
is_not = 'is NOT '
print("hdr %s %sin range %s - %s" %
(tst_hdr, is_not, sn.host_min, sn.host_max))

if __name__ == '__main__':
main()

There is this https://docs.python.org/3/howto/ipaddress.html if you just want a solution.

Or are you after code review feedback?

Barry

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


Thank you too. I had seen this library but I always try not to use
libraries outside the standard ones. Now I don't remember why I was
convinced that this wasn't part of it, perhaps because it was like that
at the time or because I got confused. Only now I realized that it is
not necessary to install it. Now I'm considering whether to use
'ipaddress' or 'socket'. What is certain is that this one you have
suggested is really comfortable. Thanks again for the report.

Unless I am not mistakes, ipadress is "standard" because it is in the standard library
--
https://mail.python.org/mailman/listinfo/python-list
Re: for a 'good python' [ In reply to ]
?

> On 13 Apr 2023, at 00:19, jak <nospam@please.ty> wrote:
>
> ?Barry ha scritto:
>> ?
>>>> On 12 Apr 2023, at 18:10, jak <nospam@please.ty> wrote:
>>> ?Hi everyone,
>>> some time ago I wrote a class to determine if an ipv4 address belonged
>>> to a subnet. Seldom using python I'm pretty sure it's not written in
>>> 'good python' nor too portable. Could you give me some advice to make it
>>> better?
>>> class calcip:
>>> def __init__(self, psubnet: str):
>>> ssubnet, scidr = psubnet.replace(' ', '').split('/')
>>> subnet = int.from_bytes(tuple(
>>> map(lambda n: (int(n)), ssubnet.split('.'))),
>>> 'big')
>>> cidr = int(scidr)
>>> mask = ((2 ** cidr) - 1) << (32 - cidr)
>>> self.__network = subnet & mask
>>> self.__wildcard = ~mask & 0xffffffff
>>> self.__broadcast = (subnet | self.__wildcard) & 0xffffffff
>>> self.__tsubnet = tuple(subnet.to_bytes(4, 'big'))
>>> self.__tnetwork = tuple(self.__network.to_bytes(4, 'big'))
>>> self.__tbroadcast = tuple(self.__broadcast.to_bytes(4, 'big'))
>>> self.__tmask = tuple(mask.to_bytes(4, 'big'))
>>> self.__twildcard = tuple(self.__wildcard.to_bytes(4, 'big'))
>>> self.__host_min = tuple((self.__network + 1).to_bytes(4, 'big'))
>>> self.__host_max = tuple((self.__broadcast - 1).to_bytes(4, 'big'))
>>> @staticmethod
>>> def __to_str(val: tuple):
>>> return '.'.join(str(v) for v in val)
>>> @property
>>> def subnet(self):
>>> return self.__to_str(self.__tsubnet)
>>> @property
>>> def network(self):
>>> return self.__to_str(self.__tnetwork)
>>> @property
>>> def broadcast(self):
>>> return self.__to_str(self.__tbroadcast)
>>> @property
>>> def mask(self):
>>> return self.__to_str(self.__tmask)
>>> @property
>>> def wildcard(self):
>>> return self.__to_str(self.__twildcard)
>>> @property
>>> def host_min(self):
>>> return self.__to_str(self.__host_min)
>>> @property
>>> def host_max(self):
>>> return self.__to_str(self.__host_max)
>>> @property
>>> def hosts_num(self):
>>> return self.__wildcard - 1
>>> @property
>>> def net_class(self):
>>> tst = (self.__tnetwork[0] & 0xf0) >> 4
>>> if (tst & 0x8) == 0:
>>> clx = 'A'
>>> elif (tst & 0xc) == 0x8:
>>> clx = 'B'
>>> elif (tst & 0xe) == 0xc:
>>> clx = 'C'
>>> elif (tst & 0xf) == 0xe:
>>> clx = 'D'
>>> elif (tst & 0xf) == 0xf:
>>> clx = 'E'
>>> return clx
>>> def __contains__(self, item):
>>> ret = True
>>> row_hdr = None
>>> try:
>>> row_hdr = int.from_bytes(tuple(map(lambda n: (int(n)), item.split('.'))), 'big')
>>> except:
>>> ret = False
>>> if ret:
>>> if not self.__network < row_hdr < self.__broadcast:
>>> ret = False
>>> return ret
>>> def main():
>>> sn = calcip('10.0.0.0/26')
>>> print(f"subnet: {sn.subnet}")
>>> print(f"network: {sn.network}")
>>> print(f"broadcast: {sn.broadcast}")
>>> print(f"mask: {sn.mask}")
>>> print(f"wildcard: {sn.wildcard}")
>>> print(f"host_min: {sn.host_min}")
>>> print(f"host_max: {sn.host_max}")
>>> print(f"Avaible hosts: {sn.hosts_num}")
>>> print(f"Class: {sn.net_class}")
>>> tst_hdr = '10.0.0.31'
>>> is_not = 'is '
>>> if not tst_hdr in sn:
>>> is_not = 'is NOT '
>>> print("hdr %s %sin range %s - %s" %
>>> (tst_hdr, is_not, sn.host_min, sn.host_max))
>>> if __name__ == '__main__':
>>> main()
>> There is this https://docs.python.org/3/howto/ipaddress.html if you just want a solution.
>> Or are you after code review feedback?
>> Barry
>>> --
>>> https://mail.python.org/mailman/listinfo/python-list
>
>
> Thank you too. I had seen this library but I always try not to use
> libraries outside the standard ones. Now I don't remember why I was
> convinced that this wasn't part of it, perhaps because it was like that
> at the time or because I got confused. Only now I realized that it is
> not necessary to install it. Now I'm considering whether to use
> 'ipaddress' or 'socket'. What is certain is that this one you have
> suggested is really comfortable. Thanks again for the report.

Ipaddress was developed outside of the std lib and later added i recall.

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

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