Re: How to pass Python command line options (vs arguments) when running script directly vs via Python interpreter?
On 2018-08-16 01:05, Chris Angelico wrote: > On Thu, Aug 16, 2018 at 8:51 AM, Cameron Simpson wrote: >> And as an additional alternative, when I want something weird (extra python >> args or the like) I usually make my script.py into a module and invoke it >> via a shell script, eg: >> >> #!/bin/sh >> exec /particular/python python-opts... -m script_module ${1+"$@"} >> >> Obviously that'd need a little adaption under Windows. > > Since an executable file without a shebang should normally be invoked > through /bin/sh, you can actually combine this technique into the > script itself with a cool hack: Well, sorta. Executable text files without a shebang line are not executable per se, but most shells pretend they are. If you try to run a shebang-less script through, say, Python's subprocess module, it won't work. > > > exec /usr/local/bin/python3 -x -W error $0 "$@" > """ > This is an example script. > > It is executable and will invoke itself through Python. > """ > import warnings > warnings.warn("This should be an error.") > print("This shouldn't happen.") > > > The "-x" parameter means "skip the first line", and in a sense, the > exec line is a non-standard shebang. :) -- https://mail.python.org/mailman/listinfo/python-list
Re: How to pass Python command line options (vs arguments) when running script directly vs via Python interpreter?
On Thu, Aug 16, 2018 at 8:32 PM, Thomas Jollans wrote: > On 2018-08-16 01:05, Chris Angelico wrote: >> On Thu, Aug 16, 2018 at 8:51 AM, Cameron Simpson wrote: >>> And as an additional alternative, when I want something weird (extra python >>> args or the like) I usually make my script.py into a module and invoke it >>> via a shell script, eg: >>> >>> #!/bin/sh >>> exec /particular/python python-opts... -m script_module ${1+"$@"} >>> >>> Obviously that'd need a little adaption under Windows. >> >> Since an executable file without a shebang should normally be invoked >> through /bin/sh, you can actually combine this technique into the >> script itself with a cool hack: > > Well, sorta. Executable text files without a shebang line are not > executable per se, but most shells pretend they are. If you try to run a > shebang-less script through, say, Python's subprocess module, it won't work. Good point. Still, for a lot of situations, it does allow you to invoke the .py file. I wonder if there's some sort of sneaky way to make the exec line appear as a comment to Python - probably involving quoting rules. ChrisA -- https://mail.python.org/mailman/listinfo/python-list
Re: Pylint false positives
On 2018-08-14 04:58 AM, Frank Millman wrote: > "D'Arcy Cain" wrote in message >> I am also getting a funny smell from your description. Are you sure >> that you need to redefine the methods? Perhaps you just need to define >> some class variables and use one method. You can also define your own >> method and call the classA method inside it for common functionality. > > As an example, I have a master class defining a unit of data (i.e. the > value of a column) retrieved from a database. I have separate > sub-classes for each data type - text, integer, date, etc. To ensure > that a value is valid before storing it as an instance attribute, I call > a method called 'check_value'. The details of check_value vary according > to the data type, but that is transparent to the piece of code that > calls check_value(). class classA: DATATYPE = None # Or default type def check_value(self, v) if not isinstance(v, self.DATATYPE): raise RuntimeError("Invalid data type for '%s'" % v) class classB(classA): DATATYPE = int Very simplistic and untested but does that give you any ideas? Hopefully your email client doesn't mess up the formatting. You can fill out check_value to do more than simply check the the type matches and you can also do further checks based on the type. Also, you can have more than one sub-class doing the same check without having to cut and paste code from another class. -- D'Arcy J.M. Cain Vybe Networks Inc. http://www.VybeNetworks.com/ IM:da...@vex.net VoIP: sip:da...@vybenetworks.com -- https://mail.python.org/mailman/listinfo/python-list
Re: How to pass Python command line options (vs arguments) when running script directly vs via Python interpreter?
On 2018-08-16 14:33, Chris Angelico wrote: > On Thu, Aug 16, 2018 at 8:32 PM, Thomas Jollans wrote: >> On 2018-08-16 01:05, Chris Angelico wrote: >>> On Thu, Aug 16, 2018 at 8:51 AM, Cameron Simpson wrote: And as an additional alternative, when I want something weird (extra python args or the like) I usually make my script.py into a module and invoke it via a shell script, eg: #!/bin/sh exec /particular/python python-opts... -m script_module ${1+"$@"} Obviously that'd need a little adaption under Windows. >>> >>> Since an executable file without a shebang should normally be invoked >>> through /bin/sh, you can actually combine this technique into the >>> script itself with a cool hack: >> >> Well, sorta. Executable text files without a shebang line are not >> executable per se, but most shells pretend they are. If you try to run a >> shebang-less script through, say, Python's subprocess module, it won't work. > > Good point. Still, for a lot of situations, it does allow you to > invoke the .py file. I wonder if there's some sort of sneaky way to > make the exec line appear as a comment to Python - probably involving > quoting rules. Easy as pie: (with an extra line) '''exec' /usr/bin/env python3 -u -E -W error "$0" "$@" ''' import sys print('hello', sys.executable) -- https://mail.python.org/mailman/listinfo/python-list
Re: lxml namespace as an attribute
> You seem to think that you need to take the namespace definitions > from the XML document itself. This is not the case: you can > provide them from whatever soure you want. I was under the impression that XML was a self-describing format. I've been disabused of that notion. Skip -- https://mail.python.org/mailman/listinfo/python-list
printing to stdout
I can run a shell script from the commandline as root in which I start a python script as user "ha". The output to stdout and stderr generated by the python script is visible in an xterm: #!/bin/dash exec 2>&1 chpst -u ha:ha:i2c -U ha /usr/local/ha/init.sh exec chpst -u ha:ha:i2c:gpio /usr/local/ha/wait4int.py So far so good. But when I run the script supervised by runit, I can see the output generated by the shell script "init.sh", but the output of the python script is not transferred to the supervised logging. The python script itself works, it reads out some I/O expanders on a Raspberry Pi. But the output of the "print" commands seems to disappear: [..] while True: if GPIO.input(23) == 1: # if still 0, another event has occurred GPIO.wait_for_edge(23, GPIO.FALLING) print ('---') while GPIO.input(23) == 0: for pcf in pcf_present: output = bus.read_byte(pcf) print ("%x: %x" % (pcf, output)) if GPIO.input(23) == 1: loopcntr = 0 break else: loopcntr += 1 if loopcntr >=20: print ('[ALERT] possible INT loop, disable 10 seconds') sleep (10) GPIO.cleanup() Anyone a hint? Note: I'm a newbie to python. -- richard lucassen http://contact.xaq.nl/ -- https://mail.python.org/mailman/listinfo/python-list
Re: printing to stdout
On 16Aug2018 22:37, richard lucassen wrote: I can run a shell script from the commandline as root in which I start a python script as user "ha". The output to stdout and stderr generated by the python script is visible in an xterm: #!/bin/dash exec 2>&1 chpst -u ha:ha:i2c -U ha /usr/local/ha/init.sh exec chpst -u ha:ha:i2c:gpio /usr/local/ha/wait4int.py So far so good. But when I run the script supervised by runit, I can see the output generated by the shell script "init.sh", but the output of the python script is not transferred to the supervised logging. The python script itself works, it reads out some I/O expanders on a Raspberry Pi. But the output of the "print" commands seems to disappear: [...] This isn't specific to Python, you'll find it with most programmes. (The shell's builtin "echo" command is an exception.) Some discussion: most output streams are buffered: this means that when you issue some kind of "write" operation to them, the output data are copied to a buffer area in memory, and only actually written out to the operating system (which mediates the data between programmes) at certain times. This reduces the OS level data transfers, which is generally a performance win overall. When are the data sent on to the OS? That depends on the buffered arrangement. When the buffer fills, the data are always sent on because otherwise there's no room for more data. But otherwise, the data are sent on at specific times. An unbuffered stream sends the data on immediately. The standard error stream is usually unbuffered, so that error messages get out immediately. A fully buffered stream is sent on only when the buffer fills. A line buffered stream is sent on when a newline lands in the buffer. You can of course devise whatever system you like, but these three are the common presupplied automatic ones. Also, you can usually force any buffered data to be send on by flushing the buffer. On UNIX systems, the _default_ behaviour of the standard output stream depends on what it is connected to. Stdout is line buffered when connected to a terminal and fully buffered otherwise. This generally makes for nice interactive behaviour (you see timely output when working interactively) and better overall performance when the output is going to a file or a pipe. So let's look at your script: print ("%x: %x" % (pcf, output)) [...] print ('[ALERT] possible INT loop, disable 10 seconds') Your programme will be writing into a buffer. Your messages only go out when enough have accrued to fill the buffer. To force te messages to go out in a timely manner you need to flush the buffer. You have two choices here: call sys.stdout.flush() or pass "flush=True" with the print call, eg: print(, flush=True) Just looking at your loop I would be inclined to just call flush once at the bottom, _before_ the sleep() call: sys.stdout.flush() Your call; the performance difference will be small, so it tends to come down to keeping your code readable and maintainable. Cheers, Cameron Simpson -- https://mail.python.org/mailman/listinfo/python-list
Re: Program to output a subset of the composite numbers
Thanks, I think that is an interesting tactic. From there what might the language look like to filter out the composites that are not one less than twice another composite number? -- https://mail.python.org/mailman/listinfo/python-list
Re: Program to output a subset of the composite numbers
DATA 15, 27, 35, 39, 49, 50, 51, 55, 63, 65, 69, 75, 77, 87, 91, 95, 99, 111, 115, 119, 123, 125, 129, 135, 143, 147, 153, 155, 159, 161, 169, 171, 175, 183, 185, 187, 189, 195, 203, 207, 209, 215, 219, 221 -- https://mail.python.org/mailman/listinfo/python-list
Re: Program to output a subset of the composite numbers
I'm sorry I did not correctly state the subset I was after: "Composite numbers that are one less than twice a composite." The output would begin: DATA 15, 27, 35, 39, 49, 50, 51, 55, 63, 65, 69, 75, 77, 87, 91, 95, 99, 111, 115, 119, 123, 125, 129, 135, 143, 147, 153, 155, 159, 161, 169, 171, 175, 183, 185, 187, 189, 195, 203, 207, 209, 215, 219, 221 -- https://mail.python.org/mailman/listinfo/python-list
Re: Program to output a subset of the composite numbers
Yes, I will try it! Thank you kindly. -- https://mail.python.org/mailman/listinfo/python-list
Re: Pylint false positives
"D'Arcy Cain" wrote in message news:6b4b8587-46c0-19b0-c538-efdf396f0...@vybenetworks.com... On 2018-08-14 04:58 AM, Frank Millman wrote: > As an example, I have a master class defining a unit of data (i.e. the > value of a column) retrieved from a database. I have separate > sub-classes for each data type - text, integer, date, etc. To ensure > that a value is valid before storing it as an instance attribute, I call > a method called 'check_value'. The details of check_value vary according > to the data type, but that is transparent to the piece of code that > calls check_value(). class classA: DATATYPE = None # Or default type def check_value(self, v) if not isinstance(v, self.DATATYPE): raise RuntimeError("Invalid data type for '%s'" % v) class classB(classA): DATATYPE = int Very simplistic and untested but does that give you any ideas? Hopefully your email client doesn't mess up the formatting. You can fill out check_value to do more than simply check the the type matches and you can also do further checks based on the type. Also, you can have more than one sub-class doing the same check without having to cut and paste code from another class. Thanks, D'Arcy. That is a neat idea if all you want to do is check the data type, but I do a lot more than that. How would you extend it without a long chain of if isinstance(v, str): [perform checks for str] elif isinstance(v, int) [perform checks for int] etc etc I find that using a separate method per subclass does exactly what I want, and that part of my project has been working stably for some time. The only thing that has changed is that I recently started using pylint (as a result of switching my editor to VS Code). My main class has the following method (simplified) - class Field: def setval(self, value): # handle value received from external source """ checkval is a method defined in each subclass it does a bit of typecasting, so value is replaced on return it can raise an exception, which is caught elsewhere """ value = self.checkval(value) # this is the line that pylint complains about [various other checks] if all checks are passed: self._value = value Frank -- https://mail.python.org/mailman/listinfo/python-list
Re: Pylint false positives
On Wed, 15 Aug 2018 10:44:57 +, Jon Ribbens wrote: > Obviously what I'm objecting to is not the presence of a loop, it's the > presence of many obscure, bodgey and/or broken features all lumped > together: > * using @abstractmethod without metaclass=ABCMeta I'll cop to that one -- it was a bug in my made-up pseudo-code. I simply assumed that people would know you need to use ABCMeta. Meap culpa. On the other hand, your objection to the following three idioms is as good an example of the Blurb Paradox as I've ever seen. Python is designed to do these sorts of things. Failing to use them when it simplifies your code is like hiring a fork-lift to lift and turn your car around because using reverse gear is "obscure, bodgey and/or broken". > * code running directly under the class definition > * creating a method then changing its name with foo.__name__ > * poking things into to the class namespace with locals() Each of these are standard Python techniques, utterly unexceptional. "Code running directly under the class" describes every use of the class keyword (except those with an empty body). If you write: class Spam: x = 1 you are running code under the class. This is not just a pedantic technicality, it is fundamental to Python's execution model. If someone does not understand this fact, they don't understand Python. The Python interpreter goes to great lengths to insert the class namespace into the execution scope while executing code under the class body, and has done so since Python 1.5 or older, even before it had lexical scoping! [steve@ando ~]$ python1.5 Python 1.5.2 (#1, Aug 27 2012, 09:09:18) [GCC 4.1.2 20080704 (Red Hat 4.1.2-52)] on linux2 Copyright 1991-1995 Stichting Mathematisch Centrum, Amsterdam >>> x = 23 >>> class Spam: ... x = 42 ... y = x + 1 ... >>> print x, Spam.x, Spam.y 23 42 43 "Creating a method then changing its name" -- that's precisely what we do anytime we create a closure and modify it using functools.wraps. The only difference is that wraps hides that behind a decorator. Some of us have been using Python long enough to remember when the standard idiom for decorating a function was to manually adjust its name, docstring etc: # Something like this. def decorate(func): def inner(arg): preprocess() x = func(arg) postprocess() return x inner.__name__ = func.__name__ inner.__doc__ = func.__doc__ inner.__dict__.update(func.__dict__) return inner Now functools.wraps hides all that behind a convenient decorator interface, but we're still changing the name. If you *don't* change the function's name, you're effectively populating your code with functions that might as well be anonymous, or at least have generic names like "inner". Why would you not give your functions meaningful names, just because they came out of a factory? "Poking things into the class namespace with locals()" -- I'll admit that this one is a little rarer. But again, the interpreter goes to deliberate lengths to ensure that locals in a class body is available for writing. If we're not supposed to use locals, why do you think Python makes it available? Its not like writing to locals inside a class is any more bizarre than using getattr, its just less common. Not one of those three techniques is "bodgey and/or broken", and if you think they're obscure, well, I'm sorry but that says more about the breadth of your Python knowledge than the feature itself. Nobody calling themselves an experienced Python programmer ought to have any trouble reading and maintaining code like that I showed. If they do, they have a serious hole in their knowledge of the language, like a C programmer who doesn't get pointers. > * dynamically adding @abstractmethod methods to a class I simply don't get this objection at all. All methods are added dynamically to classes (that's how Python's execution model works, def is an executable statement not a declaration). Making them abstract doesn't change this. You might be thinking of the warning in the docs: "Dynamically adding abstract methods to a class, [...] [is] not supported." but that is talking about the case where you add the method to the class after the class is created, from the outside: class X(metaclass=ABCMeta): def method(self): pass # Doesn't work. X.method = abstractmethod(X.method) But this works exactly as you would expect: py> class Foo(metaclass=abc.ABCMeta): ... for name in ('spam', 'eggs'): ... @abc.abstractmethod ... def inner(self): pass ... inner.__name__ = name ... locals()[name] = inner ... del inner ... py> class Bar(Foo): ... pass ... py> Bar() Traceback (most recent call last): File "", line 1, in TypeError: Can't instantiate abstract class Bar with abstract methods eggs, spam > (Not to mention your code mean
Re: Pylint false positives
On Fri, 17 Aug 2018 08:14:02 +0200, Frank Millman wrote: > How would you extend it without a long chain of > if isinstance(v, str): > [perform checks for str] > elif isinstance(v, int) > [perform checks for int] > etc > etc > > I find that using a separate method per subclass does exactly what I > want, and that part of my project has been working stably for some time. You might consider using single dispatch instead: https://docs.python.org/3/library/functools.html#functools.singledispatch -- Steven D'Aprano "Ever since I learned about confirmation bias, I've been seeing it everywhere." -- Jon Ronson -- https://mail.python.org/mailman/listinfo/python-list