with statement - backport for Python 2.5 - python

I'd like to use with statement in Python 2.5 in some production code. It was backported, should I expect any problems (e.g. with availability/compatibility on other machines/etc)?
Is this code
from __future__ import with_statement
compatible with Python 2.6?

Yes, that statement is a no-operation in Python 2.6, so you can freely use it to make with a keyword in your 2.5 code as well, without affecting your code's operation in 2.6. This is in fact the general design intention of "importing from the future" in Python!

You can call this in Python 2.6 and 3.0/1 without problems (it's a no-op there).

with_statement wasn't back ported but implemented in Python 2.5. Adding new keywords or syntax can break existing applications. With Python the way they decided to handle this is allow people to opt-in to those features early so you can slowly transition your code over.
From http://python.org/doc/2.5.2/ref/future.html
A future statement is a directive to
the compiler that a particular module
should be compiled using syntax or
semantics that will be available in a
specified future release of Python.
The future statement is intended to
ease migration to future versions of
Python that introduce incompatible
changes to the language. It allows use
of the new features on a per-module
basis before the release in which the
feature becomes standard.
You can actually inspect futures to get information on when first supported, when the import isn't needed anymore, etc.
Python 2.5.1 (r251:54863, Apr 18 2007, 08:51:08) [MSC v.1310 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import __future__
>>> dir(__future__)
['CO_FUTURE_ABSOLUTE_IMPORT', 'CO_FUTURE_DIVISION', 'CO_FUTURE_WITH_STATEMENT', 'CO_GENERATOR_ALLOWED', 'CO_NESTED', '_Feature', '__all__', '__builtins__',
__doc__', '__file__', '__name__', 'absolute_import', 'all_feature_names', 'division', 'generators', 'nested_scopes', 'with_statement']
>>> __future__.with_statement
_Feature((2, 5, 0, 'alpha', 1), (2, 6, 0, 'alpha', 0), 32768)
>>>
I personally have been heavily using the with_statement in Python 2.5 for well over a year and have not had issues. I also transparently run that code with Python 2.6. There are some weird corner cases they have worked at cleaning up in the language, mostly related to cleanly and correctly compacting nested with statements.

Related

What is the replacement for python IN package?

I am trying to use a code which was written for python 2 and may run with python 3.6.0, but it does not run with python 3.6.4. It imports the IN module, and uses IN.IP_RECVERR. I tried to google it, but it is a 'bit' hard to find anything about a module called IN (naming fail?). To demonstrate in REPL, that it works in python 2, but not in 3.6.4:
$ python2
Python 2.7.14 (default, Jan 5 2018, 10:41:29)
[GCC 7.2.1 20171224] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import IN
>>> IN.IP_RECVERR
11
>>>
$ python3
Python 3.6.4 (default, Jan 5 2018, 02:35:40)
[GCC 7.2.1 20171224] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import IN
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ModuleNotFoundError: No module named 'IN'
>>>
What is the replacement for this IN module in newer versions of python 3?
This is presumably the private plat-linux/IN.py module, which was never intended to be used. There have been plans to remove these plat-* files for a few zillion years, but it looks like it finally happened in issue 28027 for 3.6. As mentioned in What's New in Python 3.6:
The undocumented IN, CDROM, DLFCN, TYPES, CDIO, and STROPTS modules have been removed. They had been available in the platform specific Lib/plat-*/ directories, but were chronically out of date, inconsistently available across platforms, and unmaintained. The script that created these modules is still available in the source distribution at Tools/scripts/h2py.py.
Most of the useful constants that are at least somewhat portable (as in you can expect them to be available and work the same on your old laptop's linux and your brand-new Galaxy's linux, if not on OS X or Solaris) have long been made available through other places in the stdlib.
I think this specific one you're looking for is an example of not completely useless, but not portable enough to put anywhere safe, because linux documents the existence of IP_RECVERR, but not its value. So, you really need the version from your own system's ip headers.
The way to do this safely, if you actually need the IN module, is to run Tools/scripts/h2py.py with the Python version you're using, on the specific platform you need. That will generate an IN.py from the appropriate headers on your system (or on your cross-compilation target), which you can then use on that system. If you want to distribute your code, you'd probably need to put a step to do that into the setup.py, so it'll be run at install time (and at wheel-building time for people who install pre-built wheels, but you may need to be careful to make sure the targets are specific enough).
If you don't need to be particularly portable, you just need to access the one value in a few scripts that you're only deploying on your laptop or your company's set of identical containers or the like, you may be better off hardcoding the values (with a nice scare comment explaining the details).

Python - Difference Between Windows SystemParametersInfoW vs SystemParametersInfoA Function

I have a quick question that I cannot seem to clarify, despite my research on Stack Overflow and beyond. My questions involves the Windows SystemParametersInfo function with its variants SystemParametersInfoW (Unicode) and SystemParametersInfoA (ANSI) in relation to a Python 3.x script.
In a Python script I am writing, I came across two different explanations into when to use these variants. This answer to a question says that for 64-bit machines you must use SystemParametersInfoW while for 32-bit machines you must use SystemParametersInfoA, thus you should run a function to determine which bit machine the script is running on. However, another answer here (and I've seen more people advocate for this type of answer) and here says that SystemParametersInfoW must be used with Python 3.x since it passes a Unicode string while SystemParametersInfoA is used for Python 2.x and below since it passes a byte string conducive with ANSI.
So what is the right answer here as I would need to proceed forward differently with my script? Again, I am using Python 3.5 so it would make sense that the second answer fits, however is there any truth in the bit of the machine being a factor between using SystemParametersInfoW and SystemParametersInfoA? Is it a mixture of both answers or should I go ahead and use SystemParametersInfoW regardless of whether it will be used on a 32 or 64 bit machine? Do I even need to determine the bit of the machine the script is running on? Thank you for your help in clarifying this issue!
Internally, Windows uses Unicode. The SystemParametersInfoA function converts ANSI parameter strings to Unicode and internally calls SystemParametersInfoW. You can call either from Python whether 32- or 64-bit, in Python 2.x or 3.x. Usually you want the W version to pass and retrieve Unicode strings since Windows is internally Unicode. The A version can lose information.
Example that works in Python 2 or 3, 32- or 64-bit. Note that the W version returns a Unicode string in the buffer, while the A version returns a byte string.
from __future__ import print_function
from ctypes import *
import sys
print(sys.version)
SPI_GETDESKWALLPAPER = 0x0073
dll = WinDLL('user32')
buf = create_string_buffer(200)
ubuf = create_unicode_buffer(200)
if dll.SystemParametersInfoA(SPI_GETDESKWALLPAPER,200,buf,0):
print(buf.value)
if dll.SystemParametersInfoW(SPI_GETDESKWALLPAPER,200,ubuf,0):
print(ubuf.value)
Output (Python 2.X 32-bit and Python 3.X 64-bit):
C:\>py -2 test.py
2.7.13 (v2.7.13:a06454b1afa1, Dec 17 2016, 20:42:59) [MSC v.1500 32 bit (Intel)]
c:\windows\web\wallpaper\theme1\img1.jpg
c:\windows\web\wallpaper\theme1\img1.jpg
C:\>py -3 test.py
3.6.1 (v3.6.1:69c0db5, Mar 21 2017, 18:41:36) [MSC v.1900 64 bit (AMD64)]
b'c:\\windows\\web\\wallpaper\\theme1\\img1.jpg'
c:\windows\web\wallpaper\theme1\img1.jpg
On Windows 3.x/95/98/ME it is likely that only SystemParametersInfoA works correctly. On all other systems both the A and W flavor will work regardless of the OS bitness.
Assuming you only support "recent" versions of Windows, you should just pick the flavor most comfortable for you to use in your language and that usually means the flavor that matches the default string type in your language.
If you want to support both Python v2 & v3 you would have to choose at run-time which function to call if you are using the default string type.

Python version Check (major attribute)

What does sys.version_info.major do?
I understand that sys.version_info returns the version of interpreter we are using. What role does major have to do in this?
How does it work in the following code?
import sys
if sys.version_info.major < 3:
#code here
else:
#code here
Python 3.5.1 (v3.5.1:37a07cee5969, Dec 5 2015, 21:12:44)
[GCC 4.2.1 (Apple Inc. build 5666) (dot 3)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import sys
>>> sys.version_info
sys.version_info(major=3, minor=5, micro=1, releaselevel='final', serial=0)
major can tell you whether it's python2 or python3. I guess it imports different libraries depends on the specific python versions.
I am using python 3.5.1, you can see the version_info about it.
Here's a trite example:
from __future__ import print_function
import sys
if sys.version_info.major<3:
input = raw_input # Python2 ~== eval(input())
else:
#code here
This makes Python 2.x behave a bit more like Python 3 ... the future import cannot be in the if suite because it must appear before other imports. But the changes in semantics for the input() builtin function between Python 2.x and Python 3 can handled in a conditional.
For the most part it's a bad idea to go much beyond this in your efforts to support Python2 and Python3 in the same file.
The more challenging changes between Python2 and Python3 relate to strings as bytes vs. the newer strings as Unicode; and thus the need to explicitly specify encodings and use bytes objects for many networking protocols and APIs.
For example, I have Python 3.5.3 installed on my computer. sys_version stores the following information:
sys.version_info(major=3, minor=5, micro=3, releaselevel='final', serial=0)
The reason version is split into major, minor and micro is that programmers writing code for multiple versions of Python may need to differentiate between them somehow. Most differences are between major versions 2 and 3 of Python and that explains the context of major usage in your code.

Why is python so much slower on windows?

I learned about pystones today and so I decided to see what my various environments were like. I ran pystones on my laptop that is running windows on the bare metal and got these results
Python 2.7.2 (default, Jun 12 2011, 15:08:59) [MSC v.1500 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> from test import pystone
>>> for i in range(0,10):
... pystone.pystones()
...
(1.636334799754252, 30556.094026423627)
(2.1157907919853756, 23631.82607155689)
(2.5324817108003685, 19743.479207278437)
(2.541626695533182, 19672.4405231788)
(2.536022267835051, 19715.915208695682)
(2.540327088340973, 19682.50475676099)
(2.544761766911506, 19648.20465716261)
(2.540296805235016, 19682.739393664764)
(2.533851636391205, 19732.804905346253)
(2.536483186973612, 19712.3325148696)
Then I ran it on some of our linux VMs and got 2.7-3.4 times better performance. So I fired up my vmware Linux VM on my laptop and reran the same test and got these results:
Python 2.7.2+ (default, Oct 4 2011, 20:03:08)
[GCC 4.6.1] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> for i in range(0,10):
... pystone.pystones()
...
(1.75, 28571.428571428572)
(1.17, 42735.042735042734)
(1.6600000000000001, 30120.48192771084)
(1.8399999999999999, 27173.913043478264)
(1.8200000000000003, 27472.52747252747)
(1.8099999999999987, 27624.30939226521)
(1.3099999999999987, 38167.938931297744)
(1.7800000000000011, 28089.88764044942)
(1.8200000000000038, 27472.527472527414)
(1.490000000000002, 33557.04697986573)
I can't quite understand how the linux VM running inside the same windows is actually FASTER than python running on the same bare metal under windows.
What is so different about python on windows that it performs slower on the bare OS than it does inside a VM running Linux on the same box?
More details
Windows platform Win7x64
32 bit python running on both platforms
32 bit linux VM running the windows platform in VMWare
Had similar problem on windows 10 - it was because of windows defender.
I had to exclude python directories and process in windows defender settings and restart computer.
Before: I had to wait like ~20 seconds to run any python code - now it's milliseconds.
I can't answer your question, however consider this list of things that could be making a difference:
You're using different versions of Python. "2.7.2+" indicates that your linux Python was built from a version control checkout rather than a release.
They were compiled with different compilers (and conceivably meaningfully different optimization levels).
You haven't mentioned reproducing this much. It's conceivable it was a fluke if you haven't.
Your VM might be timing inaccurately.
You're linking different implementations of Python's dependencies, notably libc as Ignacio Vazquez-Abrams points out.
I don't know what pystone's actual benchmarks are like, but many things work differently--things like unicode handling or disk IO could be system-dependent factors.
Do you run antivirus software on that Windows box? This perhaps could explain it. I personally like to add Python, Cygwin and my sources directory to antivirus exclusion list - I think I get a small, but noticeable speedup. Maybe that explains your results.
Benchmark your startup, but there are just simply some slow modules to initialize on windows. A tiny hack that saves me a second on startup every time:
import os
import mimetypes #mimetypes gets imported later in dep chain
if __name__ == "__main__":
# stub this out, so registry db wont ever be read, not needed
mimetypes._winreg = None
Another source of slowness is, multiple standard library modules compile and cache their regexes at import time. re.compile just looks like its slow on windows

Python __future__ outside of a specific module

In python 2.7, by using
from __future__ import division, print_function
I can now have print(1/2) showing 0.5.
However is it possible to have this automatically imported at python startup ?
I tried to use the sitecustomize.py special module but the inport is only valid inside the module and not in the shell.
As I'm sure people will ask why I need that : teaching Python to teenagers I noticed that the integer division was not easy for them so we decided to switch to Python 3. However one of the requirement of the course was to be able to plot function and Matplotlib is pretty good but only valid for Python 2.7.
So my idea was to use a custom 2.7 installation...not perfect but I don't have a better idea to have both Matplotlib and the new "natural" division "1/2=0.5".
Any advice or maybe a Matplotlib alternative that is working on python 3.2 ?
matplotlib on python 3 is closer than you may think: https://github.com/matplotlib/matplotlib-py3; http://www.lfd.uci.edu/~gohlke/pythonlibs/#matplotlib.
Why not use PYTHONSTARTUP instead of sitecustomize.py?
localhost-2:~ $ cat startup.py
from __future__ import print_function
from __future__ import division
localhost-2:~ $ export PYTHONSTARTUP=""
localhost-2:~ $ python
Python 2.7.2 (v2.7.2:8527427914a2, Jun 11 2011, 15:22:34)
[GCC 4.2.1 (Apple Inc. build 5666) (dot 3)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> 1/2
0
>>> print("fred",end=",")
File "<stdin>", line 1
print("fred",end=",")
^
SyntaxError: invalid syntax
>>> ^D
localhost-2:~ $ export PYTHONSTARTUP=startup.py
localhost-2:~ $ python
Python 2.7.2 (v2.7.2:8527427914a2, Jun 11 2011, 15:22:34)
[GCC 4.2.1 (Apple Inc. build 5666) (dot 3)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> 1/2
0.5
>>> print("fred",end=",")
fred,>>>
No need to compile a new version of Python 2.x. You can do this at start up.
As you found, sitecustomize.py does not work. This is because the from __future__ import IDENTIFIER isn't an import. It flags the module to be compiled under special rules. Any module that uses those features must have the __future__ import, as well as the interactive console.
The following shell command will start the interactive console with division and print_function active:
python -ic "from __future__ import division, print_function"
You could alias to python (on linux) or set up a launcher to hide the extra stuff.
If you are using IDLE, the PYTHONSTARTUP script #DSM suggests should work there as well.
Note that these are not global throughout the interpreter, it only affects the interactive console. Modules on the file-system must import from __future__ explicitly to use the feature. If this is an issue, I suggest making a template to base work off of with all the needed imports:
# True division
from __future__ import division
# Modules
import matplotlib
# ... code ...
def main():
pass
if __name__ == "__main__":
main()
This may not be practical, but you may be able to compile a custom Python with the Python 3 division behavior backported. The problem with this is matplotlib might require the Python 2 behavior (although I'm not sure).

Categories