Path: csiph.com!usenet.pasdenom.info!weretis.net!feeder1.news.weretis.net!feeder.erje.net!eu.feeder.erje.net!newsfeed.xs4all.nl!newsfeed2.news.xs4all.nl!xs4all!newsgate.cistron.nl!newsgate.news.xs4all.nl!post.news.xs4all.nl!not-for-mail Return-Path: X-Original-To: python-announce-list@python.org Delivered-To: python-announce-list@mail.python.org X-Spam-Status: OK 0.000 X-Spam-Evidence: '*H*': 1.00; '*S*': 0.00; 'tutorial': 0.03; 'package,': 0.03; 'root': 0.05; 'url:bitbucket': 0.05; 'attribute': 0.07; 'skip:` 10': 0.07; 'subject:released': 0.07; 'versions,': 0.07; 'string': 0.09; 'alias': 0.09; 'attributes': 0.09; 'classes.': 0.09; 'dependency': 0.09; 'imported': 0.09; 'namespace': 0.09; 'python': 0.11; '1.3.': 0.16; 'accessible,': 0.16; 'dictionaries': 0.16; 'exported': 0.16; 'imports': 0.16; 'means:': 0.16; 'namespace.': 0.16; 'pypy.': 0.16; 'pytest': 0.16; 'specifying': 0.16; 'sys.modules': 0.16; 'to:addr:python-announce- list': 0.16; 'underlying': 0.16; 'url:issues': 0.16; 'url:py': 0.16; 'value``': 0.16; 'fix': 0.17; 'users.': 0.18; "python's": 0.19; 'version.': 0.19; 'command': 0.22; '>>>': 0.22; 'example': 0.22; 'import': 0.22; 'tests': 0.22; 'install': 0.23; 'header :User-Agent:1': 0.23; 'entries': 0.24; 'example.': 0.24; 'helper': 0.24; 'package.': 0.24; 'skip:` 20': 0.24; 'specifies': 0.24; 'skip:" 30': 0.26; 'somewhere': 0.26; 'skip:" 20': 0.27; 'gets': 0.27; 'installed': 0.27; 'function': 0.29; 'skip:- 40': 0.29; 'respective': 0.29; 'url:mailman': 0.30; 'code': 0.31; 'lines': 0.31; "skip:' 10": 0.31; '1.3': 0.31; 'go.': 0.31; 'initialized': 0.31; 'loading': 0.31; 'file': 0.32; 'option': 0.32; 'regular': 0.32; 'skip:- 30': 0.32; 'another': 0.32; 'running': 0.33; 'addresses': 0.33; 'skip:_ 10': 0.34; 'common': 0.35; 'objects': 0.35; 'add': 0.35; 'version': 0.36; 'accessing': 0.36; 'raising': 0.36; 'url:listinfo': 0.36; 'url:org': 0.36; 'skip:- 20': 0.37; 'two': 0.37; 'list.': 0.37; 'system,': 0.38; 'handle': 0.38; 'needed': 0.38; 'files': 0.38; 'issue': 0.38; 'skip:- 10': 0.38; 'skip:_ 30': 0.39; 'channel': 0.39; 'obtain': 0.39; 'to:addr:python.org': 0.39; 'release': 0.40; 'skip:a 30': 0.61; 'new': 0.61; 'simple': 0.61; 'complete': 0.62; 'name': 0.63; 'different': 0.65; 'here': 0.66; 'containing': 0.69; 'default': 0.69; 'special': 0.74; 'completion': 0.78; 'introduce': 0.78; 'accessed.': 0.84; 'lazy': 0.91 From: Ronny Pfannschmidt To: Subject: apipkg 1.3 released Date: Mon, 16 Feb 2015 00:03:22 +0100 User-Agent: Trojita/v0.4.1-490-gfbd34bf; Qt/4.8.6; X11; Linux; Fedora release 21 (Twenty One) MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: quoted-printable X-Mailman-Approved-At: Mon, 16 Feb 2015 07:07:12 +0100 X-BeenThere: python-announce-list@python.org X-Mailman-Version: 2.1.15 Precedence: list Reply-To: python-list@python.org List-Id: Announcement-only list for the Python programming language List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Approved: python-announce-list@python.org Newsgroups: comp.lang.python.announce Message-ID: Lines: 111 NNTP-Posting-Host: 2001:888:2000:d::a6 X-Trace: 1424066833 news.xs4all.nl 2940 [2001:888:2000:d::a6]:58690 X-Complaints-To: abuse@xs4all.nl Xref: csiph.com comp.lang.python.announce:1575 Hello, i pleased to annouce the release of apipkg 1.3. Welcome to apipkg! ------------------------ With apipkg you can control the exported namespace of a python package and greatly reduce the number of imports for your users. It is a `small pure python module`_ that works on virtually all Python versions, including CPython2.3 to Python3.1, Jython and PyPy. It=20 co-operates well with Python's ``help()`` system, custom importers (PEP302) and common command line completion tools. Usage is very simple: you can require 'apipkg' as a dependency or you can copy paste the <200 Lines of code into your project. As extra it will automatically set package.__version__ to your distribution version. Tutorial example ------------------- Here is a simple ``mypkg`` package that specifies one namespace and exports two objects imported from different modules:: # mypkg/__init__.py import apipkg apipkg.initpkg(__name__, { 'path': { 'Class1': "_mypkg.somemodule:Class1", 'clsattr': "_mypkg.othermodule:Class2.attr", } } The package is initialized with a dictionary as namespace. You need to create a ``_mypkg`` package with a ``somemodule.py`` and ``othermodule.py`` containing the respective classes. The ``_mypkg`` is not special - it's a completely regular python package. Namespace dictionaries contain ``name: value`` mappings where the value may be another namespace dictionary or a string specifying an import location. On accessing an namespace attribute an import will be performed:: >>> import mypkg >>> mypkg.path >>> mypkg.path.Class1 # '_mypkg.somemodule' gets imported now >>> mypkg.path.clsattr # '_mypkg.othermodule' gets imported now 4 # the value of _mypkg.othermodule.Class2.attr The ``mypkg.path`` namespace and its two entries are loaded when they are accessed. This means: * lazy loading - only what is actually needed is ever loaded * only the root "mypkg" ever needs to be imported to get access to the complete functionality. * the underlying modules are also accessible, for example:: from mypkg.sub import Class1 Including apipkg in your package -------------------------------------- If you don't want to add an ``apipkg`` dependency to your package you can copy the `apipkg.py`_ file somewhere to your own package, for example ``_mypkg/apipkg.py`` in the above example. You then import the ``initpkg`` function from that new place and are good to go. .. _`small pure python module`: .. _`apipkg.py`: http://bitbucket.org/hpk42/apipkg/src/tip/apipkg.py Feedback? ----------------------- If you have questions you are welcome to * join the #pylib channel on irc.freenode.net * subscribe to the http://codespeak.net/mailman/listinfo/py-dev list. * create an issue on http://bitbucket.org/hpk42/apipkg/issues 1.3 ---------------------------------------- - fix issue2 - adapt tests on Jython - handle jython __pkgpath__ missabstraction when running python from jar=20 files - alias modules pointing to unimportable modules will return None for all their attributes instead of raising ImportError. This addresses python3.4 where any call to getframeinfo() can choke on sys.modules contents if pytest is not installed (because py.test.* imports it). - introduce apipkg.distribution_version(name) as helper to obtain the current version number of a package from install metadata its used by default with the package name - add an eagerloading option and eagerload automatically if bpython is used (workaround for their monkeypatching) -- Ronny