[svn r63521] fix py.std docs and simplify its implementation (which is a 5 liner, anyway).
--HG-- branch : trunk
This commit is contained in:
parent
ff0bdb3076
commit
e84337d7cd
|
@ -6,76 +6,17 @@ Miscellaneous features of the py lib
|
||||||
Mapping the standard python library into py
|
Mapping the standard python library into py
|
||||||
===========================================
|
===========================================
|
||||||
|
|
||||||
After you have worked with the py lib a bit, you probably enjoy
|
The :api:`py.std` object allows lazy access to
|
||||||
the lazy importing feature, i.e. you only have to do ``import py`` and
|
standard library modules. For example, to get to the print-exception
|
||||||
work your way to your desired object. Using the full path
|
|
||||||
also ensures that there remains a focus on getting short paths
|
|
||||||
to objects.
|
|
||||||
|
|
||||||
The :api:`py.std` hook
|
|
||||||
----------------------
|
|
||||||
|
|
||||||
Of course, no matter what, everybody will continue to use the
|
|
||||||
python standard library because it is a very usable code base.
|
|
||||||
However, to properly support lazyness the py lib offers a way
|
|
||||||
to get to many standard modules without requiring "import"
|
|
||||||
statements. For example, to get to the print-exception
|
|
||||||
functionality of the standard library you can write::
|
functionality of the standard library you can write::
|
||||||
|
|
||||||
py.std.traceback.print_exc()
|
py.std.traceback.print_exc()
|
||||||
|
|
||||||
without having to do anything else than the usual ``import py``
|
without having to do anything else than the usual ``import py``
|
||||||
at the beginning. Note that not having imports for the
|
at the beginning. You can access any other top-level standard
|
||||||
`python standard library` obviously gets rid of the *unused
|
library module this way. This means that you will only trigger
|
||||||
import* problem. Modules only get imported when you actually
|
imports of modules that are actually needed. Note that no attempt
|
||||||
need them.
|
is made to import submodules.
|
||||||
|
|
||||||
Moreover, this approach resolves some of the issues stated in
|
|
||||||
`the relative/absolute import PEP-328`_, as with the above
|
|
||||||
approach you never have ambiguity problems. The above
|
|
||||||
traceback-usage is an absolute path that will not be
|
|
||||||
accidentally get confused with local names. (Well, never put
|
|
||||||
a file ``py.py`` in an importable path, btw, mind you :-)
|
|
||||||
|
|
||||||
Automagically accessing sub packages doesn't work (yet?)
|
|
||||||
--------------------------------------------------------
|
|
||||||
|
|
||||||
If you use the :api:`py.std` hook you currently cannot magically
|
|
||||||
import nested packages which otherwise need explicit imports of
|
|
||||||
their sub-packages. For example, the suversion bindings
|
|
||||||
require you to do something like::
|
|
||||||
|
|
||||||
import svn.client
|
|
||||||
|
|
||||||
If you just do the naive thing with the py lib, i.e. write
|
|
||||||
``py.std.svn.client`` it will not work unless you previously
|
|
||||||
imported it already. The py lib currently doesn't try to
|
|
||||||
magically make this work. The :api:`py.std` hook really is
|
|
||||||
intended for Python standard modules which very seldomly (if
|
|
||||||
at all) provide such nested packages.
|
|
||||||
|
|
||||||
**Note that you may never rely** on module identity, i.e.
|
|
||||||
that ``X is py.std.X`` for any ``X``. This is to allow
|
|
||||||
us later to lazyly import nested packages. Yes, lazyness
|
|
||||||
is hard to resist :-)
|
|
||||||
|
|
||||||
Note: you get an AttributeError, not an ImportError
|
|
||||||
---------------------------------------------------
|
|
||||||
|
|
||||||
If you say ``py.std.XYZ`` and importing ``XYZ`` produces an
|
|
||||||
``ImportError`` , it will actually show up as an
|
|
||||||
``AttributeError``. It is deemed more important to adhere to
|
|
||||||
the standard ``__getattr__`` protocol than to let the
|
|
||||||
``ImportError`` pass through. For example, you might want to
|
|
||||||
do::
|
|
||||||
|
|
||||||
getattr(py.std.cStringIO, 'StringIO', py.std.StringIO.StringIO)
|
|
||||||
|
|
||||||
and you would expect that it works. It does work although it will
|
|
||||||
take away some lazyness because ``py.std.StringIO.StringIO`` will
|
|
||||||
be imported in any case.
|
|
||||||
|
|
||||||
.. _`the relative/absolute import PEP-328`: http://www.python.org/peps/pep-0328.html
|
|
||||||
|
|
||||||
Support for interaction with system utilities/binaries
|
Support for interaction with system utilities/binaries
|
||||||
======================================================
|
======================================================
|
||||||
|
|
|
@ -2,18 +2,11 @@
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
class Std(object):
|
class Std(object):
|
||||||
""" makes all standard python modules available as a lazily
|
""" lazily import standard modules """
|
||||||
computed attribute.
|
|
||||||
"""
|
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.__dict__ = sys.modules
|
self.__dict__ = sys.modules
|
||||||
|
|
||||||
def __getattr__(self, name):
|
def __getattr__(self, name):
|
||||||
try:
|
return __import__(name)
|
||||||
m = __import__(name)
|
|
||||||
except ImportError:
|
|
||||||
raise AttributeError("py.std: could not import %s" % name)
|
|
||||||
return m
|
|
||||||
|
|
||||||
std = Std()
|
std = Std()
|
||||||
|
|
|
@ -6,7 +6,7 @@ def test_os():
|
||||||
assert py.std.os is os
|
assert py.std.os is os
|
||||||
|
|
||||||
def test_import_error_converts_to_attributeerror():
|
def test_import_error_converts_to_attributeerror():
|
||||||
py.test.raises(AttributeError, "py.std.xyzalskdj")
|
py.test.raises(ImportError, "py.std.xyzalskdj")
|
||||||
|
|
||||||
def test_std_gets_it():
|
def test_std_gets_it():
|
||||||
for x in py.std.sys.modules:
|
for x in py.std.sys.modules:
|
||||||
|
|
Loading…
Reference in New Issue