[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
|
||||
===========================================
|
||||
|
||||
After you have worked with the py lib a bit, you probably enjoy
|
||||
the lazy importing feature, i.e. you only have to do ``import py`` and
|
||||
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
|
||||
The :api:`py.std` object allows lazy access to
|
||||
standard library modules. For example, to get to the print-exception
|
||||
functionality of the standard library you can write::
|
||||
|
||||
py.std.traceback.print_exc()
|
||||
|
||||
without having to do anything else than the usual ``import py``
|
||||
at the beginning. Note that not having imports for the
|
||||
`python standard library` obviously gets rid of the *unused
|
||||
import* problem. Modules only get imported when you actually
|
||||
need them.
|
||||
|
||||
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
|
||||
at the beginning. You can access any other top-level standard
|
||||
library module this way. This means that you will only trigger
|
||||
imports of modules that are actually needed. Note that no attempt
|
||||
is made to import submodules.
|
||||
|
||||
Support for interaction with system utilities/binaries
|
||||
======================================================
|
||||
|
|
|
@ -2,18 +2,11 @@
|
|||
import sys
|
||||
|
||||
class Std(object):
|
||||
""" makes all standard python modules available as a lazily
|
||||
computed attribute.
|
||||
"""
|
||||
|
||||
""" lazily import standard modules """
|
||||
def __init__(self):
|
||||
self.__dict__ = sys.modules
|
||||
|
||||
def __getattr__(self, name):
|
||||
try:
|
||||
m = __import__(name)
|
||||
except ImportError:
|
||||
raise AttributeError("py.std: could not import %s" % name)
|
||||
return m
|
||||
return __import__(name)
|
||||
|
||||
std = Std()
|
||||
|
|
|
@ -6,7 +6,7 @@ def test_os():
|
|||
assert py.std.os is os
|
||||
|
||||
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():
|
||||
for x in py.std.sys.modules:
|
||||
|
|
Loading…
Reference in New Issue