Re: Getty fully qualified class name from class object
On 8/22/23 11:13, Greg Ewing via Python-list wrote: Classes have a __module__ attribute: >>> logging.Handler.__module__ 'logging' Not sure why I didn't think to look for such a thing. Looks like it's as simple as f'{cls.__module__}.{cls.__qualname__}'. Thanks! -- Google Where SkyNet meets Idiocracy -- https://mail.python.org/mailman/listinfo/python-list
Getty fully qualified class name from class object
How can I programmatically get the fully qualified name of a class from its class object? (I'm referring to the name that is shown when str() or repr() is called on the class object.) Neither the __name__ or __qualname__ class attributes include the module. For example: >>> import logging >>> str(logging.Handler) "" >>> logging.Handler.__name__ 'Handler' >>> logging.Handler.__qualname__ 'Handler' How can I programmatically get 'logging.Handler' from the class object? -- Google Where SkyNet meets Idiocracy -- https://mail.python.org/mailman/listinfo/python-list
Which more Pythonic - self.__class__ or type(self)?
Seems like an FAQ, and I've found a few things on StackOverflow that discuss the technical differences in edge cases, but I haven't found anything that talks about which form is considered to be more Pythonic in those situations where there's no functional difference. Is there any consensus? -- Google Where SkyNet meets Idiocracy -- https://mail.python.org/mailman/listinfo/python-list
Re: Tool that can document private inner class?
On 2/8/23 08:25, Weatherby,Gerard wrote: No. I interpreted your query as “is there something that can read docstrings of dunder methods?” Have you tried the Sphinx specific support forums? https://www.sphinx-doc.org/en/master/support.html Yes. I've posted to both the -user and -dev groups, and I've also filed an issue[1]. I haven't received a response. Thus my conclusion that Sphinx, specifically autodoc, simply can't do this. [1] https://github.com/sphinx-doc/sphinx/issues/11181 -- Google Where SkyNet meets Idiocracy -- https://mail.python.org/mailman/listinfo/python-list
Re: Tool that can document private inner class?
On 2/7/23 14:53, Weatherby,Gerard wrote: Yes. Inspect module import inspect class Mine: def __init__(self): self.__value = 7 def __getvalue(self): /"""Gets seven""" /return self.__value mine = Mine() data = inspect.getdoc(mine) for m in inspect.getmembers(mine): if '__getvalue' in m[0]: d = inspect.getdoc(m[1]) print(d) Can inspect generate HTML documentation, à la Sphinx and other tools? -- Google Where SkyNet meets Idiocracy -- https://mail.python.org/mailman/listinfo/python-list
Tool that can document private inner class?
I've been banging my head on Sphinx for a couple of days now, trying to get it to include the docstrings of a private (name starts with two underscores) inner class. All I've managed to do is convince myself that it really can't do it. See https://github.com/sphinx-doc/sphinx/issues/11181. Is there a tool out there that can do this? -- Google Where SkyNet meets Idiocracy -- https://mail.python.org/mailman/listinfo/python-list
Re: set.add() doesn't replace equal element
On 12/30/22 17:00, Paul Bryan wrote: It seems to me like you have to ideas of what "equal" means. You want to update a "non-equal/equal" value in the set (because of a different time stamp). If you truly considered them equal, the time stamp would be irrelevant and updating the value in the set would be unnecessary. I would: a) /not/ consider two different leases with two different time stamps to be equal, and b) as already mentioned, store them in another data structure like a dictionary. Not knowing the specifics of the DHCP object structure, if a DHCP lease object has some immutable key or other durable immutable attribute, I would be inclined to make that the dictionary key, and store the DHCP object as the value. I have come to the conclusion that you are correct. Thanks! -- Google Where SkyNet meets Idiocracy -- https://mail.python.org/mailman/listinfo/python-list
Re: set.add() doesn't replace equal element
On 12/30/22 15:47, Paul Bryan wrote: What kind of elements are being added to the set? Can you show reproducible sample code? The objects in question are DHCP leases. I consider them "equal" if the lease address (or IPv6 prefix) is equal, even if the timestamps have changed. That code is not small, but it's easy to demonstrate the behavior. >>> import datetime >>> class Foo(object): ... def __init__(self, index): ... self.index = index ... self.timestamp = datetime.datetime.now() ... def __eq__(self, other): ... return type(other) is Foo and other.index == self.index ... def __hash__(self): ... return hash(self.index) ... def __repr__(self): ... return f'Foo({self.index}) created at {str(self.timestamp)}' ... >>> f1 = Foo(1) >>> s = { f1 } >>> s {Foo(1) created at 2022-12-30 16:24:12.352908} >>> f2 = Foo(1) >>> f2 Foo(1) created at 2022-12-30 16:24:35.489208 >>> s.add(f2) >>> s {Foo(1) created at 2022-12-30 16:24:12.352908} -- Google Where SkyNet meets Idiocracy -- https://mail.python.org/mailman/listinfo/python-list
set.add() doesn't replace equal element
I just discovered this behavior, which is problematic for my particular use. Is there a different set API (or operator) that can be used to add an element to a set, and replace any equal element? If not, am I correct that I should call set.discard() before calling set.add() to achieve the behavior that I want? -- Google Where SkyNet meets Idiocracy -- https://mail.python.org/mailman/listinfo/python-list
Re: Calling pselect/ppoll/epoll_pwait
On 12/2/22 14:00, Ian Pilcher wrote: Does Python provide any way to call the "p" variants of the I/O multiplexing functions? Just to close this out ... As others suggested, there's no easy way to call the "p" variants of the I/O multiplexing functions, but this can be worked around by "mapping" signals to file descriptors. There are a few ways to accomplish this. 1. Use a Linux signalfd. There's at least one library out there that provides signalfd support to Python. 2. Use signal.set_wakeup_fd()[1]. I didn't really explore this, as it appears that there isn't any way to filter the signals that will be reported. 3. Roll your own. This turned out to be really simple for my use case, which is simply to set an exit flag and wake my program up if it receives SIGINT or SIGTERM. _sel = selectors.DefaultSelector() _exit_flag = False _sig_pipe_r, _sig_pipe_w = os.pipe2(os.O_NONBLOCK | os.O_CLOEXEC) def _sig_handler(signum, frame): global _exit_flag _exit_flag = True os.write(_sig_pipe_w, b'\x00') _sel.register(_sig_pipe_r, selectors.EVENT_READ) # register other file descriptors of interest signal.signal(signal.SIGINT, _sig_handler) signal.signal(signal.SIGTERM, _sig_handler) while not _exit_flag: ready = _sel.select() # handle other file descriptors [1] https://docs.python.org/3/library/signal.html#signal.set_wakeup_fd -- Google Where SkyNet meets Idiocracy -- https://mail.python.org/mailman/listinfo/python-list
Calling pselect/ppoll/epoll_pwait
Does Python provide any way to call the "p" variants of the I/O multiplexing functions? Looking at the documentation of the select[1] and selectors[2] modules, it appears that they expose only the "non-p" variants. [1] https://docs.python.org/3/library/select.html [2] https://docs.python.org/3/library/selectors.html -- Google Where SkyNet meets Idiocracy -- https://mail.python.org/mailman/listinfo/python-list
Re: Dealing with non-callable classmethod objects
On 11/12/22 14:57, Cameron Simpson wrote: You shouldn't need a throwaway class, just use the name "classmethod" directly - it's the type! if not callable(factory): if type(factory) is classmethod: # replace fctory with a function calling factory.__func__ factory = lambda arg: factory.__func__(classmethod, arg) else: raise TypeError("unhandled factory type %s:%r" % (type(factory), factory) value = factory(d[attr]) Or I could use the C++ version: face << palm; Thanks! -- Google Where SkyNet meets Idiocracy -- https://mail.python.org/mailman/listinfo/python-list
Re: Dealing with non-callable classmethod objects
On 11/11/22 16:47, Cameron Simpson wrote: On 11Nov2022 15:29, Ian Pilcher wrote: * Can I improve the 'if callable(factory):' test above? This treats all non-callable objects as classmethods, which is obviously not correct. Ideally, I would check specifically for a classmethod, but there doesn't seem to be any literal against which I could check the factory's type. Yeah, it does feel a bit touchy feely. You could see if the `inspect` module tells you more precise things about the `factory`. The other suggestion I have is to put the method name in `_attrs`; if that's a `str` you could special case it as a well known type for the factory and look it up with `getattr(cls,factory)`. So I've done this. class _HasUnboundClassMethod(object): @classmethod def _classmethod(cls): pass # pragma: no cover _methods = [ _classmethod ] _ClassMethodType = type(_HasUnboundClassMethod._methods[0]) Which allows me to do this: def __init__(self, d): for attr, factory in self._attrs.items(): if callable(factory): value = factory(d[attr]) else: assert type(factory) is self._ClassMethodType value = factory.__func__(type(self), d[attr]) setattr(self, attr, value) It's a bit cleaner, although I'm not thrilled about having a throwaway class, just to define a literal that ought to be provided by the runtime. -- Google Where SkyNet meets Idiocracy -- https://mail.python.org/mailman/listinfo/python-list
Re: Superclass static method name from subclass
On 11/11/22 11:02, Thomas Passin wrote: You can define a classmethod in SubClass that seems to do the job: class SuperClass(object): @staticmethod def spam(): # "spam" and "eggs" are a Python tradition print('spam from SuperClass') class SubClass(SuperClass): @classmethod def eggs(self): super().spam() SubClass.eggs() # Prints "spam from SuperClass" That did it! Thanks! -- Google Where SkyNet meets Idiocracy -- https://mail.python.org/mailman/listinfo/python-list
Re: Superclass static method name from subclass
On 11/11/22 11:29, Dieter Maurer wrote: Ian Pilcher wrote at 2022-11-11 10:21 -0600: class SuperClass(object): @staticmethod def foo(): pass class SubClass(SuperClass): bar = SuperClass.foo ^^ Is there a way to do this without specifically naming 'SuperClass'? Unless you overrode it, you can use `self.foo` or `SubClass.foo`; if you overrode it (and you are using either Python 3 or Python 2 and a so called "new style class"), you can use `super`. When you use `super` outside a method definition, you must call it with parameters. SubClass.foo doesn't work, because 'SubClass' doesn't actually exist until the class is defined. >>> class SubClass(SuperClass): ... bar = SubClass.foo ... Traceback (most recent call last): File "", line 1, in File "", line 2, in SubClass NameError: name 'SubClass' is not defined. Did you mean: 'SuperClass'? Similarly, self.foo doesn't work, because self isn't defined: >>> class SubClass(SuperClass): ... bar = self.foo ... Traceback (most recent call last): File "", line 1, in File "", line 2, in SubClass NameError: name 'self' is not defined -- Google Where SkyNet meets Idiocracy -- https://mail.python.org/mailman/listinfo/python-list
Dealing with non-callable classmethod objects
I am trying to figure out a way to gracefully deal with uncallable classmethod objects. The class hierarchy below illustrates the issue. (Unfortunately, I haven't been able to come up with a shorter example.) import datetime class DUID(object): _subclasses = {} def __init_subclass__(cls, **kwargs): super().__init_subclass__(**kwargs) cls._subclasses[cls.duid_type] = cls def __init__(self, d): for attr, factory in self._attrs.items(): setattr(self, attr, factory(d[attr])) @classmethod def from_dict(cls, d): subcls = cls._subclasses[d['duid_type']] return subcls(d) class DuidLL(DUID): @staticmethod def _parse_l2addr(addr): return bytes.fromhex(addr.replace(':', '')) duid_type = 'DUID-LL' _attrs = { 'layer2_addr': _parse_l2addr } class DuidLLT(DuidLL): @classmethod def _parse_l2addr(cls, addr): return super()._parse_l2addr(addr) duid_type = 'DUID-LLT' _attrs = { 'layer2_addr': _parse_l2addr, 'time': datetime.datetime.fromisoformat } A bit of context on why I want to do this ... This is a simplified subset of a larger body of code that parses a somewhat complex configuration. The configuration is a YAML document, that pyyaml parses into a dictionary (which contains other dictionaries, lists, etc., etc.). My code then parses that dictionary into an object graph that represents the configuration. Rather than embedding parsing logic into each of my object classes, I have "lifted" it into the parent class (DUID in the example). A subclasses need only provide a few attributes that identifies its required and optional attributes, default values, etc. (simplified to DuidLL._attrs and DuidLLT._attrs in the example). The parent class factory function (DUID.from_dict) uses the information in the subclass's _attrs attribute to control how it parses the configuration dictionary. Importantly, a subclass's _attrs attribute maps attribute names to "factories" that are used to parse the values into various types of objects. Thus, DuidLL's 'layer2_addr' attribute is parsed with its _parse_l2addr() static method, and DuidLLT's 'time' attribute is parsed with datetime.datetime.fromisoformat(). A factory can be any callable object that takes a dictionary as its only argument. This works with static methods (as well as normal functions and object types that have an appropriate constructor): duid_ll = DUID.from_dict({ 'duid_type': 'DUID-LL', 'layer2_addr': 'de:ad:be:ef:00:00' }) type(duid_ll) duid_ll.duid_type 'DUID-LL' duid_ll.layer2_addr b'\xde\xad\xbe\xef\x00\x00' It doesn't work with a class method, such as DuidLLT._parse_l2addr(): duid_llt = DUID.from_dict({ 'duid_type': 'DUID-LLT', 'layer2_addr': 'de:ad:be:ef:00:00', 'time': '2015-09-04T07:53:04-05:00' }) Traceback (most recent call last): File "", line 1, in File "/home/pilcher/subservient/wtf/wtf.py", line 19, in from_dict return subcls(d) File "/home/pilcher/subservient/wtf/wtf.py", line 14, in __init__ setattr(self, attr, factory(d[attr])) TypeError: 'classmethod' object is not callable In searching, I've found a few articles that discuss the fact that classmethod objects aren't callable, but the situation actually seems to be more complicated. >>> type(DuidLLT._parse_l2addr) >>> callable(DuidLLT._parse_l2addr) True The method itself is callable, which makes sense. The factory function doesn't access it directly, however, it gets it out of the _attrs dictionary. >>> type(DuidLLT._attrs['layer2_addr']) >>> callable(DuidLLT._attrs['layer2_addr']) False I'm not 100% sure, but I believe that this is happening because the class (DuidLLT) doesn't exist at the time that its _attrs dictionary is defined. Thus, there is no class to which the method can be bound at that time and the dictionary ends up containing the "unbound version." Fortunately, I do know the class in the context from which I actually need to call the method, so I am able to call it with its __func__ attribute. A modified version of DUID.__init__() appears to work: def __init__(self, d): for attr, factory in self._attrs.items(): if callable(factory): # <= ???! value = factory(d[attr]) else: value = factory.__func__(type(self), d[attr]) setattr(self, attr, value) A couple of questions (finally!): * Is my analysis of why this is happening correct? * Can I improve the 'if callable(factory):' test above? This treats all non-callable objects as classmethods, which is obviously not correct. Ideally, I would check specifically for a classmethod, but there doesn't seem to be any literal against which I could check the factory's type. Note: I am aware that there are any number of workarounds for this issue. I just want to make sure that I understand what is going on, and determine if there's a be
Superclass static method name from subclass
Is it possible to access the name of a superclass static method, when defining a subclass attribute, without specifically naming the super- class? Contrived example: class SuperClass(object): @staticmethod def foo(): pass class SubClass(SuperClass): bar = SuperClass.foo ^^ Is there a way to do this without specifically naming 'SuperClass'? -- Google Where SkyNet meets Idiocracy -- https://mail.python.org/mailman/listinfo/python-list
Re: Any socket library to communicate with kernel via netlink?
On 11/18/19 9:23 PM, lampahome wrote: As title, I tried to communicate with kernel via netlink. But I failed when I receive msg from kernel. The weird point is sending successfully from user to kernel, failed when receiving from kernel. So I want to check code in 3rd library and dig in, but always found library called netlinkg but it actually does something like modify network address or check network card... Any idea is welcome https://pypi.org/project/pyroute2/ -- Ian Pilcher arequip...@gmail.com "I grew up before Mark Zuckerberg invented friendship" -- https://mail.python.org/mailman/listinfo/python-list
Distutils - bdist_rpm - specify python interpretter location
I am trying to use Distutils "bdist_rpm" function on Fedora 30. It is failing, because Fedora does not provide a "python" executable; it provides /usr/bin/python2 and /usr/bin/python3. The error message is: env: 'python': No such file or directory error: Bad exit status from /var/tmp/rpm-tmp.a3xWMd (%build) When run with the --spec-only option, one can see where 'python' is used in the generated SPEC file: %build env CFLAGS="$RPM_OPT_FLAGS" python setup.py build %install python setup.py install -O1 --root=$RPM_BUILD_ROOT --record=INSTALLED_FILES Is there a way to tell Distutils to use 'python2'? Thanks! -- ======== Ian Pilcher arequip...@gmail.com "I grew up before Mark Zuckerberg invented friendship" -- https://mail.python.org/mailman/listinfo/python-list
Re: Get __name__ in C extension module
On 10/7/19 2:09 AM, Barry Scott wrote: I meant pass in the specific named logger that you C code will use. Right, but I'm assuming that your C/C++ code will receive the logger object by calling PyArg_ParseTuple (or similar), and I further assume that you want to validate that the object actually is a logger. Doing that validation (by using an "O!" unit in the PyArg_ParseTuple format string) requires access to the logging.Logger type object, and I was unable to find a way to access that object by name. -- ============ Ian Pilcher arequip...@gmail.com "I grew up before Mark Zuckerberg invented friendship" -- https://mail.python.org/mailman/listinfo/python-list
Re: Get __name__ in C extension module
On 10/6/19 12:55 PM, Barry Scott wrote: Then the answer to your question is simple. Do it in python and passt logger into the C++ module. Funny thing, that's exactly where I started this journey. I couldn't figure out how to get the logging.Logger type object, so that I could use a "O!" format string unit. This led me to read a bit more about the logging framework, which led me to the advice to get loggers by name, rather than passing them around, etc., etc. Next I would never code directly against the C API. Its a pain to use and get right, get the ref counts wrong and you get memory leaks of worse crash python. Well, I like driving cars with manual transmissions, so ... -- ======== Ian Pilcher arequip...@gmail.com "I grew up before Mark Zuckerberg invented friendship" -- https://mail.python.org/mailman/listinfo/python-list
Re: Get __name__ in C extension module
On 10/6/19 11:55 AM, MRAB wrote: Don't you already have the module's name? You have to specify it in the PyModuleDef struct that you pass to PyModule_Create. I do. Perhaps I'm trying to be too Pythonic, but there's so much advice out there about using getLogger(__name__) in Python code, rather than hardcoding the name. I've been trying to follow that pattern in my extension module. Calling PyModule_Create returns a reference to the module, and you can get its namespace dict with PyModule_GetDict(...). Right. I have that in my module init function, but how do I access that later in one of my extension functions? The only thing I can think of would be to save it in a static variable, but static variables seem to be a no-no in extensions. -- ======== Ian Pilcher arequip...@gmail.com "I grew up before Mark Zuckerberg invented friendship" -- https://mail.python.org/mailman/listinfo/python-list
Re: Get __name__ in C extension module
On 10/5/19 12:55 PM, Ian Pilcher wrote: This is straightforward, except that I cannot figure out how to retrieve the __name__. Making progress. I can get a __name__ value with: PyDict_GetItemString(PyEval_GetGlobals(), "__name__") I say "a __name__ value" because the returned value is actually that of the calling module, not the name of my extension. Is this normal? Thanks! -- ======== Ian Pilcher arequip...@gmail.com "I grew up before Mark Zuckerberg invented friendship" -- https://mail.python.org/mailman/listinfo/python-list
Get __name__ in C extension module
On 10/4/19 4:30 PM, Ian Pilcher wrote: Ideally, I would pass my existing Logging.logger object into my C function and use PyObject_CallMethod to call the appropriate method on it (info, debug, etc.). As I've researched this further, I've realized that this isn't the correct approach. My extension should be doing the C equivalent of: logger = logging.getLogger(__name__) This is straightforward, except that I cannot figure out how to retrieve the __name__. I can get it from the module object with PyModule_GetName, but that requires that I have a reference to the module object in order to do so. I would have thought that this would be easy for a module function to access, but I haven't been able to find any API which does this. (Module functions get NULL as their 'self' argument.) Any pointers appreciated. Thanks! -- ============ Ian Pilcher arequip...@gmail.com "I grew up before Mark Zuckerberg invented friendship" -- https://mail.python.org/mailman/listinfo/python-list
Using a logging.Logger in a C extension
I am working my way through writing a C extension, and I've realized that I need to log a few messages from the C code. Ideally, I would pass my existing Logging.logger object into my C function and use PyObject_CallMethod to call the appropriate method on it (info, debug, etc.). PyArg_ParseTuple should be able to handle this with an "O!" format unit, but I can't figure out how to retrieve the type object for logging.Logger. Any hints, links, etc. appreciated. Thanks! -- ======== Ian Pilcher arequip...@gmail.com "I grew up before Mark Zuckerberg invented friendship" -- https://mail.python.org/mailman/listinfo/python-list
Irritating bytearray behavior
I am using a bytearray to construct a very simple message, that will be sent across the network. The message should always be 20 bytes: 2 bytes - address family (AF_INET or AF_INET6) - network byte order 2 bytes - (padding) 4 or 16 bytes - IP address The size of the IP address is dependent on whether it is an IPv4 address (4 bytes) or an IPv6 address (16 bytes). In the IPv4 case, it should be followed by 12 bytes of padding, to keep the message size consistent. Naïvely, I thought that I could do this: ip = ipaddress.ip_address(unicode(addr)) msg = bytearray(20) msg[1] = socket.AF_INET if ip.version == 4 else socket.AF_INET6 msg[4:] = ip.packed sock.sendto(msg, dest) This doesn't work in the IPv4 case, because the bytearray gets truncated to only 8 bytes (4 bytes plus the size of ip.packed). Is there a way to avoid this behavior copy the contents of ip.packed into the bytearray without changing its size? TIA -- ==== Ian Pilcher arequip...@gmail.com "I grew up before Mark Zuckerberg invented friendship" -- https://mail.python.org/mailman/listinfo/python-list
Re: The basics of the logging module mystify me
On 04/19/2018 04:52 AM, Thomas Jollans wrote: Or, more often than not, it's best to use the logging module's configuration system that creates the right web of handlers and formatters for you. Wow! This is the first I've heard of logging.config (although it's easy to find now that I know that it exists). As far as I can remember, none of the logging tutorials that I read ever mentioned it. -- ======== Ian Pilcher arequip...@gmail.com "I grew up before Mark Zuckerberg invented friendship" -- https://mail.python.org/mailman/listinfo/python-list
Re: Spot the invalid syntax
On 03/08/2018 05:30 PM, Ben Finney wrote: Not sufficiently, it seems. Check the line preceding the ‘return’ statement. Indeed. :-/ Then, switch to using a programmer's text editor (I prefer Emacs) that can spot these syntax errors while you type. The sad thing is that I am. Just too bone-headed to use properly, apparently. -- ==== Ian Pilcher arequip...@gmail.com "I grew up before Mark Zuckerberg invented friendship" -- https://mail.python.org/mailman/listinfo/python-list
Re: Spot the invalid syntax
On 03/08/2018 05:26 PM, Chris Angelico wrote: On Fri, Mar 9, 2018 at 10:23 AM, Ian Pilcher wrote: (Because I certainly can't.) ips.update(_san_dnsname_ips(cname, True) return ips I've checked for tabs and mismatched parentheses. Check the immediately preceding line (the one I quoted). (Sometimes, you just need another pair of eyes.) D'oh! Clearly, my checking needs work. Thanks mucho! -- ============ Ian Pilcher arequip...@gmail.com "I grew up before Mark Zuckerberg invented friendship" -- https://mail.python.org/mailman/listinfo/python-list
Spot the invalid syntax
(Because I certainly can't.) def _san_dnsname_ips(dnsname, dnsname_is_cname=False): """ Returns a set of IP addresses, managed by this IPa instance, that correspond to the DNS name (from the subjectAltName). """ fqdn = dnsutil.DNSName(dnsname).make_absolute() if fqdn.__len__() < 4: logger.debug("Skipping IPs for %s: hostname too short" % dnsname) return () zone = dnsutil.DNSName(resolver.zone_for_name(fqdn)) name = fqdn.relativize(zone) try: result = api.Command['dnsrecord_show'](zone, name)['result'] except errors.NotFound as nf: logger.debug("Skipping IPs for %s: %s" % (dnsname, nf)) return () ips = set() for ip in itertools.chain(result.get('arecord', ()), result.get('record', ())): if _ip_rdns_ok(ip, fqdn): ips.add(ip) cnames = result.get('cnamerecord', ()) if cnames: if dnsname_is_cname: logger.debug("Skipping IPs for %s: chained CNAME" % dnsname) else: for cname in cnames: if not cname.endswith('.'): cname = u'%s.%s' % (cname, zone) ips.update(_san_dnsname_ips(cname, True) return ips 2.7 and 3.6 are both giving me: File "/tmp/test.py", line 32 return ips ^ SyntaxError: invalid syntax I've checked for tabs and mismatched parentheses. Aargh! -- Ian Pilcher arequip...@gmail.com "I grew up before Mark Zuckerberg invented friendship" -- https://mail.python.org/mailman/listinfo/python-list
Re: __new__ and __init__ - why does this work?
On 08/09/2017 07:54 AM, Steve D'Aprano wrote: On Wed, 9 Aug 2017 10:08 am, Ian Pilcher wrote: I have created a class to provide a "hash consing"[1] set. Your footnote for [1] appears to be missing. What's a hash consing set? It appears to be nothing more than frozen sets which you put in a cache so as to confuse identity and value *wink* Uugh. Here's the link: https://en.wikipedia.org/wiki/Hash_consing I doubt very much you're actually saving any time, since you create a temporary frozen set before returning the one in the cache. You might save some memory though. Indeed. This is all about using memory efficiently. Your __init__ method does nothing. Get rid of it and save two lines of code :-) Well, it prevents frozenset.__init__ from being called. Also, there is at least theoretically the vague possibility that frozenset.__init__ does something (phones home to Guido?) so you shouldn't block it if you don't need to. I do want to prevent frozenset.__init__ from being called *again* when an existing instance is returned, so I've decided to take this approach: def __new__(cls, *args, **kwargs): self = super(UniqueSet, cls).__new__(cls, *args, **kwargs) self._initialized = False return UniqueSet._registry.setdefault(self, self) def __init__(self, *args, **kwargs): if not self._initialized: super(UniqueSet, self).__init__(self, *args, **kwargs) self._initialized = True -- ======== Ian Pilcher arequip...@gmail.com "I grew up before Mark Zuckerberg invented friendship" -- https://mail.python.org/mailman/listinfo/python-list
Re: __new__ and __init__ - why does this work?
On 08/08/2017 10:19 PM, Ian Kelly wrote: It's initialized by the superclass call to __new__. frozenset is immutable, and __init__ methods of immutable types generally don't do anything (if they could, then they wouldn't be immutable), which is why it doesn't really matter that you didn't call it. At the same time, it generally doesn't hurt to call it, and you probably shouldn't even have an override of __init__ here if it doesn't do anything. Thanks for the explanation. I'll admit that I'm a bit paranoid about the potential effects of "re-__init__-ing" an object, at least in the general case. What do you think of this? def __new__(cls, *args, **kwargs): self = super(UniqueSet, cls).__new__(cls, *args, **kwargs) self._initialized = False return UniqueSet._registry.setdefault(self, self) def __init__(self, *args, **kwargs): if not self._initialized: super(UniqueSet, self).__init__(self, *args, **kwargs) self._initialized = True It seems a bit inefficient that you create *two* sets in __new__ and then map one of them to the other in your registry. Why not just create the UniqueSet and then map it to itself if it's not already registered? Something like this (untested): def __new__(cls, *args, **kwargs): self = super(UniqueSet, cls).__new__(cls, *args, **kwargs) return UniqueSet._registry.setdefault(self, self) That was mainly me being unfamiliar with the frozenset API (and not overly concerned about the size of the _registry, since I expect that there will be a very small number of entries). Your version is much more elegant. Thank you! -- ======== Ian Pilcher arequip...@gmail.com "I grew up before Mark Zuckerberg invented friendship" -- https://mail.python.org/mailman/listinfo/python-list
__new__ and __init__ - why does this work?
I have created a class to provide a "hash consing"[1] set. class UniqueSet(frozenset): _registry = dict() def __new__(cls, *args, **kwargs): set = frozenset(*args, **kwargs) try: return UniqueSet._registry[set] except KeyError: self = super(UniqueSet, cls).__new__(cls, *args, **kwargs) UniqueSet._registry[set] = self return self def __init__(self, *args, **kwargs): pass I can't figure out how it works, though. In particular, I can't figure out how the call to __new__ actually initializes the set (since my __init__ never calls the superclass __init__). Is this a particular behavior of frozenset, or am I missing something about the way that __new__ and __init__ interact? -- ======== Ian Pilcher arequip...@gmail.com "I grew up before Mark Zuckerberg invented friendship" -- https://mail.python.org/mailman/listinfo/python-list
Subclassing dict to modify values
YANQ (Yet Another Newbie Question) ... I would like to create a subclass of dict that modifies values as they are inserted. (Effectively I want to do the equivalent of "interning" the values, although they aren't strings.) Do I need to implement any methods other than __setitem__? (I.e. will any other methods/operators that add values to the dictionary call my __setitem__ method?) -- ============ Ian Pilcher arequip...@gmail.com "I grew up before Mark Zuckerberg invented friendship" -- https://mail.python.org/mailman/listinfo/python-list
Re: Get list of attributes from list of objects?
On 08/02/2017 12:49 PM, Chris Angelico wrote: On Thu, Aug 3, 2017 at 3:21 AM, Ian Pilcher wrote: You can't eliminate the loop, but you can compact it into a single logical operation: namelist = [foo.name for foo in foolist] That's a "list comprehension", and is an elegant way to process a list in various ways. Very nice! Thank you! -- ======== Ian Pilcher arequip...@gmail.com "I grew up before Mark Zuckerberg invented friendship" -- https://mail.python.org/mailman/listinfo/python-list
Get list of attributes from list of objects?
Given a list of objects that all have a particular attribute, is there a simple way to get a list of those attributes? In other words: class Foo(object): def __init__(self, name): self.name = name foolist = [ Foo('a'), Foo('b'), Foo('c') ] namelist = [] for foo in foolist: namelist.append(foo.name) Is there a way to avoid the for loop and create 'namelist' with a single expression? -- ======== Ian Pilcher arequip...@gmail.com "I grew up before Mark Zuckerberg invented friendship" -- https://mail.python.org/mailman/listinfo/python-list
Re: Why does Python want to read /proc/meminfo
On 05/06/2017 12:51 AM, dieter wrote: Personally, I doubt that you will find a reference. Instead, I assume that the reference comes from the C runtime library. It might hepl optimize memory management to know about "meminfo" details. You're right. Seems that it's glibc's qsort(). So it seems that any service written in Python (or any other program that uses qsort) needs to be given read access to most of /proc or deal with the (unspecified) consequences of not allowing qsort() to determine the amount of memory in the system. Delightful. -- ======== Ian Pilcher arequip...@gmail.com "I grew up before Mark Zuckerberg invented friendship" -- https://mail.python.org/mailman/listinfo/python-list
Why does Python want to read /proc/meminfo
I am trying to write an SELinux policy to confine a simple service that I have written in Python, and I'm trying to decide whether to allow or dontaudit various denials. To start, I've reduced my service to the simplest case: #!/usr/bin/python import sys sys.exit() Running this program in a confined domain generated the following denial: avc: denied { read } for pid=2024 comm="denatc" name="meminfo" dev="proc" ino=4026532028 scontext=system_u:system_r:denatc_t:s0 tcontext=system_u:object_r:proc_t:s0 tclass=file The program does continue on and exit cleanly, so it doesn't seem to strictly require the access. Does anyone know why Python is trying to access this file, or what functionality I might be missing if I don't allow the access? -- ============ Ian Pilcher arequip...@gmail.com "I grew up before Mark Zuckerberg invented friendship" -- https://mail.python.org/mailman/listinfo/python-list
Re: cryptography default_backend is "hazmat"?
On 03/19/2017 05:46 PM, Paul Moore wrote: 1. Fernet symmetric encryption, which is fine, but needs me to manage the key safely (and offers no help in doing that) 2. X509, whose docs are a reference (that you need to understand X509 to follow) and a couple of tutorials on generating/requesting keys. Nothing on using X509 for encryption. Actually, even loading an X.509 certificate from a PEM file requires a backend, which means delving into the "hazmat" area. I'm not saying that some crypto functions require careful handling; they obviously do. But is default_backend one of them? -- ============ Ian Pilcher arequip...@gmail.com "I grew up before Mark Zuckerberg invented friendship" -- https://mail.python.org/mailman/listinfo/python-list
Re: cryptography default_backend is "hazmat"?
On 03/18/2017 05:15 PM, Chris Angelico wrote: So the question is: How well do you trust the examples? Are they likely to be instructing you in a safe way to use this potentially-dangerous module? But as far as I can tell, there's no way to use many of the non-hazmat functions (e.g. parsing a certificate) without a backend, and all of the backends are "hazmat". So what's the point of marking something as hazmat, if a large portion of the rest of the module can't be used without it? -- ======== Ian Pilcher arequip...@gmail.com "I grew up before Mark Zuckerberg invented friendship" -- https://mail.python.org/mailman/listinfo/python-list
cryptography default_backend is "hazmat"?
Yet another newbie question/observation ... So every example I can find of using python-cryptography includes a call to cryptography.hazmat.backends.default_backend(). Of course, the documentation at https://cryptography.io/en/latest/hazmat/backends/ says: ! Danger This is a “Hazardous Materials” module. You should ONLY use it if you’re 100% absolutely sure that you know what you’re doing because this module is full of land mines, dragons, and dinosaurs with laser guns. Anyone else see a conflict here? -- Ian Pilcher arequip...@gmail.com "I grew up before Mark Zuckerberg invented friendship" -- https://mail.python.org/mailman/listinfo/python-list
Re: python-daemon and PID files
On 03/04/2017 11:14 PM, Chris Angelico wrote: Why do you need a pidfile? When I get systemd to start a process, I just have it not fork. Much easier. Forget about python-daemon - just run your script in the simple and straight-forward way. Because forking daemons was good enough for my grandpappy, and it ought to be good enough you young whippersnappers today. In other words ... facepalm. Thanks! -- Ian Pilcher arequip...@gmail.com "I grew up before Mark Zuckerberg invented friendship" -- https://mail.python.org/mailman/listinfo/python-list
python-daemon and PID files
Is it possible to get python-daemon to create "systemd style" PID file? I.e., systemd wants a daemon to write a file with a specific name that *contains* the PID of the child process. python-daemon, OTOH, seems to use its pidfile parameter as more of a lock file. Currently, I'm creating my PID file manually in the child process, but systemd complains, because it wants the PID file to exist before the parent exits. -- ============ Ian Pilcher arequip...@gmail.com "I grew up before Mark Zuckerberg invented friendship" -- https://mail.python.org/mailman/listinfo/python-list
Re: Noob confused by ConfigParser defaults
On 02/20/2017 03:45 AM, Peter Otten wrote: You can provide a default value in your code with parser = configparser.ConfigParser() parser.read(configfile) value = parser.get("section-1", "option-1", fallback="default value") Perfect. Thank you! -- ============ Ian Pilcher arequip...@gmail.com "I grew up before Mark Zuckerberg invented friendship" -- https://mail.python.org/mailman/listinfo/python-list
Re: Noob confused by ConfigParser defaults
On 02/20/2017 01:39 AM, Ben Finney wrote: I think you misinderstand the semantics of what ‘configparser’ expects https://docs.python.org/3/library/configparser.html#configparser-objects>: You are absolutely correct. Thank you! -- ==== Ian Pilcher arequip...@gmail.com "I grew up before Mark Zuckerberg invented friendship" -- https://mail.python.org/mailman/listinfo/python-list
Noob confused by ConfigParser defaults
I am trying to use ConfigParser for the first time (while also writing my first quasi-serious Python program). Assume that I want to parse a a configuration file of the following form: [section-1] option-1 = value1 option-2 = value2 [section-2] option-1 = value3 option-2 = value4 How do a set a default for option-1 *only* in section-1? -- Ian Pilcher arequip...@gmail.com "I grew up before Mark Zuckerberg invented friendship" -- https://mail.python.org/mailman/listinfo/python-list
Re: accessing elements of a tuple
Matthew Sacks wrote: > How can I access "DB" from the list directly using an index? list[0][1] ... or did I misunderstand your question? -- ======== Ian Pilcher arequip...@gmail.com -- http://mail.python.org/mailman/listinfo/python-list