From tim_one@email.msn.com Sun Jan 2 05:52:34 2000 From: tim_one@email.msn.com (Tim Peters) Date: Sun, 2 Jan 2000 00:52:34 -0500 Subject: [Python-Dev] Re: [Distutils] Questions about distutils strategy In-Reply-To: <199912091617.LAA05742@eric.cnri.reston.va.us> Message-ID: <000401bf54e5$91587280$1f2d153f@tim> Briefly backtracking to an old thread: [Guido] > ... > The problem lies in which key is used. All versions of > Python 1.5.x (1.5, 1.5.1, 1.5.2) use the same key! This > is a main cause of trouble, because it means that different > versions cannot peacefully live together even if the user > installs them into different directories -- they will all > use the registry keys of the last version installed. This, > in turn, means that someone who writes a Python application > that has a dependency on a particular Python version (and > which application worth distributing doesn't :-) cannot > trust that if a Python installation is present, it is the > right one. But they also cannot simply bundle the standard > installer for the correct Python version with their program, > because its installation would overwrite an existing Python > application, thus breaking some *other* Python apps that > the user might already have installed. Right, that's one class of intractable problem under Windows. *Inside* my workplace, another kind of problem is caused when people try to make a Python app available over the Windows network. They stick the Python they want and its libraries out on the network, with python.exe in the same directory as the app. Now some people have highly customized Python setups, and the network Python picks up "the wrong" site.py etc. That sucks, and there appears no sane way to stop it. Telling internal app distributors they need to invent a unique registry key and fiddle their python.exe's resources is a non-starter. Ditto telling people with highly customized Pythons "don't do that". Ditto telling anyone they have to run any sort of installation script just to use a network app (sometimes they don't even know they're running it! e.g., when it's a subsystem invoked by another app). So while everyone is thinking about the hardest possible scenarios, please give a thought to the dirt simple one too <0.5 wink>: an app distributor who knows exactly what they're doing, and for whom *any* magical inference is simply a barrier to overcome. The latter can be satisfied by any number of means, from an envar that says "please don't try to be helpful, *this* is the directory you look in, and if you don't find stuff there give up" to a cmdline switch that says the same. Nothing Windows-specific there -- any OS with an envar or a cmdline will play along . > ... > I thought a bit about how VB solves this. I think that when > you wrap up a VB app in, all the support code (mostly a big > DLL) is wrapped with it. When the user runs the installer, > the DLL is installed (probably in the WINDOWS directory). If > a user installs several VB apps built with the same VB > version, they all attempt to install the exact same DLL; of > course the installers notice this and optimize it away, keeping > a reference count. This is the way most *MS* DLLs work; stuff like the C runtime libraries and MS database drivers work exactly the same way. It's rare for pkgs other than MS's to attempt to use this mechanism, though (the reason is given below). > (Ignoring for now the fact that those reference counts don't > always work!) ? They work very well, in my experience. Where they fail is when installers & uninstallers break the rules. MS publishes the list of MS DLLs that are to be treated this way: an installer "must" use refcounting on the DLLs in the list. Alas, some (especially older) installation pkgs don't. Then the refcounts get screwed up. That's what makes the mechanism brittle: "the system" doesn't enforce it, it relies on universal & intelligent cooperation. It's very likely that someone distributing a Python app will neglect (out of ignorance) to bump the refcount on their Python components, so the refcount will be artificially low, and a later uninstall of some unrelated pkg that *did* follow the rules will merrily delete Python. Gordon and I will repeat this until it sinks in : almost everyone with a successful Windows product ships the non-MS DLLs they rely on and copies them into their own app directory. It's simple and it works; alternatives are complicated and don't work. Many even ship & copy MS DLLs (e.g., Scriptics copies its own msvcrt.dll (the MS C runtime) into Tcl's directories). Worrying about space consumed by redundant Python components is a bad case of premature optimization <0.3 wink>. > ... > How can we do something similar for Python? Seriously, short of getting MS to distribute Python and put the Python DLLs on The List of refcounted resources, we should pursue this line reluctantly if at all. MS may have a better scheme in the future, but for now better safe than sorry. a-couple-mb-on-a-modern-pc-isn't-worth-the-time-it-took- to-read-this-ly y'rs - tim From gstein@lyra.org Mon Jan 3 02:53:24 2000 From: gstein@lyra.org (Greg Stein) Date: Sun, 2 Jan 2000 18:53:24 -0800 (PST) Subject: [Python-Dev] new imputil.py Message-ID: This message is in MIME format. The first part should be readable text, while the remaining parts are likely unreadable without MIME-aware tools. Send mail to mime@docserver.cac.washington.edu for more info. --1658348780-1657214722-946868004=:412 Content-Type: TEXT/PLAIN; charset=US-ASCII Happy New Year! I've attached a new imputil.py to this message. It isn't posted on my page yet, as I'd like some feedback before declaring this new version viable. In this imputil, there is an ImportManager class. It gets installed as the import hook, with the presumption that it is the only import hook (technically, it could chain, but I've disabled that for now). I think Python 1.6 should drop the __import__ builtin and move to something like sys.import_hook (to allow examination and change). Another alternative would be sys.get_import_hook() and sys.set_import_hook(). [ I don't think we would want a "set" that returned the old version as the only way to get the current hook function; we want to be able to easily find the ImportManager instance. ] The ImportManager knows how to scan sys.path when it needs to find a top-level module/package (e.g. given a.b.c, the "a" is the top-level; b.c falls "below" that). sys.path can contain strings which specify a filesystem directory, or it can contain Importer instances. The manager also records an ordered list of suffix/importer pairs. The add_suffix() method is used to append new suffixes, but clients can also access the .suffixes attribute for fine-grained manipulation/ordering. There is a new importer called _FilesystemImporter which understands how to look into a directory for Python modules. It borrows/refers to the ImportManager's .suffixes attribute, using that to find modules in a directory. This is also the Importer that gets associated with each filesystem-based module. The importers used for suffix-based importing are derived from SuffixImporter. While a function could be used here, future changes will be easier if we presume class instances. The new imputil works fine (use _test_revamp() to switch to the new import mechanism). Importer subclasses using the old imputil should continue to work, although I am deprecating the 2-tuple return value for get_code(). get_code() should return None or the 3-tuple form now. I think I still have a bit more work to do, to enable something like "import a.b.c" where a.zip is an archive on the path and "b.c" resides in the archive. Note: it *is* possible to do sys.path.append(ZipImporter(filename)) and have "a.b.c" in the Zip file. It would simply be nicer to be able to drop arbitrary .zip files onto the path and use their basename as the top-level name of a package. Anyhow: I haven't looked at this scenario yet to find what the new system is missing (if anything). As always: feedback is more than appreciated! Especially from people using imputil today. Did I break anything? Does the new scheme still feel right to you? etc. Cheers, -g p.s. I'd also like to remove PackageArchiveImporter and PackageArchive. They don't seem to add any real value. I might move DirectoryImporter and PathImporter to an "examples" file, too. -- Greg Stein, http://www.lyra.org/ --1658348780-1657214722-946868004=:412 Content-Type: TEXT/PLAIN; charset=US-ASCII; name="imputil.py" Content-Transfer-Encoding: BASE64 Content-ID: Content-Description: Content-Disposition: attachment; filename="imputil.py" Iw0KIyBpbXB1dGlsLnB5DQojDQojIFdyaXR0ZW4gYnkgR3JlZyBTdGVpbi4g UHVibGljIERvbWFpbi4NCiMgTm8gQ29weXJpZ2h0LCBubyBSaWdodHMgUmVz ZXJ2ZWQsIGFuZCBubyBXYXJyYW50aWVzLg0KIw0KIyBVdGlsaXRpZXMgdG8g aGVscCBvdXQgd2l0aCBjdXN0b20gaW1wb3J0IG1lY2hhbmlzbXMuDQojDQoj IEFkZGl0aW9uYWwgbW9kaWZpY2F0aW9ucyB3ZXJlIGNvbnRyaWJlZCBieSBN YXJjLUFuZHJlIExlbWJ1cmcgYW5kDQojIEdvcmRvbiBNY01pbGxhbi4NCiMN CiMgVGhpcyBtb2R1bGUgaXMgbWFpbnRhaW5lZCBieSBHcmVnIGFuZCBpcyBh dmFpbGFibGUgYXQ6DQojICAgIGh0dHA6Ly93d3cubHlyYS5vcmcvZ3JlZy9w eXRob24vaW1wdXRpbC5weQ0KIw0KIyBTaW5jZSB0aGlzIGlzbid0IGluIHRo ZSBQeXRob24gZGlzdHJpYnV0aW9uIHlldCwgd2UnbGwgdXNlIHRoZSBDVlMg SUQNCiMgZm9yIHRyYWNraW5nOg0KIyAgICRJZDogaW1wdXRpbC5weSx2IDEu OSAyMDAwLzAxLzAzIDAyOjM4OjI5IGdzdGVpbiBFeHAgJA0KIw0KDQojIG5v dGU6IGF2b2lkIGltcG9ydGluZyBub24tYnVpbHRpbiBtb2R1bGVzDQppbXBv cnQgaW1wDQppbXBvcnQgc3lzDQppbXBvcnQgc3Ryb3ANCmltcG9ydCBfX2J1 aWx0aW5fXw0KDQojIGZvciB0aGUgRGlyZWN0b3J5SW1wb3J0ZXINCmltcG9y dCBzdHJ1Y3QNCmltcG9ydCBtYXJzaGFsDQoNCl9TdHJpbmdUeXBlID0gdHlw ZSgnJykNCl9Nb2R1bGVUeXBlID0gdHlwZShzeXMpDQoNCmNsYXNzIEltcG9y dE1hbmFnZXI6DQogICJNYW5hZ2UgdGhlIGltcG9ydCBwcm9jZXNzLiINCg0K ICBkZWYgaW5zdGFsbChzZWxmKToNCiAgICAjIyMgd2FybmluZzogUHl0aG9u IDEuNiB3aWxsIGhhdmUgYSBkaWZmZXJlbnQgaG9vayBtZWNoYW5pc207IHRo aXMNCiAgICAjIyMgY29kZSB3aWxsIG5lZWQgdG8gY2hhbmdlLg0KICAgIHNl bGYuX19jaGFpbl9pbXBvcnQgPSBfX2J1aWx0aW5fXy5fX2ltcG9ydF9fDQog ICAgc2VsZi5fX2NoYWluX3JlbG9hZCA9IF9fYnVpbHRpbl9fLnJlbG9hZA0K ICAgIF9fYnVpbHRpbl9fLl9faW1wb3J0X18gPSBzZWxmLl9pbXBvcnRfaG9v aw0KICAgICMjIyBmaXggdGhpcw0KICAgICNfX2J1aWx0aW5fXy5yZWxvYWQg PSBOb25lDQogICAgI19fYnVpbHRpbl9fLnJlbG9hZCA9IHNlbGYuX3JlbG9h ZF9ob29rDQoNCiAgZGVmIGFkZF9zdWZmaXgoc2VsZiwgc3VmZml4LCBpbXBv cnRlcik6DQogICAgYXNzZXJ0IGlzaW5zdGFuY2UoaW1wb3J0ZXIsIFN1ZmZp eEltcG9ydGVyKQ0KICAgIHNlbGYuc3VmZml4ZXMuYXBwZW5kKChzdWZmaXgs IGltcG9ydGVyKSkNCg0KICAjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMj IyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjDQog ICMNCiAgIyBQUklWQVRFIE1FVEhPRFMNCiAgIw0KICBkZWYgX19pbml0X18o c2VsZik6DQogICAgIyB3ZSdyZSBkZWZpbml0ZWx5IGdvaW5nIHRvIGJlIGlt cG9ydGluZyBzb21ldGhpbmcgaW4gdGhlIGZ1dHVyZSwNCiAgICAjIHNvIGxl dCdzIGp1c3QgbG9hZCB0aGUgT1MtcmVsYXRlZCBmYWNpbGl0aWVzLg0KICAg IGlmIG5vdCBfb3Nfc3RhdDoNCiAgICAgIF9vc19ib290c3RyYXAoKQ0KDQog ICAgIyBJbml0aWFsaXplIHRoZSBzZXQgb2Ygc3VmZml4ZXMgdGhhdCB3ZSBy ZWNvZ25pemUgYW5kIGltcG9ydC4NCiAgICAjIFRoZSBkZWZhdWx0IHdpbGwg aW1wb3J0IGR5bmFtaWMtbG9hZCBtb2R1bGVzIGZpcnN0LCBmb2xsb3dlZCBi eQ0KICAgICMgLnB5IGZpbGVzIChvciBhIC5weSBmaWxlJ3MgY2FjaGVkIGJ5 dGVjb2RlKQ0KICAgIHNlbGYuc3VmZml4ZXMgPSBbIF0NCiAgICBmb3IgZGVz YyBpbiBpbXAuZ2V0X3N1ZmZpeGVzKCk6DQogICAgICBpZiBkZXNjWzJdID09 IGltcC5DX0VYVEVOU0lPTjoNCiAgICAgICAgc2VsZi5zdWZmaXhlcy5hcHBl bmQoKGRlc2NbMF0sIER5bkxvYWRTdWZmaXhJbXBvcnRlcihkZXNjKSkpDQog ICAgc2VsZi5zdWZmaXhlcy5hcHBlbmQoKCcucHknLCBQeVN1ZmZpeEltcG9y dGVyKCkpKQ0KDQogICAgIyBUaGlzIGlzIHRoZSBpbXBvcnRlciB0aGF0IHdl IHVzZSBmb3IgZ3JhYmJpbmcgc3R1ZmYgZnJvbSB0aGUNCiAgICAjIGZpbGVz eXN0ZW0uIEl0IGRlZmluZXMgb25lIG1vcmUgbWV0aG9kIChpbXBvcnRfZnJv bV9kaXIpIGZvciBvdXIgdXNlLg0KICAgIHNlbGYuZnNfaW1wID0gX0ZpbGVz eXN0ZW1JbXBvcnRlcihzZWxmLnN1ZmZpeGVzKQ0KDQogIGRlZiBfaW1wb3J0 X2hvb2soc2VsZiwgZnFuYW1lLCBnbG9iYWxzPU5vbmUsIGxvY2Fscz1Ob25l LCBmcm9tbGlzdD1Ob25lKToNCiAgICAiIiJQeXRob24gY2FsbHMgdGhpcyBo b29rIHRvIGxvY2F0ZSBhbmQgaW1wb3J0IGEgbW9kdWxlLiIiIg0KDQogICAg cGFydHMgPSBzdHJvcC5zcGxpdChmcW5hbWUsICcuJykNCg0KICAgICMgZGV0 ZXJtaW5lIHRoZSBjb250ZXh0IG9mIHRoaXMgaW1wb3J0DQogICAgcGFyZW50 ID0gc2VsZi5fZGV0ZXJtaW5lX2ltcG9ydF9jb250ZXh0KGdsb2JhbHMpDQoN CiAgICAjIGlmIHRoZXJlIGlzIGEgcGFyZW50LCB0aGVuIGl0cyBpbXBvcnRl ciBzaG91bGQgbWFuYWdlIHRoaXMgaW1wb3J0DQogICAgaWYgcGFyZW50Og0K ICAgICAgbW9kdWxlID0gcGFyZW50Ll9faW1wb3J0ZXJfXy5fZG9faW1wb3J0 KHBhcmVudCwgcGFydHMsIGZyb21saXN0KQ0KICAgICAgaWYgbW9kdWxlOg0K ICAgICAgICByZXR1cm4gbW9kdWxlDQoNCiAgICAjIGhhcyB0aGUgdG9wIG1v ZHVsZSBhbHJlYWR5IGJlZW4gaW1wb3J0ZWQ/DQogICAgdHJ5Og0KICAgICAg dG9wX21vZHVsZSA9IHN5cy5tb2R1bGVzW3BhcnRzWzBdXQ0KICAgIGV4Y2Vw dCBLZXlFcnJvcjoNCg0KICAgICAgIyBsb29rIGZvciB0aGUgdG9wbW9zdCBt b2R1bGUNCiAgICAgIHRvcF9tb2R1bGUgPSBzZWxmLl9pbXBvcnRfdG9wX21v ZHVsZShwYXJ0c1swXSkNCiAgICAgIGlmIG5vdCB0b3BfbW9kdWxlOg0KICAg ICAgICAjIHRoZSB0b3Btb3N0IG1vZHVsZSB3YXNuJ3QgZm91bmQgYXQgYWxs Lg0KICAgICAgICByYWlzZSBJbXBvcnRFcnJvciwgJ05vIG1vZHVsZSBuYW1l ZCAnICsgZnFuYW1lDQogICAgICAgIHJldHVybiBzZWxmLl9fY2hhaW5faW1w b3J0KG5hbWUsIGdsb2JhbHMsIGxvY2FscywgZnJvbWxpc3QpDQoNCiAgICAj IGZhc3QtcGF0aCBzaW1wbGUgaW1wb3J0cw0KICAgIGlmIGxlbihwYXJ0cykg PT0gMToNCiAgICAgIGlmIG5vdCBmcm9tbGlzdDoNCiAgICAgICAgcmV0dXJu IHRvcF9tb2R1bGUNCg0KICAgICAgaWYgbm90IHRvcF9tb2R1bGUuX19kaWN0 X18uZ2V0KCdfX2lzcGtnX18nKToNCiAgICAgICAgIyBfX2lzcGtnX18gaXNu J3QgZGVmaW5lZCAodGhlIG1vZHVsZSB3YXMgbm90IGltcG9ydGVkIGJ5IHVz KSwgb3INCiAgICAgICAgIyBpdCBpcyB6ZXJvLg0KICAgICAgICAjDQogICAg ICAgICMgSW4gdGhlIGZvcm1lciBjYXNlLCB0aGVyZSBpcyBubyB3YXkgdGhh dCB3ZSBjb3VsZCBpbXBvcnQNCiAgICAgICAgIyBzdWItbW9kdWxlcyB0aGF0 IG9jY3VyIGluIHRoZSBmcm9tbGlzdCAoYnV0IHdlIGNhbid0IHJhaXNlIGFu DQogICAgICAgICMgZXJyb3IgYmVjYXVzZSBpdCBtYXkganVzdCBiZSBuYW1l cykgYmVjYXVzZSB3ZSBkb24ndCBrbm93IGhvdw0KICAgICAgICAjIHRvIGRl YWwgd2l0aCBwYWNrYWdlcyB0aGF0IHdlcmUgaW1wb3J0ZWQgYnkgb3RoZXIg c3lzdGVtcy4NCiAgICAgICAgIw0KICAgICAgICAjIEluIHRoZSBsYXR0ZXIg Y2FzZSAoX19pc3BrZ19fID09IDApLCB0aGVyZSBjYW4ndCBiZSBhbnkgc3Vi LQ0KICAgICAgICAjIG1vZHVsZXMgcHJlc2VudCwgc28gd2UgY2FuIGp1c3Qg cmV0dXJuLg0KICAgICAgICAjDQogICAgICAgICMgSW4gYm90aCBjYXNlcywg c2luY2UgbGVuKHBhcnRzKSA9PSAxLCB0aGUgdG9wX21vZHVsZSBpcyBhbHNv DQogICAgICAgICMgdGhlICJib3R0b20iIHdoaWNoIGlzIHRoZSBkZWZpbmVk IHJldHVybiB3aGVuIGEgZnJvbWxpc3QgZXhpc3RzLg0KICAgICAgICByZXR1 cm4gdG9wX21vZHVsZQ0KDQogICAgaW1wb3J0ZXIgPSB0b3BfbW9kdWxlLl9f ZGljdF9fLmdldCgnX19pbXBvcnRlcl9fJykNCiAgICBpZiBpbXBvcnRlcjoN CiAgICAgIHJldHVybiBpbXBvcnRlci5fZmluaXNoX2ltcG9ydCh0b3BfbW9k dWxlLCBwYXJ0c1sxOl0sIGZyb21saXN0KQ0KDQogICAgIyBJZiB0aGUgaW1w b3J0ZXIgZG9lcyBub3QgZXhpc3QsIHRoZW4gd2UgaGF2ZSB0byBiYWlsLiBB IG1pc3NpbmcgaW1wb3J0ZXINCiAgICAjIG1lYW5zIHRoYXQgc29tZXRoaW5n IGVsc2UgaW1wb3J0ZWQgdGhlIG1vZHVsZSwgYW5kIHdlIGhhdmUgbm8ga25v d2xlZGdlDQogICAgIyBvZiBob3cgdG8gZ2V0IHN1Yi1tb2R1bGVzIG91dCBv ZiB0aGUgdGhpbmcuDQogICAgcmFpc2UgSW1wb3J0RXJyb3IsICdObyBtb2R1 bGUgbmFtZWQgJyArIGZxbmFtZQ0KICAgIHJldHVybiBzZWxmLl9fY2hhaW5f aW1wb3J0KG5hbWUsIGdsb2JhbHMsIGxvY2FscywgZnJvbWxpc3QpDQoNCiAg ZGVmIF9kZXRlcm1pbmVfaW1wb3J0X2NvbnRleHQoc2VsZiwgZ2xvYmFscyk6 DQogICAgIiIiUmV0dXJucyB0aGUgY29udGV4dCBpbiB3aGljaCBhIG1vZHVs ZSBzaG91bGQgYmUgaW1wb3J0ZWQuDQoNCiAgICBUaGUgY29udGV4dCBjb3Vs ZCBiZSBhIGxvYWRlZCAocGFja2FnZSkgbW9kdWxlIGFuZCB0aGUgaW1wb3J0 ZWQgbW9kdWxlDQogICAgd2lsbCBiZSBsb29rZWQgZm9yIHdpdGhpbiB0aGF0 IHBhY2thZ2UuIFRoZSBjb250ZXh0IGNvdWxkIGFsc28gYmUgTm9uZSwNCiAg ICBtZWFuaW5nIHRoZXJlIGlzIG5vIGNvbnRleHQgLS0gdGhlIG1vZHVsZSBz aG91bGQgYmUgbG9va2VkIGZvciBhcyBhDQogICAgInRvcC1sZXZlbCIgbW9k dWxlLg0KICAgICIiIg0KDQogICAgaWYgbm90IGdsb2JhbHMgb3Igbm90IGds b2JhbHMuZ2V0KCdfX2ltcG9ydGVyX18nKToNCiAgICAgICMgZ2xvYmFscyBk b2VzIG5vdCByZWZlciB0byBvbmUgb2Ygb3VyIG1vZHVsZXMgb3IgcGFja2Fn ZXMuIFRoYXQNCiAgICAgICMgaW1wbGllcyB0aGVyZSBpcyBubyByZWxhdGl2 ZSBpbXBvcnQgY29udGV4dCAoYXMgZmFyIGFzIHdlIGFyZQ0KICAgICAgIyBj b25jZXJuZWQpLCBhbmQgaXQgc2hvdWxkIGp1c3QgcGljayBpdCBvZmYgdGhl IHN0YW5kYXJkIHBhdGguDQogICAgICByZXR1cm4gTm9uZQ0KDQogICAgIyBU aGUgZ2xvYmFscyByZWZlciB0byBhIG1vZHVsZSBvciBwYWNrYWdlIG9mIG91 cnMuIEl0IHdpbGwgZGVmaW5lDQogICAgIyB0aGUgY29udGV4dCBvZiB0aGUg bmV3IGltcG9ydC4gR2V0IHRoZSBtb2R1bGUvcGFja2FnZSBmcW5hbWUuDQog ICAgcGFyZW50X2ZxbmFtZSA9IGdsb2JhbHNbJ19fbmFtZV9fJ10NCg0KICAg ICMgaWYgYSBwYWNrYWdlIGlzIHBlcmZvcm1pbmcgdGhlIGltcG9ydCwgdGhl biByZXR1cm4gaXRzZWxmIChpbXBvcnRzDQogICAgIyByZWZlciB0byBwa2cg Y29udGVudHMpDQogICAgaWYgZ2xvYmFsc1snX19pc3BrZ19fJ106DQogICAg ICBwYXJlbnQgPSBzeXMubW9kdWxlc1twYXJlbnRfZnFuYW1lXQ0KICAgICAg YXNzZXJ0IGdsb2JhbHMgaXMgcGFyZW50Ll9fZGljdF9fDQogICAgICByZXR1 cm4gcGFyZW50DQoNCiAgICBpID0gc3Ryb3AucmZpbmQocGFyZW50X2ZxbmFt ZSwgJy4nKQ0KDQogICAgIyBhIG1vZHVsZSBvdXRzaWRlIG9mIGEgcGFja2Fn ZSBoYXMgbm8gcGFydGljdWxhciBpbXBvcnQgY29udGV4dA0KICAgIGlmIGkg PT0gLTE6DQogICAgICByZXR1cm4gTm9uZQ0KDQogICAgIyBpZiBhIG1vZHVs ZSBpbiBhIHBhY2thZ2UgaXMgcGVyZm9ybWluZyB0aGUgaW1wb3J0LCB0aGVu IHJldHVybiB0aGUNCiAgICAjIHBhY2thZ2UgKGltcG9ydHMgcmVmZXIgdG8g c2libGluZ3MpDQogICAgcGFyZW50X2ZxbmFtZSA9IHBhcmVudF9mcW5hbWVb OmldDQogICAgcGFyZW50ID0gc3lzLm1vZHVsZXNbcGFyZW50X2ZxbmFtZV0N CiAgICBhc3NlcnQgcGFyZW50Ll9fbmFtZV9fID09IHBhcmVudF9mcW5hbWUN CiAgICByZXR1cm4gcGFyZW50DQoNCiAgZGVmIF9pbXBvcnRfdG9wX21vZHVs ZShzZWxmLCBuYW1lKToNCiAgICAjIHNjYW4gc3lzLnBhdGggbG9va2luZyBm b3IgYSBsb2NhdGlvbiBpbiB0aGUgZmlsZXN5c3RlbSB0aGF0IGNvbnRhaW5z DQogICAgIyB0aGUgbW9kdWxlLCBvciBhbiBJbXBvcnRlciBvYmplY3QgdGhh dCBjYW4gaW1wb3J0IHRoZSBtb2R1bGUuDQogICAgZm9yIGl0ZW0gaW4gc3lz LnBhdGg6DQogICAgICBpZiB0eXBlKGl0ZW0pID09IF9TdHJpbmdUeXBlOg0K ICAgICAgICBtb2R1bGUgPSBzZWxmLmZzX2ltcC5pbXBvcnRfZnJvbV9kaXIo aXRlbSwgbmFtZSkNCiAgICAgIGVsc2U6DQogICAgICAgIG1vZHVsZSA9IGl0 ZW0uaW1wb3J0X3RvcChuYW1lKQ0KICAgICAgaWYgbW9kdWxlOg0KICAgICAg ICByZXR1cm4gbW9kdWxlDQogICAgcmV0dXJuIE5vbmUNCg0KICBkZWYgX3Jl bG9hZF9ob29rKHNlbGYsIG1vZHVsZSk6DQogICAgIlB5dGhvbiBjYWxscyB0 aGlzIGhvb2sgdG8gcmVsb2FkIGEgbW9kdWxlLiINCg0KICAgICMgcmVsb2Fk aW5nIG9mIGEgbW9kdWxlIG1heSBvciBtYXkgbm90IGJlIHBvc3NpYmxlIChk ZXBlbmRpbmcgb24gdGhlDQogICAgIyBpbXBvcnRlciksIGJ1dCBhdCBsZWFz dCB3ZSBjYW4gdmFsaWRhdGUgdGhhdCBpdCdzIG91cnMgdG8gcmVsb2FkDQog ICAgaW1wb3J0ZXIgPSBtb2R1bGUuX19kaWN0X18uZ2V0KCdfX2ltcG9ydGVy X18nKQ0KICAgIGlmIG5vdCBpbXBvcnRlcjoNCiAgICAgIHJldHVybiBzZWxm Ll9fY2hhaW5fcmVsb2FkKG1vZHVsZSkNCg0KICAgICMgb2theS4gaXQgaXMg dXNpbmcgdGhlIGltcHV0aWwgc3lzdGVtLCBhbmQgd2UgbXVzdCBkZWxlZ2F0 ZSBpdCwgYnV0DQogICAgIyB3ZSBkb24ndCBrbm93IHdoYXQgdG8gZG8gKHll dCkNCiAgICAjIyMgd2Ugc2hvdWxkIGJsYXN0IHRoZSBtb2R1bGUgZGljdCBh bmQgZG8gYW5vdGhlciBnZXRfY29kZSgpLiBuZWVkIHRvDQogICAgIyMjIGZs ZXNoIHRoaXMgb3V0IGFuZCBhZGQgcHJvcGVyIGRvY2NvLi4uDQogICAgcmFp c2UgU3lzdGVtRXJyb3IsICJyZWxvYWQgbm90IHlldCBpbXBsZW1lbnRlZCIN Cg0KDQpjbGFzcyBJbXBvcnRlcjoNCiAgIkJhc2UgY2xhc3MgZm9yIHJlcGxh Y2luZyBzdGFuZGFyZCBpbXBvcnQgZnVuY3Rpb25zLiINCg0KICBkZWYgaW5z dGFsbChzZWxmKToNCiAgICBzeXMucGF0aC5pbnNlcnQoMCwgc2VsZikNCg0K ICBkZWYgaW1wb3J0X3RvcChzZWxmLCBuYW1lKToNCiAgICAiSW1wb3J0IGEg dG9wLWxldmVsIG1vZHVsZS4iDQogICAgcmV0dXJuIHNlbGYuX2ltcG9ydF9v bmUoTm9uZSwgbmFtZSwgbmFtZSkNCg0KICAjIyMjIyMjIyMjIyMjIyMjIyMj IyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMj IyMjIyMjDQogICMNCiAgIyBQUklWQVRFIE1FVEhPRFMNCiAgIw0KICBkZWYg X2ZpbmlzaF9pbXBvcnQoc2VsZiwgdG9wLCBwYXJ0cywgZnJvbWxpc3QpOg0K ICAgICMgaWYgImEuYi5jIiB3YXMgcHJvdmlkZWQsIHRoZW4gbG9hZCB0aGUg Ii5iLmMiIHBvcnRpb24gZG93biBmcm9tDQogICAgIyBiZWxvdyB0aGUgdG9w LWxldmVsIG1vZHVsZS4NCiAgICBib3R0b20gPSBzZWxmLl9sb2FkX3RhaWwo dG9wLCBwYXJ0cykNCg0KICAgICMgaWYgdGhlIGZvcm0gaXMgImltcG9ydCBh LmIuYyIsIHRoZW4gcmV0dXJuICJhIg0KICAgIGlmIG5vdCBmcm9tbGlzdDoN CiAgICAgICMgbm8gZnJvbWxpc3Q6IHJldHVybiB0aGUgdG9wIG9mIHRoZSBp bXBvcnQgdHJlZQ0KICAgICAgcmV0dXJuIHRvcA0KDQogICAgIyB0aGUgdG9w IG1vZHVsZSB3YXMgaW1wb3J0ZWQgYnkgc2VsZi4NCiAgICAjDQogICAgIyB0 aGlzIG1lYW5zIHRoYXQgdGhlIGJvdHRvbSBtb2R1bGUgd2FzIGFsc28gaW1w b3J0ZWQgYnkgc2VsZiAoanVzdA0KICAgICMgbm93LCBvciBpbiB0aGUgcGFz dCBhbmQgd2UgZmV0Y2hlZCBpdCBmcm9tIHN5cy5tb2R1bGVzKS4NCiAgICAj DQogICAgIyBzaW5jZSB3ZSBpbXBvcnRlZC9oYW5kbGVkIHRoZSBib3R0b20g bW9kdWxlLCB0aGlzIG1lYW5zIHRoYXQgd2UgY2FuDQogICAgIyBhbHNvIGhh bmRsZSBpdHMgZnJvbWxpc3QgKGFuZCByZWxpYWJseSB1c2UgX19pc3BrZ19f KS4NCg0KICAgICMgaWYgdGhlIGJvdHRvbSBub2RlIGlzIGEgcGFja2FnZSwg dGhlbiAocG90ZW50aWFsbHkpIGltcG9ydCBzb21lIG1vZHVsZXMuDQogICAg Iw0KICAgICMgbm90ZTogaWYgaXQgaXMgbm90IGEgcGFja2FnZSwgdGhlbiAi ZnJvbWxpc3QiIHJlZmVycyB0byBuYW1lcyBpbg0KICAgICMgICAgICAgdGhl IGJvdHRvbSBtb2R1bGUgcmF0aGVyIHRoYW4gbW9kdWxlcy4NCiAgICAjIG5v dGU6IGZvciBhIG1peCBvZiBuYW1lcyBhbmQgbW9kdWxlcyBpbiB0aGUgZnJv bWxpc3QsIHdlIHdpbGwNCiAgICAjICAgICAgIGltcG9ydCBhbGwgbW9kdWxl cyBhbmQgaW5zZXJ0IHRob3NlIGludG8gdGhlIG5hbWVzcGFjZSBvZg0KICAg ICMgICAgICAgdGhlIHBhY2thZ2UgbW9kdWxlLiBQeXRob24gd2lsbCBwaWNr IHVwIGFsbCBmcm9tbGlzdCBuYW1lcw0KICAgICMgICAgICAgZnJvbSB0aGUg Ym90dG9tIChwYWNrYWdlKSBtb2R1bGU7IHNvbWUgd2lsbCBiZSBtb2R1bGVz IHRoYXQNCiAgICAjICAgICAgIHdlIGltcG9ydGVkIGFuZCBzdG9yZWQgaW4g dGhlIG5hbWVzcGFjZSwgb3RoZXJzIGFyZSBleHBlY3RlZA0KICAgICMgICAg ICAgdG8gYmUgcHJlc2VudCBhbHJlYWR5Lg0KICAgIGlmIGJvdHRvbS5fX2lz cGtnX186DQogICAgICBzZWxmLl9pbXBvcnRfZnJvbWxpc3QoYm90dG9tLCBm cm9tbGlzdCkNCg0KICAgICMgaWYgdGhlIGZvcm0gaXMgImZyb20gYS5iIGlt cG9ydCBjLCBkIiB0aGVuIHJldHVybiAiYiINCiAgICByZXR1cm4gYm90dG9t DQoNCiAgZGVmIF9pbXBvcnRfb25lKHNlbGYsIHBhcmVudCwgbW9kbmFtZSwg ZnFuYW1lKToNCiAgICAiSW1wb3J0IGEgc2luZ2xlIG1vZHVsZS4iDQoNCiAg ICAjIGhhcyB0aGUgbW9kdWxlIGFscmVhZHkgYmVlbiBpbXBvcnRlZD8NCiAg ICB0cnk6DQogICAgICByZXR1cm4gc3lzLm1vZHVsZXNbZnFuYW1lXQ0KICAg IGV4Y2VwdCBLZXlFcnJvcjoNCiAgICAgIHBhc3MNCg0KICAgICMgbG9hZCB0 aGUgbW9kdWxlJ3MgY29kZSwgb3IgZmV0Y2ggdGhlIG1vZHVsZSBpdHNlbGYN CiAgICByZXN1bHQgPSBzZWxmLmdldF9jb2RlKHBhcmVudCwgbW9kbmFtZSwg ZnFuYW1lKQ0KICAgIGlmIHJlc3VsdCBpcyBOb25lOg0KICAgICAgcmV0dXJu IE5vbmUNCg0KICAgICMjIyBiYWNrd2FyZHMtY29tcGF0DQogICAgaWYgbGVu KHJlc3VsdCkgPT0gMjoNCiAgICAgIHJlc3VsdCA9IHJlc3VsdCArICh7fSwp DQoNCiAgICBtb2R1bGUgPSBzZWxmLl9wcm9jZXNzX3Jlc3VsdChyZXN1bHQs IGZxbmFtZSkNCg0KICAgICMgaW5zZXJ0IHRoZSBtb2R1bGUgaW50byBpdHMg cGFyZW50DQogICAgaWYgcGFyZW50Og0KICAgICAgc2V0YXR0cihwYXJlbnQs IG1vZG5hbWUsIG1vZHVsZSkNCiAgICByZXR1cm4gbW9kdWxlDQoNCiAgZGVm IF9wcm9jZXNzX3Jlc3VsdChzZWxmLCAoaXNwa2csIGNvZGUsIHZhbHVlcyks IGZxbmFtZSk6DQogICAgIyBkaWQgZ2V0X2NvZGUoKSByZXR1cm4gYW4gYWN0 dWFsIG1vZHVsZT8gKHJhdGhlciB0aGFuIGEgY29kZSBvYmplY3QpDQogICAg aXNfbW9kdWxlID0gdHlwZShjb2RlKSBpcyBfTW9kdWxlVHlwZQ0KDQogICAg IyB1c2UgdGhlIHJldHVybmVkIG1vZHVsZSwgb3IgY3JlYXRlIGEgbmV3IG9u ZSB0byBleGVjIGNvZGUgaW50bw0KICAgIGlmIGlzX21vZHVsZToNCiAgICAg IG1vZHVsZSA9IGNvZGUNCiAgICBlbHNlOg0KICAgICAgbW9kdWxlID0gaW1w Lm5ld19tb2R1bGUoZnFuYW1lKQ0KDQogICAgIyMjIHJlY29yZCBwYWNrYWdl cyBhIGJpdCBkaWZmZXJlbnRseT8/DQogICAgbW9kdWxlLl9faW1wb3J0ZXJf XyA9IHNlbGYNCiAgICBtb2R1bGUuX19pc3BrZ19fID0gaXNwa2cNCg0KICAg ICMgaW5zZXJ0IGFkZGl0aW9uYWwgdmFsdWVzIGludG8gdGhlIG1vZHVsZSAo YmVmb3JlIGV4ZWN1dGluZyB0aGUgY29kZSkNCiAgICBtb2R1bGUuX19kaWN0 X18udXBkYXRlKHZhbHVlcykNCg0KICAgICMgdGhlIG1vZHVsZSBpcyBhbG1v c3QgcmVhZHkuLi4gbWFrZSBpdCB2aXNpYmxlDQogICAgc3lzLm1vZHVsZXNb ZnFuYW1lXSA9IG1vZHVsZQ0KDQogICAgIyBleGVjdXRlIHRoZSBjb2RlIHdp dGhpbiB0aGUgbW9kdWxlJ3MgbmFtZXNwYWNlDQogICAgaWYgbm90IGlzX21v ZHVsZToNCiAgICAgIGV4ZWMgY29kZSBpbiBtb2R1bGUuX19kaWN0X18NCg0K ICAgIHJldHVybiBtb2R1bGUNCg0KICBkZWYgX2xvYWRfdGFpbChzZWxmLCBt LCBwYXJ0cyk6DQogICAgIiIiSW1wb3J0IHRoZSByZXN0IG9mIHRoZSBtb2R1 bGVzLCBkb3duIGZyb20gdGhlIHRvcC1sZXZlbCBtb2R1bGUuDQoNCiAgICBS ZXR1cm5zIHRoZSBsYXN0IG1vZHVsZSBpbiB0aGUgZG90dGVkIGxpc3Qgb2Yg bW9kdWxlcy4NCiAgICAiIiINCiAgICBmb3IgcGFydCBpbiBwYXJ0czoNCiAg ICAgIGZxbmFtZSA9ICIlcy4lcyIgJSAobS5fX25hbWVfXywgcGFydCkNCiAg ICAgIG0gPSBzZWxmLl9pbXBvcnRfb25lKG0sIHBhcnQsIGZxbmFtZSkNCiAg ICAgIGlmIG5vdCBtOg0KICAgICAgICByYWlzZSBJbXBvcnRFcnJvciwgIk5v IG1vZHVsZSBuYW1lZCAiICsgZnFuYW1lDQogICAgcmV0dXJuIG0NCg0KICBk ZWYgX2ltcG9ydF9mcm9tbGlzdChzZWxmLCBwYWNrYWdlLCBmcm9tbGlzdCk6 DQogICAgJ0ltcG9ydCBhbnkgc3ViLW1vZHVsZXMgaW4gdGhlICJmcm9tIiBs aXN0LicNCg0KICAgICMgaWYgJyonIGlzIHByZXNlbnQgaW4gdGhlIGZyb21s aXN0LCB0aGVuIGxvb2sgZm9yIHRoZSAnX19hbGxfXycgdmFyaWFibGUNCiAg ICAjIHRvIGZpbmQgYWRkaXRpb25hbCBpdGVtcyAobW9kdWxlcykgdG8gaW1w b3J0Lg0KICAgIGlmICcqJyBpbiBmcm9tbGlzdDoNCiAgICAgIGZyb21saXN0 ID0gbGlzdChmcm9tbGlzdCkgKyBsaXN0KHBhY2thZ2UuX19kaWN0X18uZ2V0 KCdfX2FsbF9fJywgW10pKQ0KDQogICAgZm9yIHN1YiBpbiBmcm9tbGlzdDoN CiAgICAgICMgaWYgdGhlIG5hbWUgaXMgYWxyZWFkeSBwcmVzZW50LCB0aGVu IGRvbid0IHRyeSB0byBpbXBvcnQgaXQgKGl0DQogICAgICAjIG1pZ2h0IG5v dCBiZSBhIG1vZHVsZSEpLg0KICAgICAgaWYgc3ViICE9ICcqJyBhbmQgbm90 IGhhc2F0dHIocGFja2FnZSwgc3ViKToNCiAgICAgICAgc3VibmFtZSA9ICIl cy4lcyIgJSAocGFja2FnZS5fX25hbWVfXywgc3ViKQ0KICAgICAgICBzdWJt b2QgPSBzZWxmLl9pbXBvcnRfb25lKHBhY2thZ2UsIHN1Yiwgc3VibmFtZSkN CiAgICAgICAgaWYgbm90IHN1Ym1vZDoNCiAgICAgICAgICByYWlzZSBJbXBv cnRFcnJvciwgImNhbm5vdCBpbXBvcnQgbmFtZSAiICsgc3VibmFtZQ0KDQog IGRlZiBfZG9faW1wb3J0KHNlbGYsIHBhcmVudCwgcGFydHMsIGZyb21saXN0 KToNCiAgICAiIiJBdHRlbXB0IHRvIGltcG9ydCB0aGUgbW9kdWxlIHJlbGF0 aXZlIHRvIHBhcmVudC4NCg0KICAgIFRoaXMgbWV0aG9kIGlzIHVzZWQgd2hl biB0aGUgaW1wb3J0IGNvbnRleHQgc3BlY2lmaWVzIHRoYXQgPHNlbGY+DQog ICAgaW1wb3J0ZWQgdGhlIHBhcmVudCBtb2R1bGUuDQogICAgIiIiDQogICAg dG9wX25hbWUgPSBwYXJ0c1swXQ0KICAgIHRvcF9mcW5hbWUgPSBwYXJlbnQu X19uYW1lX18gKyAnLicgKyB0b3BfbmFtZQ0KICAgIHRvcF9tb2R1bGUgPSBz ZWxmLl9pbXBvcnRfb25lKHBhcmVudCwgdG9wX25hbWUsIHRvcF9mcW5hbWUp DQogICAgaWYgbm90IHRvcF9tb2R1bGU6DQogICAgICAjIHRoaXMgaW1wb3J0 ZXIgYW5kIHBhcmVudCBjb3VsZCBub3QgZmluZCB0aGUgbW9kdWxlIChyZWxh dGl2ZWx5KQ0KICAgICAgcmV0dXJuIE5vbmUNCg0KICAgIHJldHVybiBzZWxm Ll9maW5pc2hfaW1wb3J0KHRvcF9tb2R1bGUsIHBhcnRzWzE6XSwgZnJvbWxp c3QpDQoNCiAgIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMj IyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIw0KICAjDQogICMg TUVUSE9EUyBUTyBPVkVSUklERQ0KICAjDQogIGRlZiBnZXRfY29kZShzZWxm LCBwYXJlbnQsIG1vZG5hbWUsIGZxbmFtZSk6DQogICAgIiIiRmluZCBhbmQg cmV0cmlldmUgdGhlIGNvZGUgZm9yIHRoZSBnaXZlbiBtb2R1bGUuDQoNCiAg ICBwYXJlbnQgc3BlY2lmaWVzIGEgcGFyZW50IG1vZHVsZSB0byBkZWZpbmUg YSBjb250ZXh0IGZvciBpbXBvcnRpbmcuIEl0DQogICAgbWF5IGJlIE5vbmUs IGluZGljYXRpbmcgbm8gcGFydGljdWxhciBjb250ZXh0IGZvciB0aGUgc2Vh cmNoLg0KDQogICAgbW9kbmFtZSBzcGVjaWZpZXMgYSBzaW5nbGUgbW9kdWxl IChub3QgZG90dGVkKSB3aXRoaW4gdGhlIHBhcmVudC4NCg0KICAgIGZxbmFt ZSBzcGVjaWZpZXMgdGhlIGZ1bGx5LXF1YWxpZmllZCBtb2R1bGUgbmFtZS4g VGhpcyBpcyBhIChwb3RlbnRpYWxseSkNCiAgICBkb3R0ZWQgbmFtZSBmcm9t IHRoZSAicm9vdCIgb2YgdGhlIG1vZHVsZSBuYW1lc3BhY2UgZG93biB0byB0 aGUgbW9kbmFtZS4NCiAgICBJZiB0aGVyZSBpcyBubyBwYXJlbnQsIHRoZW4g bW9kbmFtZT09ZnFuYW1lLg0KDQogICAgVGhpcyBtZXRob2Qgc2hvdWxkIHJl dHVybiBOb25lLCBvciBhIDMtdHVwbGUuDQoNCiAgICAqIElmIHRoZSBtb2R1 bGUgd2FzIG5vdCBmb3VuZCwgdGhlbiBOb25lIHNob3VsZCBiZSByZXR1cm5l ZC4NCg0KICAgICogVGhlIGZpcnN0IGl0ZW0gb2YgdGhlIDItIG9yIDMtdHVw bGUgc2hvdWxkIGJlIHRoZSBpbnRlZ2VyIDAgb3IgMSwNCiAgICAgIHNwZWNp Znlpbmcgd2hldGhlciB0aGUgbW9kdWxlIHRoYXQgd2FzIGZvdW5kIGlzIGEg cGFja2FnZSBvciBub3QuDQoNCiAgICAqIFRoZSBzZWNvbmQgaXRlbSBpcyB0 aGUgY29kZSBvYmplY3QgZm9yIHRoZSBtb2R1bGUgKGl0IHdpbGwgYmUNCiAg ICAgIGV4ZWN1dGVkIHdpdGhpbiB0aGUgbmV3IG1vZHVsZSdzIG5hbWVzcGFj ZSkuIFRoaXMgaXRlbSBjYW4gYWxzbw0KICAgICAgYmUgYSBmdWxseS1sb2Fk ZWQgbW9kdWxlIG9iamVjdCAoZS5nLiBsb2FkZWQgZnJvbSBhIHNoYXJlZCBs aWIpLg0KDQogICAgKiBUaGUgdGhpcmQgaXRlbSBpcyBhIGRpY3Rpb25hcnkg b2YgbmFtZS92YWx1ZSBwYWlycyB0aGF0IHdpbGwgYmUNCiAgICAgIGluc2Vy dGVkIGludG8gbmV3IG1vZHVsZSBiZWZvcmUgdGhlIGNvZGUgb2JqZWN0IGlz IGV4ZWN1dGVkLiBUaGlzDQogICAgICBpcyBwcm92aWRlZCBpbiBjYXNlIHRo ZSBtb2R1bGUncyBjb2RlIGV4cGVjdHMgY2VydGFpbiB2YWx1ZXMgKHN1Y2gN CiAgICAgIGFzIHdoZXJlIHRoZSBtb2R1bGUgd2FzIGZvdW5kKS4gV2hlbiB0 aGUgc2Vjb25kIGl0ZW0gaXMgYSBtb2R1bGUNCiAgICAgIG9iamVjdCwgdGhl biB0aGVzZSBuYW1lcy92YWx1ZXMgd2lsbCBiZSBpbnNlcnRlZCAqYWZ0ZXIq IHRoZSBtb2R1bGUNCiAgICAgIGhhcyBiZWVuIGxvYWRlZC9pbml0aWFsaXpl ZC4NCiAgICAiIiINCiAgICByYWlzZSBSdW50aW1lRXJyb3IsICJnZXRfY29k ZSBub3QgaW1wbGVtZW50ZWQiDQoNCg0KIyMjIyMjIyMjIyMjIyMjIyMjIyMj IyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMj IyMjIw0KIw0KIyBTb21lIGhhbmR5IHN0dWZmIGZvciB0aGUgSW1wb3J0ZXJz DQojDQoNCiMgYnl0ZS1jb21waWxlZCBmaWxlIHN1ZmZpYyBjaGFyYWN0ZXIN Cl9zdWZmaXhfY2hhciA9IF9fZGVidWdfXyBhbmQgJ2MnIG9yICdvJw0KDQoj IGJ5dGUtY29tcGlsZWQgZmlsZSBzdWZmaXgNCl9zdWZmaXggPSAnLnB5JyAr IF9zdWZmaXhfY2hhcg0KDQojIHRoZSBDX0VYVEVOU0lPTiBzdWZmaXhlcw0K X2Nfc3VmZml4ZXMgPSBmaWx0ZXIobGFtYmRhIHg6IHhbMl0gPT0gaW1wLkNf RVhURU5TSU9OLCBpbXAuZ2V0X3N1ZmZpeGVzKCkpDQoNCmRlZiBfY29tcGls ZShwYXRobmFtZSwgdGltZXN0YW1wKToNCiAgIiIiQ29tcGlsZSAoYW5kIGNh Y2hlKSBhIFB5dGhvbiBzb3VyY2UgZmlsZS4NCg0KICBUaGUgZmlsZSBzcGVj aWZpZWQgYnkgPHBhdGhuYW1lPiBpcyBjb21waWxlZCB0byBhIGNvZGUgb2Jq ZWN0IGFuZA0KICByZXR1cm5lZC4NCg0KICBQcmVzdW1pbmcgdGhlIGFwcHJv cHJpYXRlIHByaXZpbGVnZXMgZXhpc3QsIHRoZSBieXRlY29kZXMgd2lsbCBi ZQ0KICBzYXZlZCBiYWNrIHRvIHRoZSBmaWxlc3lzdGVtIGZvciBmdXR1cmUg aW1wb3J0cy4gVGhlIHNvdXJjZSBmaWxlJ3MNCiAgbW9kaWZpY2F0aW9uIHRp bWVzdGFtcCBtdXN0IGJlIHByb3ZpZGVkIGFzIGEgTG9uZyB2YWx1ZS4NCiAg IiIiDQogIGNvZGVzdHJpbmcgPSBvcGVuKHBhdGhuYW1lLCAncicpLnJlYWQo KQ0KICBpZiBjb2Rlc3RyaW5nIGFuZCBjb2Rlc3RyaW5nWy0xXSAhPSAnXG4n Og0KICAgIGNvZGVzdHJpbmcgPSBjb2Rlc3RyaW5nICsgJ1xuJw0KICBjb2Rl ID0gX19idWlsdGluX18uY29tcGlsZShjb2Rlc3RyaW5nLCBwYXRobmFtZSwg J2V4ZWMnKQ0KDQogICMgdHJ5IHRvIGNhY2hlIHRoZSBjb21waWxlZCBjb2Rl DQogIHRyeToNCiAgICBmID0gb3BlbihwYXRobmFtZSArIF9zdWZmaXhfY2hh ciwgJ3diJykNCiAgZXhjZXB0IElPRXJyb3I6DQogICAgcGFzcw0KICBlbHNl Og0KICAgIGYud3JpdGUoJ1wwXDBcMFwwJykNCiAgICBmLndyaXRlKHN0cnVj dC5wYWNrKCc8SScsIHRpbWVzdGFtcCkpDQogICAgbWFyc2hhbC5kdW1wKGNv ZGUsIGYpDQogICAgZi5mbHVzaCgpDQogICAgZi5zZWVrKDAsIDApDQogICAg Zi53cml0ZShpbXAuZ2V0X21hZ2ljKCkpDQogICAgZi5jbG9zZSgpDQoNCiAg cmV0dXJuIGNvZGUNCg0KX29zX3N0YXQgPSBfb3NfcGF0aF9qb2luID0gTm9u ZQ0KZGVmIF9vc19ib290c3RyYXAoKToNCiAgIlNldCB1cCAnb3MnIG1vZHVs ZSByZXBsYWNlbWVudCBmdW5jdGlvbnMgZm9yIHVzZSBkdXJpbmcgaW1wb3J0 IGJvb3RzdHJhcC4iDQoNCiAgbmFtZXMgPSBzeXMuYnVpbHRpbl9tb2R1bGVf bmFtZXMNCg0KICBqb2luID0gTm9uZQ0KICBpZiAncG9zaXgnIGluIG5hbWVz Og0KICAgIHNlcCA9ICcvJw0KICAgIGZyb20gcG9zaXggaW1wb3J0IHN0YXQN CiAgZWxpZiAnbnQnIGluIG5hbWVzOg0KICAgIHNlcCA9ICdcXCcNCiAgICBm cm9tIG50IGltcG9ydCBzdGF0DQogIGVsaWYgJ2RvcycgaW4gbmFtZXM6DQog ICAgc2VwID0gJ1xcJw0KICAgIGZyb20gZG9zIGltcG9ydCBzdGF0DQogIGVs aWYgJ29zMicgaW4gbmFtZXM6DQogICAgc2VwID0gJ1xcJw0KICAgIGZyb20g b3MyIGltcG9ydCBzdGF0DQogIGVsaWYgJ21hYycgaW4gbmFtZXM6DQogICAg ZnJvbSBtYWMgaW1wb3J0IHN0YXQNCiAgICBkZWYgam9pbihhLCBiKToNCiAg ICAgIGlmIGEgPT0gJyc6DQogICAgICAgIHJldHVybiBiDQogICAgICBwYXRo ID0gcw0KICAgICAgaWYgJzonIG5vdCBpbiBhOg0KICAgICAgICBhID0gJzon ICsgYQ0KICAgICAgaWYgYVstMTpdIDw+ICc6JzoNCiAgICAgICAgYSA9IGEg KyAnOicNCiAgICAgIHJldHVybiBhICsgYg0KICBlbHNlOg0KICAgIHJhaXNl IEltcG9ydEVycm9yLCAnbm8gb3Mgc3BlY2lmaWMgbW9kdWxlIGZvdW5kJw0K ICANCiAgaWYgam9pbiBpcyBOb25lOg0KICAgIGRlZiBqb2luKGEsIGIsIHNl cD1zZXApOg0KICAgICAgaWYgYSA9PSAnJzoNCiAgICAgICAgcmV0dXJuIGIN CiAgICAgIGxhc3RjaGFyID0gYVstMTpdDQogICAgICBpZiBsYXN0Y2hhciA9 PSAnLycgb3IgbGFzdGNoYXIgPT0gc2VwOg0KICAgICAgICByZXR1cm4gYSAr IGINCiAgICAgIHJldHVybiBhICsgc2VwICsgYg0KDQogIGdsb2JhbCBfb3Nf c3RhdA0KICBfb3Nfc3RhdCA9IHN0YXQNCg0KICBnbG9iYWwgX29zX3BhdGhf am9pbg0KICBfb3NfcGF0aF9qb2luID0gam9pbg0KDQpkZWYgX29zX3BhdGhf aXNkaXIocGF0aG5hbWUpOg0KICAiTG9jYWwgcmVwbGFjZW1lbnQgZm9yIG9z LnBhdGguaXNkaXIoKS4iDQogIHRyeToNCiAgICBzID0gX29zX3N0YXQocGF0 aG5hbWUpDQogIGV4Y2VwdCBPU0Vycm9yOg0KICAgIHJldHVybiBOb25lDQog IHJldHVybiAoc1swXSAmIDAxNzAwMDApID09IDAwNDAwMDANCg0KZGVmIF90 aW1lc3RhbXAocGF0aG5hbWUpOg0KICAiUmV0dXJuIHRoZSBmaWxlIG1vZGlm aWNhdGlvbiB0aW1lIGFzIGEgTG9uZy4iDQogIHRyeToNCiAgICBzID0gX29z X3N0YXQocGF0aG5hbWUpDQogIGV4Y2VwdCBPU0Vycm9yOg0KICAgIHJldHVy biBOb25lDQogIHJldHVybiBsb25nKHNbOF0pDQoNCmRlZiBfZnNfaW1wb3J0 KGRpciwgbW9kbmFtZSwgZnFuYW1lKToNCiAgIkZldGNoIGEgbW9kdWxlIGZy b20gdGhlIGZpbGVzeXN0ZW0uIg0KDQogIHBhdGhuYW1lID0gX29zX3BhdGhf am9pbihkaXIsIG1vZG5hbWUpDQogIGlmIF9vc19wYXRoX2lzZGlyKHBhdGhu YW1lKToNCiAgICB2YWx1ZXMgPSB7ICdfX3BrZ2Rpcl9fJyA6IHBhdGhuYW1l LCAnX19wYXRoX18nIDogWyBwYXRobmFtZSBdIH0NCiAgICBpc3BrZyA9IDEN CiAgICBwYXRobmFtZSA9IF9vc19wYXRoX2pvaW4ocGF0aG5hbWUsICdfX2lu aXRfXycpDQogIGVsc2U6DQogICAgdmFsdWVzID0geyB9DQogICAgaXNwa2cg PSAwDQoNCiAgICAjIGxvb2sgZm9yIGR5bmxvYWQgbW9kdWxlcw0KICAgIGZv ciBkZXNjIGluIF9jX3N1ZmZpeGVzOg0KICAgICAgZmlsZSA9IHBhdGhuYW1l ICsgZGVzY1swXQ0KICAgICAgdHJ5Og0KICAgICAgICBmcCA9IG9wZW4oZmls ZSwgZGVzY1sxXSkNCiAgICAgIGV4Y2VwdCBJT0Vycm9yOg0KICAgICAgICBw YXNzDQogICAgICBlbHNlOg0KICAgICAgICBtb2R1bGUgPSBpbXAubG9hZF9t b2R1bGUoZnFuYW1lLCBmcCwgZmlsZSwgZGVzYykNCiAgICAgICAgdmFsdWVz WydfX2ZpbGVfXyddID0gZmlsZQ0KICAgICAgICByZXR1cm4gMCwgbW9kdWxl LCB2YWx1ZXMNCg0KICB0X3B5ID0gX3RpbWVzdGFtcChwYXRobmFtZSArICcu cHknKQ0KICB0X3B5YyA9IF90aW1lc3RhbXAocGF0aG5hbWUgKyBfc3VmZml4 KQ0KICBpZiB0X3B5IGlzIE5vbmUgYW5kIHRfcHljIGlzIE5vbmU6DQogICAg cmV0dXJuIE5vbmUNCiAgY29kZSA9IE5vbmUNCiAgaWYgdF9weSBpcyBOb25l IG9yICh0X3B5YyBpcyBub3QgTm9uZSBhbmQgdF9weWMgPj0gdF9weSk6DQog ICAgZmlsZSA9IHBhdGhuYW1lICsgX3N1ZmZpeA0KICAgIGYgPSBvcGVuKGZp bGUsICdyYicpDQogICAgaWYgZi5yZWFkKDQpID09IGltcC5nZXRfbWFnaWMo KToNCiAgICAgIHQgPSBzdHJ1Y3QudW5wYWNrKCc8SScsIGYucmVhZCg0KSlb MF0NCiAgICAgIGlmIHQgPT0gdF9weToNCiAgICAgICAgY29kZSA9IG1hcnNo YWwubG9hZChmKQ0KICAgIGYuY2xvc2UoKQ0KICBpZiBjb2RlIGlzIE5vbmU6 DQogICAgZmlsZSA9IHBhdGhuYW1lICsgJy5weScNCiAgICBjb2RlID0gX2Nv bXBpbGUoZmlsZSwgdF9weSkNCg0KICB2YWx1ZXNbJ19fZmlsZV9fJ10gPSBm aWxlDQogIHJldHVybiBpc3BrZywgY29kZSwgdmFsdWVzDQoNCg0KIyMjIyMj IyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMj IyMjIyMjIyMjIyMjIyMjIyMjIw0KIw0KIyBTaW1wbGUgZnVuY3Rpb24tYmFz ZWQgaW1wb3J0ZXINCiMNCmNsYXNzIEZ1bmNJbXBvcnRlcihJbXBvcnRlcik6 DQogICJJbXBvcnRlciBzdWJjbGFzcyB0byB1c2UgYSBzdXBwbGllZCBmdW5j dGlvbiByYXRoZXIgdGhhbiBtZXRob2Qgb3ZlcnJpZGVzLiINCiAgZGVmIF9f aW5pdF9fKHNlbGYsIGZ1bmMpOg0KICAgIHNlbGYuZnVuYyA9IGZ1bmMNCiAg ZGVmIGdldF9jb2RlKHNlbGYsIHBhcmVudCwgbW9kbmFtZSwgZnFuYW1lKToN CiAgICByZXR1cm4gc2VsZi5mdW5jKHBhcmVudCwgbW9kbmFtZSwgZnFuYW1l KQ0KDQpkZWYgaW5zdGFsbF93aXRoKGZ1bmMpOg0KICBGdW5jSW1wb3J0ZXIo ZnVuYykuaW5zdGFsbCgpDQoNCg0KIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMj IyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMj Iw0KIw0KIyBCYXNlIGNsYXNzIGZvciBhcmNoaXZlLWJhc2VkIGltcG9ydGlu Zw0KIw0KY2xhc3MgUGFja2FnZUFyY2hpdmVJbXBvcnRlcihJbXBvcnRlcik6 DQogICIiIkltcG9ydGVyIHN1YmNsYXNzIHRvIGltcG9ydCBmcm9tIChmaWxl KSBhcmNoaXZlcy4NCg0KICBUaGlzIEltcG9ydGVyIGhhbmRsZXMgaW1wb3J0 cyBvZiB0aGUgc3R5bGUgPGFyY2hpdmU+LjxzdWJmaWxlPiwgd2hlcmUNCiAg PGFyY2hpdmU+IGNhbiBiZSBsb2NhdGVkIHVzaW5nIGEgc3ViY2xhc3Mtc3Bl Y2lmaWMgbWVjaGFuaXNtIGFuZCB0aGUNCiAgPHN1YmZpbGU+IGlzIGZvdW5k IGluIHRoZSBhcmNoaXZlIHVzaW5nIGEgc3ViY2xhc3Mtc3BlY2lmaWMgbWVj aGFuaXNtLg0KDQogIFRoaXMgY2xhc3MgZGVmaW5lcyB0d28gaG9va3MgZm9y IHN1YmNsYXNzZXM6IG9uZSB0byBsb2NhdGUgYW4gYXJjaGl2ZQ0KICAoYW5k IHBvc3NpYmx5IHJldHVybiBzb21lIGNvbnRleHQgZm9yIGZ1dHVyZSBzdWJm aWxlIGxvb2t1cHMpLCBhbmQgb25lDQogIHRvIGxvY2F0ZSBzdWJmaWxlcy4N CiAgIiIiDQoNCiAgZGVmIGdldF9jb2RlKHNlbGYsIHBhcmVudCwgbW9kbmFt ZSwgZnFuYW1lKToNCiAgICBpZiBwYXJlbnQ6DQogICAgICAjIHRoZSBJbXBv cnRlci5fZmluaXNoX2ltcG9ydCBsb2dpYyBlbnN1cmVzIHRoYXQgd2UgaGFu ZGxlIGltcG9ydHMNCiAgICAgICMgdW5kZXIgdGhlIHRvcCBsZXZlbCBtb2R1 bGUgKHBhY2thZ2UgLyBhcmNoaXZlKS4NCiAgICAgIGFzc2VydCBwYXJlbnQu X19pbXBvcnRlcl9fID09IHNlbGYNCg0KICAgICAgIyBpZiBhIHBhcmVudCAi cGFja2FnZSIgaXMgcHJvdmlkZWQsIHRoZW4gd2UgYXJlIGltcG9ydGluZyBh IHN1Yi1maWxlDQogICAgICAjIGZyb20gdGhlIGFyY2hpdmUuDQogICAgICBy ZXN1bHQgPSBzZWxmLmdldF9zdWJmaWxlKHBhcmVudC5fX2FyY2hpdmVfXywg bW9kbmFtZSkNCiAgICAgIGlmIHJlc3VsdCBpcyBOb25lOg0KICAgICAgICBy ZXR1cm4gTm9uZQ0KICAgICAgaWYgdHlwZShyZXN1bHQpID09IHR5cGUoKCkp Og0KICAgICAgICByZXR1cm4gKDAsKSArIHJlc3VsdA0KICAgICAgcmV0dXJu IDAsIHJlc3VsdA0KDQogICAgIyBubyBwYXJlbnQgd2FzIHByb3ZpZGVkLCBz byB0aGUgYXJjaGl2ZSBzaG91bGQgZXhpc3Qgc29tZXdoZXJlIG9uIHRoZQ0K ICAgICMgZGVmYXVsdCAicGF0aCIuDQogICAgYXJjaGl2ZSA9IHNlbGYuZ2V0 X2FyY2hpdmUobW9kbmFtZSkNCiAgICBpZiBhcmNoaXZlIGlzIE5vbmU6DQog ICAgICByZXR1cm4gTm9uZQ0KICAgIHJldHVybiAxLCAiIiwgeydfX2FyY2hp dmVfXyc6YXJjaGl2ZX0NCg0KICBkZWYgZ2V0X2FyY2hpdmUoc2VsZiwgbW9k bmFtZSk6DQogICAgIiIiR2V0IGFuIGFyY2hpdmUgb2YgbW9kdWxlcy4NCg0K ICAgIFRoaXMgbWV0aG9kIHNob3VsZCBsb2NhdGUgYW4gYXJjaGl2ZSBhbmQg cmV0dXJuIGEgdmFsdWUgd2hpY2ggY2FuIGJlDQogICAgdXNlZCBieSBnZXRf c3ViZmlsZSB0byBsb2FkIG1vZHVsZXMgZnJvbSBpdC4gVGhlIHZhbHVlIG1h eSBiZSBhIHNpbXBsZQ0KICAgIHBhdGhuYW1lLCBhbiBvcGVuIGZpbGUsIG9y IGEgY29tcGxleCBvYmplY3QgdGhhdCBjYWNoZXMgaW5mb3JtYXRpb24NCiAg ICBmb3IgZnV0dXJlIGltcG9ydHMuDQoNCiAgICBSZXR1cm4gTm9uZSBpZiB0 aGUgYXJjaGl2ZSB3YXMgbm90IGZvdW5kLg0KICAgICIiIg0KICAgIHJhaXNl IFJ1bnRpbWVFcnJvciwgImdldF9hcmNoaXZlIG5vdCBpbXBsZW1lbnRlZCIN Cg0KICBkZWYgZ2V0X3N1YmZpbGUoc2VsZiwgYXJjaGl2ZSwgbW9kbmFtZSk6 DQogICAgIiIiR2V0IGNvZGUgZnJvbSBhIHN1YmZpbGUgaW4gdGhlIHNwZWNp ZmllZCBhcmNoaXZlLg0KDQogICAgR2l2ZW4gdGhlIHNwZWNpZmllZCBhcmNo aXZlIChhcyByZXR1cm5lZCBieSBnZXRfYXJjaGl2ZSgpKSwgbG9jYXRlDQog ICAgYW5kIHJldHVybiBhIGNvZGUgb2JqZWN0IGZvciB0aGUgc3BlY2lmaWVk IG1vZHVsZSBuYW1lLg0KDQogICAgQSAyLXR1cGxlIG1heSBiZSByZXR1cm5l ZCwgY29uc2lzdGluZyBvZiBhIGNvZGUgb2JqZWN0IGFuZCBhIGRpY3QNCiAg ICBvZiBuYW1lL3ZhbHVlcyB0byBwbGFjZSBpbnRvIHRoZSB0YXJnZXQgbW9k dWxlLg0KDQogICAgUmV0dXJuIE5vbmUgaWYgdGhlIHN1YmZpbGUgd2FzIG5v dCBmb3VuZC4NCiAgICAiIiINCiAgICByYWlzZSBSdW50aW1lRXJyb3IsICJn ZXRfc3ViZmlsZSBub3QgaW1wbGVtZW50ZWQiDQoNCg0KY2xhc3MgUGFja2Fn ZUFyY2hpdmUoUGFja2FnZUFyY2hpdmVJbXBvcnRlcik6DQogICJQYWNrYWdl QXJjaGl2ZUltcG9ydGVyIHN1YmNsYXNzIHRoYXQgcmVmZXJzIHRvIGEgc3Bl Y2lmaWMgYXJjaGl2ZS4iDQoNCiAgZGVmIF9faW5pdF9fKHNlbGYsIG1vZG5h bWUsIGFyY2hpdmVfcGF0aG5hbWUpOg0KICAgIHNlbGYuX19tb2RuYW1lID0g bW9kbmFtZQ0KICAgIHNlbGYuX19wYXRoID0gYXJjaGl2ZV9wYXRobmFtZQ0K DQogIGRlZiBnZXRfYXJjaGl2ZShzZWxmLCBtb2RuYW1lKToNCiAgICBpZiBt b2RuYW1lID09IHNlbGYuX19tb2RuYW1lOg0KICAgICAgcmV0dXJuIHNlbGYu X19wYXRoDQogICAgcmV0dXJuIE5vbmUNCg0KICAjIGdldF9zdWJmaWxlIGlz IHBhc3NlZCB0aGUgZnVsbCBwYXRobmFtZSBvZiB0aGUgYXJjaGl2ZQ0KDQoN CiMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMj IyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMNCiMNCiMgRW11bGF0ZSB0aGUg c3RhbmRhcmQgZGlyZWN0b3J5LWJhc2VkIGltcG9ydCBtZWNoYW5pc20NCiMN CmNsYXNzIERpcmVjdG9yeUltcG9ydGVyKEltcG9ydGVyKToNCiAgIkltcG9y dGVyIHN1YmNsYXNzIHRvIGVtdWxhdGUgdGhlIHN0YW5kYXJkIGltcG9ydGVy LiINCg0KICBkZWYgX19pbml0X18oc2VsZiwgZGlyKToNCiAgICBzZWxmLmRp ciA9IGRpcg0KDQogIGRlZiBnZXRfY29kZShzZWxmLCBwYXJlbnQsIG1vZG5h bWUsIGZxbmFtZSk6DQogICAgaWYgcGFyZW50Og0KICAgICAgZGlyID0gcGFy ZW50Ll9fcGtnZGlyX18NCiAgICBlbHNlOg0KICAgICAgZGlyID0gc2VsZi5k aXINCg0KICAgICMgZGVmZXIgdGhlIGxvYWRpbmcgb2YgT1MtcmVsYXRlZCBm YWNpbGl0aWVzDQogICAgaWYgbm90IF9vc19zdGF0Og0KICAgICAgX29zX2Jv b3RzdHJhcCgpDQoNCiAgICAjIFJldHVybiB0aGUgbW9kdWxlIChhbmQgb3Ro ZXIgaW5mbykgaWYgZm91bmQgaW4gdGhlIHNwZWNpZmllZA0KICAgICMgZGly ZWN0b3J5LiBPdGhlcndpc2UsIHJldHVybiBOb25lLg0KICAgIHJldHVybiBf ZnNfaW1wb3J0KGRpciwgbW9kbmFtZSwgZnFuYW1lKQ0KDQogIGRlZiBfX3Jl cHJfXyhzZWxmKToNCiAgICByZXR1cm4gJzwlcy4lcyBmb3IgIiVzIiBhdCAw eCV4PicgJSAoc2VsZi5fX2NsYXNzX18uX19tb2R1bGVfXywNCiAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi5fX2NsYXNz X18uX19uYW1lX18sDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgIHNlbGYuZGlyLA0KICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICBpZChzZWxmKSkNCg0KIyMjIyMjIyMjIyMjIyMj IyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMj IyMjIyMjIyMjIw0KIw0KIyBFbXVsYXRlIHRoZSBzdGFuZGFyZCBwYXRoLXN0 eWxlIGltcG9ydCBtZWNoYW5pc20NCiMNCmNsYXNzIFBhdGhJbXBvcnRlcihJ bXBvcnRlcik6DQogIGRlZiBfX2luaXRfXyhzZWxmLCBwYXRoPXN5cy5wYXRo KToNCiAgICBzZWxmLnBhdGggPSBwYXRoDQoNCiAgICAjIHdlJ3JlIGRlZmlu aXRlbHkgZ29pbmcgdG8gYmUgaW1wb3J0aW5nIHNvbWV0aGluZyBpbiB0aGUg ZnV0dXJlLA0KICAgICMgc28gbGV0J3MganVzdCBsb2FkIHRoZSBPUy1yZWxh dGVkIGZhY2lsaXRpZXMuDQogICAgaWYgbm90IF9vc19zdGF0Og0KICAgICAg X29zX2Jvb3RzdHJhcCgpDQoNCiAgZGVmIGdldF9jb2RlKHNlbGYsIHBhcmVu dCwgbW9kbmFtZSwgZnFuYW1lKToNCiAgICBpZiBwYXJlbnQ6DQogICAgICAj IHdlIGFyZSBsb29raW5nIGZvciBhIG1vZHVsZSBpbnNpZGUgb2YgYSBzcGVj aWZpYyBwYWNrYWdlDQogICAgICByZXR1cm4gX2ZzX2ltcG9ydChwYXJlbnQu X19wa2dkaXJfXywgbW9kbmFtZSwgZnFuYW1lKQ0KDQogICAgIyBzY2FuIHN5 cy5wYXRoLCBsb29raW5nIGZvciB0aGUgcmVxdWVzdGVkIG1vZHVsZQ0KICAg IGZvciBkaXIgaW4gc2VsZi5wYXRoOg0KICAgICAgcmVzdWx0ID0gX2ZzX2lt cG9ydChkaXIsIG1vZG5hbWUsIGZxbmFtZSkNCiAgICAgIGlmIHJlc3VsdDoN CiAgICAgICAgcmV0dXJuIHJlc3VsdA0KDQogICAgIyBub3QgZm91bmQNCiAg ICByZXR1cm4gTm9uZQ0KDQoNCiMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMj IyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMN CiMNCiMgRW11bGF0ZSB0aGUgaW1wb3J0IG1lY2hhbmlzbSBmb3IgYnVpbHRp biBhbmQgZnJvemVuIG1vZHVsZXMNCiMNCmNsYXNzIEJ1aWx0aW5JbXBvcnRl cihJbXBvcnRlcik6DQogIGRlZiBnZXRfY29kZShzZWxmLCBwYXJlbnQsIG1v ZG5hbWUsIGZxbmFtZSk6DQogICAgaWYgcGFyZW50Og0KICAgICAgIyB0aGVz ZSBtb2R1bGVzIGRlZmluaXRlbHkgZG8gbm90IG9jY3VyIHdpdGhpbiBhIHBh Y2thZ2UgY29udGV4dA0KICAgICAgcmV0dXJuIE5vbmUNCg0KICAgICMgbG9v ayBmb3IgdGhlIG1vZHVsZQ0KICAgIGlmIGltcC5pc19idWlsdGluKG1vZG5h bWUpOg0KICAgICAgdHlwZSA9IGltcC5DX0JVSUxUSU4NCiAgICBlbGlmIGlt cC5pc19mcm96ZW4obW9kbmFtZSk6DQogICAgICB0eXBlID0gaW1wLlBZX0ZS T1pFTg0KICAgIGVsc2U6DQogICAgICAjIG5vdCBmb3VuZA0KICAgICAgcmV0 dXJuIE5vbmUNCg0KICAgICMgZ290IGl0LiBub3cgbG9hZCBhbmQgcmV0dXJu IGl0Lg0KICAgIG1vZHVsZSA9IGltcC5sb2FkX21vZHVsZShtb2RuYW1lLCBO b25lLCBtb2RuYW1lLCAoJycsICcnLCB0eXBlKSkNCiAgICByZXR1cm4gMCwg bW9kdWxlLCB7IH0NCg0KDQojIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMj IyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjDQoj DQojIEludGVybmFsIGltcG9ydGVyIHVzZWQgZm9yIGltcG9ydGluZyBmcm9t IHRoZSBmaWxlc3lzdGVtDQojDQpjbGFzcyBfRmlsZXN5c3RlbUltcG9ydGVy KEltcG9ydGVyKToNCiAgZGVmIF9faW5pdF9fKHNlbGYsIHN1ZmZpeGVzKToN CiAgICAjIHRoaXMgbGlzdCBpcyBzaGFyZWQgd2l0aCB0aGUgSW1wb3J0TWFu YWdlci4NCiAgICBzZWxmLnN1ZmZpeGVzID0gc3VmZml4ZXMNCg0KICBkZWYg aW1wb3J0X2Zyb21fZGlyKHNlbGYsIGRpciwgZnFuYW1lKToNCiAgICByZXN1 bHQgPSBzZWxmLl9pbXBvcnRfcGF0aG5hbWUoX29zX3BhdGhfam9pbihkaXIs IGZxbmFtZSksIGZxbmFtZSkNCiAgICBpZiByZXN1bHQ6DQogICAgICByZXR1 cm4gc2VsZi5fcHJvY2Vzc19yZXN1bHQocmVzdWx0LCBmcW5hbWUpDQogICAg cmV0dXJuIE5vbmUNCg0KICBkZWYgZ2V0X2NvZGUoc2VsZiwgcGFyZW50LCBt b2RuYW1lLCBmcW5hbWUpOg0KICAgICMgVGhpcyBpbXBvcnRlciBpcyBuZXZl ciB1c2VkIHdpdGggYW4gZW1wdHkgcGFyZW50LiBJdHMgZXhpc3RlbmNlIGlz DQogICAgIyBwcml2YXRlIHRvIHRoZSBJbXBvcnRNYW5hZ2VyLiBUaGUgSW1w b3J0TWFuYWdlciB1c2VzIHRoZQ0KICAgICMgaW1wb3J0X2Zyb21fZGlyKCkg bWV0aG9kIHRvIGltcG9ydCB0b3AtbGV2ZWwgbW9kdWxlcy9wYWNrYWdlcy4N CiAgICAjIFRoaXMgbWV0aG9kIGlzIG9ubHkgdXNlZCB3aGVuIHdlIGxvb2sg Zm9yIGEgbW9kdWxlIHdpdGhpbiBhIHBhY2thZ2UuDQogICAgYXNzZXJ0IHBh cmVudA0KDQogICAgcmV0dXJuIHNlbGYuX2ltcG9ydF9wYXRobmFtZShfb3Nf cGF0aF9qb2luKHBhcmVudC5fX3BrZ2Rpcl9fLCBtb2RuYW1lKSwNCiAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZxbmFtZSkNCg0KICBkZWYg X2ltcG9ydF9wYXRobmFtZShzZWxmLCBwYXRobmFtZSwgZnFuYW1lKToNCiAg ICBpZiBfb3NfcGF0aF9pc2RpcihwYXRobmFtZSk6DQogICAgICByZXN1bHQg PSBzZWxmLl9pbXBvcnRfcGF0aG5hbWUoX29zX3BhdGhfam9pbihwYXRobmFt ZSwgJ19faW5pdF9fJyksDQogICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgZnFuYW1lKQ0KICAgICAgaWYgcmVzdWx0Og0KICAgICAgICB2 YWx1ZXMgPSByZXN1bHRbMl0NCiAgICAgICAgdmFsdWVzWydfX3BrZ2Rpcl9f J10gPSBwYXRobmFtZQ0KICAgICAgICB2YWx1ZXNbJ19fcGF0aF9fJ10gPSBb IHBhdGhuYW1lIF0NCiAgICAgICAgcmV0dXJuIDEsIHJlc3VsdFsxXSwgdmFs dWVzDQogICAgICByZXR1cm4gTm9uZQ0KDQogICAgZm9yIHN1ZmZpeCwgaW1w b3J0ZXIgaW4gc2VsZi5zdWZmaXhlczoNCiAgICAgIGZpbGVuYW1lID0gcGF0 aG5hbWUgKyBzdWZmaXgNCiAgICAgIHRyeToNCiAgICAgICAgZmluZm8gPSBf b3Nfc3RhdChmaWxlbmFtZSkNCiAgICAgIGV4Y2VwdCBPU0Vycm9yOg0KICAg ICAgICBwYXNzDQogICAgICBlbHNlOg0KICAgICAgICByZXR1cm4gaW1wb3J0 ZXIuaW1wb3J0X2ZpbGUoZmlsZW5hbWUsIGZpbmZvLCBmcW5hbWUpDQogICAg cmV0dXJuIE5vbmUNCg0KIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMj IyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIw0KIw0K IyBTVUZGSVgtQkFTRUQgSU1QT1JURVJTDQojDQoNCmNsYXNzIFN1ZmZpeElt cG9ydGVyOg0KICBkZWYgaW1wb3J0X2ZpbGUoc2VsZiwgZmlsZW5hbWUsIGZp bmZvLCBmcW5hbWUpOg0KICAgIHJhaXNlIFJ1bnRpbWVFcnJvcg0KDQpjbGFz cyBQeVN1ZmZpeEltcG9ydGVyKFN1ZmZpeEltcG9ydGVyKToNCiAgZGVmIGlt cG9ydF9maWxlKHNlbGYsIGZpbGVuYW1lLCBmaW5mbywgZnFuYW1lKToNCiAg ICBmaWxlID0gZmlsZW5hbWVbOi0zXSArIF9zdWZmaXgNCiAgICB0X3B5ID0g bG9uZyhmaW5mb1s4XSkNCiAgICB0X3B5YyA9IF90aW1lc3RhbXAoZmlsZSkN Cg0KICAgIGNvZGUgPSBOb25lDQogICAgaWYgdF9weWMgaXMgbm90IE5vbmUg YW5kIHRfcHljID49IHRfcHk6DQogICAgICBmID0gb3BlbihmaWxlLCAncmIn KQ0KICAgICAgaWYgZi5yZWFkKDQpID09IGltcC5nZXRfbWFnaWMoKToNCiAg ICAgICAgdCA9IHN0cnVjdC51bnBhY2soJzxJJywgZi5yZWFkKDQpKVswXQ0K ICAgICAgICBpZiB0ID09IHRfcHk6DQogICAgICAgICAgY29kZSA9IG1hcnNo YWwubG9hZChmKQ0KICAgICAgZi5jbG9zZSgpDQogICAgaWYgY29kZSBpcyBO b25lOg0KICAgICAgZmlsZSA9IGZpbGVuYW1lDQogICAgICBjb2RlID0gX2Nv bXBpbGUoZmlsZSwgdF9weSkNCg0KICAgIHJldHVybiAwLCBjb2RlLCB7ICdf X2ZpbGVfXycgOiBmaWxlIH0NCg0KY2xhc3MgRHluTG9hZFN1ZmZpeEltcG9y dGVyKFN1ZmZpeEltcG9ydGVyKToNCiAgZGVmIF9faW5pdF9fKHNlbGYsIGRl c2MpOg0KICAgIHNlbGYuZGVzYyA9IGRlc2MNCg0KICBkZWYgaW1wb3J0X2Zp bGUoc2VsZiwgZmlsZW5hbWUsIGZpbmZvLCBmcW5hbWUpOg0KICAgIGZwID0g b3BlbihmaWxlbmFtZSwgc2VsZi5kZXNjWzFdKQ0KICAgIG1vZHVsZSA9IGlt cC5sb2FkX21vZHVsZShmcW5hbWUsIGZwLCBmaWxlbmFtZSwgc2VsZi5kZXNj KQ0KICAgIG1vZHVsZS5fX2ZpbGVfXyA9IGZpbGVuYW1lDQogICAgcmV0dXJu IDAsIG1vZHVsZSwgeyB9DQoNCg0KIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMj IyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMj Iw0KDQpkZWYgX3Rlc3RfZGlyKCk6DQogICJEZWJ1Zy90ZXN0IGZ1bmN0aW9u IHRvIGNyZWF0ZSBEaXJlY3RvcnlJbXBvcnRlcnMgZnJvbSBzeXMucGF0aC4i DQogIHBhdGggPSBzeXMucGF0aFs6XQ0KICBwYXRoLnJldmVyc2UoKQ0KICBm b3IgZCBpbiBwYXRoOg0KICAgIERpcmVjdG9yeUltcG9ydGVyKGQpLmluc3Rh bGwoKQ0KDQpkZWYgX3Rlc3RfcmV2YW1wKCk6DQogICJEZWJ1Zy90ZXN0IGZ1 bmN0aW9uIGZvciB0aGUgcmV2YW1wZWQgaW1wb3J0IHN5c3RlbS4iDQogIFBh dGhJbXBvcnRlcigpLmluc3RhbGwoKQ0KICBCdWlsdGluSW1wb3J0ZXIoKS5p bnN0YWxsKCkNCg0KZGVmIF9wcmludF9pbXBvcnRlcnMoKToNCiAgaXRlbXMg PSBzeXMubW9kdWxlcy5pdGVtcygpDQogIGl0ZW1zLnNvcnQoKQ0KICBmb3Ig bmFtZSwgbW9kdWxlIGluIGl0ZW1zOg0KICAgIGlmIG1vZHVsZToNCiAgICAg IHByaW50IG5hbWUsIG1vZHVsZS5fX2RpY3RfXy5nZXQoJ19faW1wb3J0ZXJf XycsICctLSBubyBpbXBvcnRlcicpDQogICAgZWxzZToNCiAgICAgIHByaW50 IG5hbWUsICctLSBub24tZXhpc3RlbnQgbW9kdWxlJw0KDQpkZWYgX3Rlc3Rf cmV2YW1wKCk6DQogIEltcG9ydE1hbmFnZXIoKS5pbnN0YWxsKCkNCiAgc3lz LnBhdGguaW5zZXJ0KDAsIEJ1aWx0aW5JbXBvcnRlcigpKQ0KDQojIyMjIyMj IyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMj IyMjIyMjIyMjIyMjIyMjIyMjDQo= --1658348780-1657214722-946868004=:412-- From mal@lemburg.com Mon Jan 3 12:28:34 2000 From: mal@lemburg.com (M.-A. Lemburg) Date: Mon, 03 Jan 2000 13:28:34 +0100 Subject: [Python-Dev] new imputil.py References: Message-ID: <387095F2.2FA64D8E@lemburg.com> Happy New Year :-) [new imputil.py] I tried the new module with the following code: import imputil,sys if sys.argv[1] != 'standard': print 'Installing imputil...', imputil.ImportManager().install() sys.path.insert(0, imputil.BuiltinImporter()) print 'done.' else: print 'Using builtin importer.' print print 'Importing standard stuff...', import string,re,os,sys print 'done.' print 'Importing mx Extensions...', from mx import DateTime,TextTools,ODBC,HTMLTools,UID,URL print 'done.' ### The new importer does load everything in the test set (top level modules, packages, extensions within packages) without problems on Linux. Some comments: · Why is the sys.path.insert(0,imputil.BuiltinImporter()) needed in order to get b/w compatibility ? · Why is there no __path__ aware code in imputil.py (this is definitely needed in order to make it a drop-in replacement) ? · Performance is still 50% of the Python builtin importer -- a bummer if you ask me. More aggressive caching is definitely needed, perhaps even some recoding of methods in C. · The old chaining code should be moved into a subclass of its own. · The code should not import strop directly as this module will probably go away RSN. Use string methods instead. · The design of the ImportManager has some minor flaws: the FS importer should be settable via class attributes, deinstallation should be possible, a query mechanism to find the importer used by a certain import would also be nice to be able to verify correct setup. · py/pyc/pyo file piping hooks would be nice to allow imports of signed (and trusted) code and/or encrypted code (a mixin class for these filters would do the trick). · Wish list: a distutils importer hooked to a list of standard package repositories, a module to file location mapper to speed up file system based imports, -- Marc-Andre Lemburg ______________________________________________________________________ Y2000: Happy New Century ! Business: http://www.lemburg.com/ Python Pages: http://www.lemburg.com/python/ From gstein@lyra.org Mon Jan 3 13:53:00 2000 From: gstein@lyra.org (Greg Stein) Date: Mon, 3 Jan 2000 05:53:00 -0800 (PST) Subject: [Python-Dev] new imputil.py In-Reply-To: <387095F2.2FA64D8E@lemburg.com> Message-ID: Excellent... thanx for the feedback! Comments: On Mon, 3 Jan 2000, M.-A. Lemburg wrote: >... > The new importer does load everything in the test set > (top level modules, packages, extensions within packages) > without problems on Linux. Great! > Some comments: >=20 > =B7 Why is the sys.path.insert(0,imputil.BuiltinImporter())=20 > needed in order to get b/w compatibility ? Because I didn't want to build too much knowledge into the ImportManager. Heck, I think adding sys.path removed some of the design elegence; adding real knowledge of builtins... well, we'll just not talk about that. :-) We could certainly do it this way; let's see what Guido says. I'm not truly adverse to it, but I'd recommend against adding a knowledge of BuiltinImporter to the ImportManager. > =B7 Why is there no __path__ aware code in imputil.py (this is > definitely needed in order to make it a drop-in replacement) ? Because I don't like __path__ :-) I don't think it would be too hard to add, though. If Guido says we need __path__, then I'll add it. I do believe there was a poll a while back where he asked whether anybody truly used it. I don't remember the result and/or Guido's resolution of the matter. > =B7 Performance is still 50% of the Python builtin importer -- > a bummer if you ask me. More aggressive caching is definitely > needed, perhaps even some recoding of methods in C. I'm scared of caching and the possibility for false positives/negatives. But yes, it is still slower and could use some analysis and/or recoding *if* the speed is a problem. Slower imports does not necessarily mean they are "too slow." > =B7 The old chaining code should be moved into a subclass of > its own. Good thought. But really: I'd just rather torch it. This kind of depends on whether we can get away with saying the ImportManager is *the* gateway between the interpreter and Python-level import hooks. In other words, will ImportManager be the *only* Python code to ever be allowed to call sys.set_import_hook() ? If the ImportManager doesn't have to "play with other import hooks", then the chaining can be removed altogether. > =B7 The code should not import strop directly as this module > will probably go away RSN. Use string methods instead. Yah. But I'm running this against 1.5.2 :-) I might be able to do something where the string methods are used if available, and use the strop module if not. [ similar to the 'os' bootstrapping that is done ] Finn Bock emailed me to say that JPython does not have strop, but does have string methods. > =B7 The design of the ImportManager has some minor flaws: the > FS importer should be settable via class attributes, The class or the object itself? Putting a class in there would be nice, or possibly passing it to the constructor (with a suitable default). This is a good idea, though. Please clarify what you'd like to see, and I'll get it added. > deinstallation > should be possible, Maybe. This is somewhat dependent upon whether it must "play nice." Deinstallation would be quite easy if we move to a sys.get/set style of interface, and it wouldn't be an issue to do de-install code. > a query mechanism to find the importer > used by a certain import would also be nice to be able to > verify correct setup. module.__importer__ provides the importer that was used. This is defined behavior (the system relies on that being set to deal with packages properly). Is this sufficient, or were you looking for something else? module.__ispkg__ is also set to 0/1 accordingly. For backwards compat, __file__ and __path__ are also set. The __all__ attribute in an __init__.py file is used for "from package import *". > =B7 py/pyc/pyo file piping hooks would be nice to allow > imports of signed (and trusted) code and/or encrypted code > (a mixin class for these filters would do the trick). I'd happily accept a base SuffixImporter class for these "pipes". I don't believe that the ImportManager, Importer, or SuffixImporter base classes would need any changes, though. Note that I probably will rearrange the _fs_import() and friends, per Guido's suggestion to move them into a base class. That may be a step towards having "pipes" available. > =B7 Wish list: a distutils importer hooked to a list of standard > package repositories, a module to file location mapper to > speed up file system based imports,=20 I'm not sure what the former would do. distutils is still a little nebulous to me right now. For a mapper, we can definitely have a custom Importer that knows where certain modules are found. However, I suspect you're looking for some kind of a cache, but there isn't a hook to say "I found at location" (which would be used to build the mapping). Suggestions on both of these would be most welcome! Cheers, -g --=20 Greg Stein, http://www.lyra.org/ From gvwilson@nevex.com Mon Jan 3 14:02:32 2000 From: gvwilson@nevex.com (gvwilson@nevex.com) Date: Mon, 3 Jan 2000 09:02:32 -0500 (EST) Subject: [Python-Dev] Software Carpentry: GUI Toolkit? Message-ID: Hi, folks. I'm putting together guidelines for submissions to the Software Carpentry design competition (www.software-carpentry.com), and would like to know what I should recommend as a Python GUI toolkit. As I understand it, the alternatives are: - Tkinter: the "standard" answer, but many people think it's showing its age, and it's an installation and update headaches because of its Tcl dependencies. - some other GUI toolkit: but there's no consensus on which one, and documentation is lacking. - CGI scripts (i.e. all interfaces are web pages): has the virtue of simplicity, but could also make some useful interfaces difficult to build (e.g. no drag and drop), and would require users to run a server, or at least get exec privileges, which can be an installation headache. If I've missed a good answer, or if there's somewhere else I should look for a solution, I'd be grateful for a pointer. Thanks, Greg From jim@interet.com Mon Jan 3 14:31:53 2000 From: jim@interet.com (James C. Ahlstrom) Date: Mon, 03 Jan 2000 09:31:53 -0500 Subject: [Python-Dev] new imputil.py References: Message-ID: <3870B2D9.31D0D350@interet.com> Greg Stein wrote: > I've attached a new imputil.py to this message. It isn't posted on my page I don't think you should be using "public domain" as a copyright because you should be protecting the code. Better to use "all rights transferred to CNRI pursuant to the Python contribution agreement", or just copyright it yourself for now. You didn't incorporate the ZipImporter in ftp://ftp.interet.com/pub/importer.py Is that because you want me to, or doesn't it work? JimA From gmcm@hypernet.com Mon Jan 3 14:38:11 2000 From: gmcm@hypernet.com (Gordon McMillan) Date: Mon, 3 Jan 2000 09:38:11 -0500 Subject: [Python-Dev] new imputil.py In-Reply-To: References: <387095F2.2FA64D8E@lemburg.com> Message-ID: <1265213088-25101227@hypernet.com> Greg Stein wrote: > On Mon, 3 Jan 2000, M.-A. Lemburg wrote: [big snip] > > · Wish list: a distutils importer hooked to a list of standard > > package repositories, a module to file location mapper to speed > > up file system based imports, > For a mapper, we can definitely have a custom Importer that knows > where certain modules are found. However, I suspect you're > looking for some kind of a cache, but there isn't a hook to say > "I found at location" (which would be used to build > the mapping). > > Suggestions on both of these would be most welcome! Haven't played with the new one yet. But for awhile I've been considering a scheme where sys.path[0] has a cache of known binary extensions { logicalname: fullpath, ... } and sys.path[-1] is the brute force importer. For standalones, sys.path[0] could be hardcoded. For normal installations, sys.path[-1] could inform sys.path[0] when a .so / .dll / .pyd is found. So when a new one is installed, the first use will be expensive, but subsequent sessions would import it in 1 I/O. I'd also like to point out that archives *can* be used in a development situation. Obviously I wouldn't bother putting a module under current development into an archive. But if the source is still installed and you haven't mucked with the __file__ attribute when you put it in the archive, then tracebacks will show you what you need. IDLE doesn't know the difference. So for most developers, the standard library can be served from an archive with no effect (other than speed). - Gordon From gstein@lyra.org Mon Jan 3 14:57:35 2000 From: gstein@lyra.org (Greg Stein) Date: Mon, 3 Jan 2000 06:57:35 -0800 (PST) Subject: [Python-Dev] new imputil.py In-Reply-To: <3870B2D9.31D0D350@interet.com> Message-ID: On Mon, 3 Jan 2000, James C. Ahlstrom wrote: > Greg Stein wrote: > > I've attached a new imputil.py to this message. It isn't posted on my page > > I don't think you should be using "public domain" as a > copyright because you should be protecting the code. > Better to use "all rights transferred to CNRI pursuant > to the Python contribution agreement", or just copyright > it yourself for now. Public Domain means there are no copyrights on the code. Anybody can claim copyright to it. Anybody can start with my version, slap their name and license on it, and do as they wish. There isn't a way for anybody to "control" public domain software, so there is no need for protection. I like to use Public Domain for code that I want to see as broadly used as possible and/or for short things. There is also a lot that I just don't care what happens with it. If I don't have a vested interest in something, then PD is fine. I wrote imputil as a tool for myself. It isn't something that I feel a need to keep my name on it -- it works for me, it does what I want, it doesn't matter what others do it. It does matter than other people *can* do stuff with it, and PD gives them the most options. Shades of grey... hard to fully explain in an email... but that's the general sentiment. I've got a few things under other licenses, but PD seemed best for imputil. > You didn't incorporate the ZipImporter in > ftp://ftp.interet.com/pub/importer.py > Is that because you want me to, or doesn't it work? I had the redesign to do first. When that settles towards something that Guido is happy with (or he has decided to punt the design altogether), then I'll integrate the ZipImporter. Cheers, -g -- Greg Stein, http://www.lyra.org/ From fdrake@acm.org Mon Jan 3 20:05:22 2000 From: fdrake@acm.org (Fred L. Drake, Jr.) Date: Mon, 3 Jan 2000 15:05:22 -0500 (EST) Subject: [Python-Dev] new imputil.py In-Reply-To: <1265213088-25101227@hypernet.com> References: <387095F2.2FA64D8E@lemburg.com> <1265213088-25101227@hypernet.com> Message-ID: <14449.258.374018.919406@weyr.cnri.reston.va.us> Gordon McMillan writes: > I'd also like to point out that archives *can* be used in a > development situation. Obviously I wouldn't bother putting a > module under current development into an archive. But if the > source is still installed and you haven't mucked with the > __file__ attribute when you put it in the archive, then > tracebacks will show you what you need. IDLE doesn't know > the difference. So for most developers, the standard library > can be served from an archive with no effect (other than speed). I don't see why we can't just add the source to the archive as well; this would allow proper tracebacks even outside the development of the library. Not including sources would cleanly result in the same situation as we currently see when there's only a .pyc file. Am I missing something fundamental? -Fred -- Fred L. Drake, Jr. Corporation for National Research Initiatives From mal@lemburg.com Mon Jan 3 18:22:02 2000 From: mal@lemburg.com (M.-A. Lemburg) Date: Mon, 03 Jan 2000 19:22:02 +0100 Subject: [Python-Dev] Better text processing support in py2k? References: <000901bf53e1$eb4248c0$472d153f@tim> Message-ID: <3870E8CA.7294B813@lemburg.com> Tim Peters wrote: > > >> This is why I do complex string processing in Icon <0.9 wink>. > > [MAL] > > You can have all that extra magic via callable tag objects > > or callable matching functions. It's not exactly nice to > > write, but I'm sure that a meta-language could do the > > conversions for you. > > That wasn't my point: I do it in Icon because it *is* "exactly nice to > write", and doesn't require any yet-another meta-language. It's all > straightforward, in a way that separate schemes pasted together can never be > (simply because they *are* "separate schemes pasted together" ). > > The point of my Python examples wasn't that they could do something > mxTextTools can't do, but that they were *Python* examples: every variation > I mentioned (or that you're likely to think of) was easy to handle for any > Python programmer because the "control flow" and "data type" etc aspects > could be handled exactly the way they always are in *non* pattern-matching > Python code too, rather than recoded in pattern-scheme-specific different > ways (e.g., where I had a vanailla "if/break", you set up a special > exception to tickle the matching engine). > > I'm not attacking mxTextTools, so don't feel compelled to defend it -- Oh, I wasn't defending it -- I know that it is cryptic and sometimes a pain to use. But given that you don't have to invoke a C compiler to get a raw speed I find it a rather useful alternative to code fast utility functions which would otherwise have to be written in C. The other reason it exists is simply because I don't like the recursive style of regexps too much. mxTextTools is simple and straightforward. Backtracking is still possible, but not recommended. > people using regexps in those examples are dead in the water. mxTextTools > is very good at what it does; if we have a real disagreement, it's probably > that I'm less optimistic about the prospects for higher-level wrappers > (e.g., MikeF's SimpleParse is much slower than "a real" BNF parsing system > (ARBNFPS), in part because he isn't doing all the optimizations ARBNFPS > does, but also in part because ARBNFPS uses an underlying engine more > optimized to its specific task than mxTextTool's more-general engine *can* > be). So I don't see mxTextTools as being the answer to everything -- and if > you hadn't written it, you would agree with that on first glance . Oh, I'm sure it *is* the answer to all out problems ;-) ... def main(*dummy): ... from mx.TextTools import * tag("",((main, Skip + CallTag, 0),)) > > Anyway, I'll keep focussing on the speed aspect of mxTextTools; > > others can focus on abstractions, so that eventually everybody > > will be happy :-) > > You and I will be, anyway . Happy New Year :-) -- Marc-Andre Lemburg ______________________________________________________________________ Y2000: Happy New Century ! Business: http://www.lemburg.com/ Python Pages: http://www.lemburg.com/python/ From mal@lemburg.com Tue Jan 4 18:36:00 2000 From: mal@lemburg.com (M.-A. Lemburg) Date: Tue, 04 Jan 2000 19:36:00 +0100 Subject: [Python-Dev] new imputil.py References: Message-ID: <38723D90.D2AE1CA4@lemburg.com> Greg Stein wrote: > > Comments: > > On Mon, 3 Jan 2000, M.-A. Lemburg wrote: > >... > > The new importer does load everything in the test set > > (top level modules, packages, extensions within packages) > > without problems on Linux. > > Great! > > > Some comments: > > > > · Why is the sys.path.insert(0,imputil.BuiltinImporter()) > > needed in order to get b/w compatibility ? > > Because I didn't want to build too much knowledge into the ImportManager. > Heck, I think adding sys.path removed some of the design elegence; adding > real knowledge of builtins... well, we'll just not talk about that. :-) > > We could certainly do it this way; let's see what Guido says. I'm not > truly adverse to it, but I'd recommend against adding a knowledge of > BuiltinImporter to the ImportManager. I was under the impression that the ImportManager should replace the current implementation. In that light it should of course provide all the needed techniques per default without the need to tweak sys.path. > > · Why is there no __path__ aware code in imputil.py (this is > > definitely needed in order to make it a drop-in replacement) ? > > Because I don't like __path__ :-) I don't think it would be too hard to > add, though. > > If Guido says we need __path__, then I'll add it. I do believe there was a > poll a while back where he asked whether anybody truly used it. I don't > remember the result and/or Guido's resolution of the matter. AFAIK, JimF is using it in Zope. I will use it in the b/w compatibility package for the soon to be released mx Extensions packages (instead of using relative imports, BTW -- can't wait for those to happen). > > · Performance is still 50% of the Python builtin importer -- > > a bummer if you ask me. More aggressive caching is definitely > > needed, perhaps even some recoding of methods in C. > > I'm scared of caching and the possibility for false positives/negatives. > > But yes, it is still slower and could use some analysis and/or recoding > *if* the speed is a problem. Slower imports does not necessarily mean they > are "too slow." There has been some moaning about the current Python startup speed, so I guess people already find the existing strategy too slow. Anyway, put the cache risks into the user's hands and have them decide whether or not to use them. The important thing is providing a standard approach to caching which all importers can use and hook into rather than having three or four separate cache implementations. > > · The old chaining code should be moved into a subclass of > > its own. > > Good thought. But really: I'd just rather torch it. This kind of depends > on whether we can get away with saying the ImportManager is *the* gateway > between the interpreter and Python-level import hooks. In other words, > will ImportManager be the *only* Python code to ever be allowed to call > sys.set_import_hook() ? If the ImportManager doesn't have to "play with > other import hooks", then the chaining can be removed altogether. Hmm, nuking the chains might cause some problems with code using the old ni.py or other code such as my old ClassModules.py module which emulates modules using classes (provides all the cool __getattr__ and __setattr__ features to modules as well). > > · The code should not import strop directly as this module > > will probably go away RSN. Use string methods instead. > > Yah. But I'm running this against 1.5.2 :-) > > I might be able to do something where the string methods are used if > available, and use the strop module if not. > [ similar to the 'os' bootstrapping that is done ] > > Finn Bock emailed me to say that JPython does not have strop, but does > have string methods. Since imputil.py targets 1.6 you can safely assume that string methods are in place. > > · The design of the ImportManager has some minor flaws: the > > FS importer should be settable via class attributes, > > The class or the object itself? Putting a class in there would be nice, or > possibly passing it to the constructor (with a suitable default). > > This is a good idea, though. Please clarify what you'd like to see, and > I'll get it added. I usually put these things into the class so that subclasses can easily override the setting. > > deinstallation > > should be possible, > > Maybe. This is somewhat dependent upon whether it must "play nice." > Deinstallation would be quite easy if we move to a sys.get/set style of > interface, and it wouldn't be an issue to do de-install code. I was thinking mainly of debugging situations where you play around with new importer code -- its probably not important for production code. > > a query mechanism to find the importer > > used by a certain import would also be nice to be able to > > verify correct setup. > > module.__importer__ provides the importer that was used. This is defined > behavior (the system relies on that being set to deal with packages > properly). > > Is this sufficient, or were you looking for something else? I was thinking of a situations like: if : or if : raise SystemError,'wrong setup' Don't know if these queries are possible with the current flags and attributes. > module.__ispkg__ is also set to 0/1 accordingly. > > For backwards compat, __file__ and __path__ are also set. The __all__ > attribute in an __init__.py file is used for "from package import *". > > > · py/pyc/pyo file piping hooks would be nice to allow > > imports of signed (and trusted) code and/or encrypted code > > (a mixin class for these filters would do the trick). > > I'd happily accept a base SuffixImporter class for these "pipes". I don't > believe that the ImportManager, Importer, or SuffixImporter base classes > would need any changes, though. > > Note that I probably will rearrange the _fs_import() and friends, per > Guido's suggestion to move them into a base class. That may be a step > towards having "pipes" available. It would be nice to be able to use the concept of stackable streams as source for byte and source code. For this to work one would have to make the file reading process a little more abstract by using e.g. a StreamReader instead (see the current unicode-proposal.txt version). > > · Wish list: a distutils importer hooked to a list of standard > > package repositories, a module to file location mapper to > > speed up file system based imports, > > I'm not sure what the former would do. distutils is still a little > nebulous to me right now. Basically it should scan a set of URLs providing access to package repositories which hold distutils installable package archives. In case it finds a suitable package it should then proceed to auto-install it and then continue the normal import process. > For a mapper, we can definitely have a custom Importer that knows where > certain modules are found. However, I suspect you're looking for some kind > of a cache, but there isn't a hook to say "I found at > location" (which would be used to build the mapping). Right. I would like to see some standard mechanism used throughout the ImportManager for this. One which all importers can use and rely on. E.g. it would be nice to have an option to load the cache from disk upon startup to reduce search times. All this should be left for the user to configure with the standard setting being no cache at all (to avoid confusion and reduce support costs ;-). -- Marc-Andre Lemburg ______________________________________________________________________ Y2000: Happy New Century ! Business: http://www.lemburg.com/ Python Pages: http://www.lemburg.com/python/ From bwarsaw@cnri.reston.va.us (Barry A. Warsaw) Tue Jan 4 21:04:48 2000 From: bwarsaw@cnri.reston.va.us (Barry A. Warsaw) (Barry A. Warsaw) Date: Tue, 4 Jan 2000 16:04:48 -0500 (EST) Subject: [Python-Dev] new imputil.py References: Message-ID: <14450.24688.492098.917284@anthem.cnri.reston.va.us> Happy New Year! >>>>> "GS" == Greg Stein writes: GS> I think Python 1.6 should drop the __import__ builtin and move GS> to something like sys.import_hook (to allow examination and GS> change). Wait! You can't remove builtin __import__ without breaking code. E.g. Mailman uses __import__ quite a bit in its CGI (and other) harnesses. Why does __import__ need to be removed? Why can't it just just the same mechanism the import statement uses? GS> I might be able to do something where the string methods are GS> used if available, and use the strop module if not. [ similar GS> to the 'os' bootstrapping that is done ] GS> Finn Bock emailed me to say that JPython does not have strop, GS> but does have string methods. Sorry Greg, I haven't had time to look at this stuff at all, so maybe I'm missing something essential, but if you just continue to use the string module, you'll be fine for JPython and CPython 1.5.2. In CPython 1.5.2, you /will/ actually be using the strop module under the covers. In CPython 1.6 and JPython 1.1 you'll be using string methods under the covers. Your penalty is one layer of Python function calls. Never use strop directly though. >>>>> "MA" == M writes: MA> There has been some moaning about the current Python startup MA> speed, so I guess people already find the existing strategy MA> too slow. Definitely. -Barry From gmcm@hypernet.com Wed Jan 5 03:49:08 2000 From: gmcm@hypernet.com (Gordon McMillan) Date: Tue, 4 Jan 2000 22:49:08 -0500 Subject: [Python-Dev] new imputil.py In-Reply-To: <14449.258.374018.919406@weyr.cnri.reston.va.us> References: <1265213088-25101227@hypernet.com> Message-ID: <1265079245-1617919@hypernet.com> Fred L. Drake, Jr.wrote: > Gordon McMillan writes: > > I'd also like to point out that archives *can* be used in a > > development situation. Obviously I wouldn't bother putting a > > module under current development into an archive. But if the > > source is still installed and you haven't mucked with the > > __file__ attribute when you put it in the archive, then > > tracebacks will show you what you need. IDLE doesn't know > the > difference. So for most developers, the standard library > can > be served from an archive with no effect (other than speed). > > I don't see why we can't just add the source to the archive as > well; > this would allow proper tracebacks even outside the development > of the library. Not including sources would cleanly result in > the same situation as we currently see when there's only a .pyc > file. > Am I missing something fundamental? Sure you could. Then you could patch IDLE, Pythonwin, etc. to open the proper archive and extract the source. Then you could patch them (and archive) to update on the fly. And while you're at it, I'd really like a jacuzzi jet that gets my neck and shoulders without having to scrunch into all kinds of strange positions. - Gordon Return-Path: Delivered-To: python-dev@dinsdale.python.org Received: from python.org (parrot.python.org [132.151.1.90]) by dinsdale.python.org (Postfix) with ESMTP id A76701CD65 for ; Fri, 14 Jan 2000 12:39:29 -0500 (EST) Received: from merlin.codesourcery.com (IDENT:qmailr@[206.168.99.1]) by python.org (8.9.1a/8.9.1) with SMTP id MAA17463 for ; Fri, 14 Jan 2000 12:39:29 -0500 (EST) Received: (qmail 2115 invoked by uid 513); 14 Jan 2000 17:44:23 -0000 Mailing-List: contact publicity-help@software-carpentry.com; run by ezmlm Delivered-To: mailing list publicity@software-carpentry.com Received: (qmail 2110 invoked from network); 14 Jan 2000 17:44:19 -0000 Date: Fri, 14 Jan 2000 12:40:13 -0500 (EST) From: gvwilson@nevex.com To: publicity@software-carpentry.com Message-ID: MIME-Version: 1.0 Content-Type: MULTIPART/MIXED; BOUNDARY="168427786-1646135556-947871613=:8785" Subject: [Python-Dev] ANNOUNCEMENT: Open Source Design Competition Sender: python-dev-admin@python.org Errors-To: python-dev-admin@python.org X-BeenThere: python-dev@python.org X-Mailman-Version: 1.2 (experimental) Precedence: bulk List-Id: Python core developers This message is in MIME format. The first part should be readable text, while the remaining parts are likely unreadable without MIME-aware tools. Send mail to mime@docserver.cac.washington.edu for more info. --168427786-1646135556-947871613=:8785 Content-Type: TEXT/PLAIN; charset=US-ASCII The Software Carpentry project is pleased to announce the launch of its first Open Source design competition. The project's logo is attached, and details of the competition are included below. This message is being sent to you because you have expressed an interest in covering this story, or publicizing this project. If you have any questions, or do not wish to receive future notices about Software Carpentry, please contact: Dr. Gregory V. Wilson Software Carpentry Project Coordinator (416) 593 2428 gvwilson@software-carpentry.com Thanks for your interest! Greg Wilson ---------------------------------------------------------------------- ---------------------------------------------------------------------- Los Alamos National Laboratory Code Sourcery, LLC Software Carpentry Open Source Design Competition $100,000 in Prizes! ---------------------------------------------------------------------- The Software Carpentry project is pleased to announce its first Open Source design competition, with prizes totaling $100,000. Students and professionals from any country, working individually or in teams, are invited to submit design outlines for: * a platform inspection tool to replace autoconf; * a dependency management tool to replace make; * an issue tracking system to replace gnats and Bugzilla; and * a unit and regression testing harness with the functionality of XUnit, Expect, and DejaGnu. Participants may submit separate entries in one or more categories by March 31, 2000. Entries must be in English, and no more than 5000 words long; examples are available at http://www.software-carpentry.com. The competition will be judged by a panel that includes the following noted software developers, authors, and computational scientists: Stephen Adler Brookhaven National Laboratory Frank Alexander Los Alamos National Laboratory Donnie Barnes Red Hat Chris DiBona VA Linux Paul Dubois Lawrence Livermore National Laboratory Andrew Hunt Pragmatic Programmers, LLC Stephen R. Lee Los Alamos National Laboratory Josh MacDonald University of California, Berkeley Brian Marick Reliable Software Technologies Doug Mewhort Queen's University Bruce Perens co-founder of the Open Source Initiative Dave Thomas Pragmatic Programmers, LLC Jon Udell author of Practical Internet Groupware Guido van Rossum inventor of Python Tom Van Vleck TransIlluminant Phil Wadler Bell Labs Scot Wingo AuctionRover The best four entries in each category will be awarded $2500, and invited to submit full designs by June 1, 2000. The best design in each category will then receive an additional $7500, while runners-up will each receive $2500. Once winning designs have been announced, $200,000 will be available through open bidding for implementation, testing, and documentation. All of the project's work will be Open Source; all tools will be written in, or scriptable with, Python, and will be required to run on both Linux and Microsoft Windows NT. ---------------------------------------------------------------------- The Software Carpentry project is sponsored by the Advanced Computing Laboratory at the U.S. Department of Energy's Los Alamos National Laboratory (http://www.acl.lanl.gov), and administered by Code Sourcery, LLC (http://www.codesourcery.com). The project's aim is to encourage adoption of better software development practices by making software tools easier to use, and by documenting design, testing, and related activities. For more information on the project, or to let us know that you intend to submit a proposal, see http://www.software-carpentry.com, or mail info@software-carpentry.com. --168427786-1646135556-947871613=:8785 Content-Type: IMAGE/GIF; name="software-carpentry-logo.gif" Content-Transfer-Encoding: BASE64 Content-ID: Content-Description: Content-Disposition: attachment; filename="software-carpentry-logo.gif" R0lGODlhLAGhANX/AIACFYU8R2RkZqWlp0pKS+np6tXV1snJyr+/wLW2u+Dh 5srM1Pf4/PT1+e7v877Ax4GDiZygq6Sos4yPl5aZobm7wNrc4aywuXF0efv8 /M7PzywtLJF8U0s4F6mTa76pgXBeQE0+LeDb2M7JxsfAvaCPi7yysJBxb7Ge nf////7+/v39/fv7+/n5+fj4+Pb29vPz8/Ly8u/v7+3t7ebm5uLi4t3d3dnZ 2dLS0sXFxa6urh4eHg8PDwgICAMDAwAAACwAAAAALAGhAEAG/8CUcEgsGo/I pHLJbDqf0Kh0Sq1ar9isdsvter/gsFipcjXLQ1aBhtDg3m/NLdN0rZotVpPV aq7MTH9OLipFOSgxRXZ4dEx5e3pMLJFLGYBLgkxld0yLjpRKj0ktM4VEMgk6 FRcQGBILCrELEwITCRe4uRgEBAICvLwYF6sJEjV9RC4yRjKJRCwzoCkxy0QZ BdIupUUzL0WkpkMyMEUrMnQ2HOoeHh/u7OocJi8uOiEgNUYzAhsbO/0EMPDb UKFQDG/WYtjYEKJfCF4gfIEgQCOGtBfOhqiYcUmINmYIh7SQEU4ItSIZohWB UW3IigLIRM7gJI7csxmNaip5QYNmEv8XNKRV2EBBxYAdDNSETLKChs0lNTRU OFIBgqkZBZrA6MmEp7QiKOJxaDcihQsDJFCUKAHhBIgOHULEKGmEBoF//XYE HDhhhYoCLZXIKKADAwQlJ1sgmNBKgEDHkIsy2ZozCQsaHZFcXpoEcJMCMwTb ALWiRlYiMGx0/BtBQtaiLWxkFDKjhk8WNgKnmGGDZoFYFiwUFPLiBgRftf7S UGTjqRAZo4mUPj1EYcwUKmhoEABiLAEIE2h15/BWQGsJEnANuFGkQA1QGWjY zbvBVz8KQqavVE0kO42SL9jAmXu35bYSCnB15wEJNYR2SnRE0FBDSS40196E RMSWAAUYTHD/zAET2BCOCqbtl5l8ShRwA2dHyHCDc0JQcEEBKsBmgIOh3EAd Ei48oMABQjQgwQY//CCMQAqkUIOITKh4HRIz3HDJDOCBF94EFGQZwZbopYfL A/iZpWMnNmQ1UH13IZCGDRgqUVpvS5AIYYqjIQBXBwpyI+USF0TgCwQX3HJB el12GcFxyGG5I3Y2LIcdBCOscINhBVAAgwpsKlEDDoG1YMANoBSAw464UeBa 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 d8M73tIIAgA7 --168427786-1646135556-947871613=:8785-- From jeremy@cnri.reston.va.us Mon Jan 17 20:35:37 2000 From: jeremy@cnri.reston.va.us (Jeremy Hylton) Date: Mon, 17 Jan 2000 15:35:37 -0500 (EST) Subject: [Python-Dev] developers day session on compilers Message-ID: <14467.32025.761662.841271@goon.cnri.reston.va.us> I am championing a Developers' Day session on a Python compiler. There is a short Web page describing the goals of the session at http://www.python.org/workshops/2000-01/compiler.html. I'd appreciate feedback on the content and format of the session. If you have ideas for what we should talk about or do, please followup to me or to the list. Jeremy From mal@lemburg.com Tue Jan 18 22:55:04 2000 From: mal@lemburg.com (M.-A. Lemburg) Date: Tue, 18 Jan 2000 23:55:04 +0100 Subject: [Python-Dev] Python Tools/ Message-ID: <3884EF48.A6107775@lemburg.com> I was just looking through the Tools dir of the CVS version (looking for a tool which autoexpands tabs in Python source files -- which I didn't find) and found some other useful scripts along the way. To my surprise these executable files did not have a .py extension even though were Python source files. Is this intended ? I find that scripts like "world" provide useful information which would be nice to have in the standard lib -- with .py extension... Other tidbits: I noted that at least in my CVS tree the Tools/ht2html dir does not include any executable: have I missed something ? The script Tools/scripts/parseentities.py is not executable for some reason. -- Marc-Andre Lemburg ______________________________________________________________________ Business: http://www.lemburg.com/ Python Pages: http://www.lemburg.com/python/ From guido@CNRI.Reston.VA.US Wed Jan 19 12:50:05 2000 From: guido@CNRI.Reston.VA.US (Guido van Rossum) Date: Wed, 19 Jan 2000 07:50:05 -0500 Subject: [Python-Dev] Python Tools/ In-Reply-To: Your message of "Tue, 18 Jan 2000 23:55:04 +0100." <3884EF48.A6107775@lemburg.com> References: <3884EF48.A6107775@lemburg.com> Message-ID: <200001191250.HAA18786@eric.cnri.reston.va.us> > I was just looking through the Tools dir of the CVS version > (looking for a tool which autoexpands tabs in Python source > files -- which I didn't find) and found some other useful scripts > along the way. > > To my surprise these executable files did not have a .py > extension even though were Python source files. Is this > intended ? I find that scripts like "world" provide useful > information which would be nice to have in the standard > lib -- with .py extension... I would agree, but that's Barry's creation, so I'll let him answer for himself. Any other scripts with the same problem? > Other tidbits: > > I noted that at least in my CVS tree the Tools/ht2html > dir does not include any executable: have I missed something ? Actually, that directory is a ghost and shouldn't have been exported at all. (Barry, can you erase it from sweetpea?) > The script Tools/scripts/parseentities.py is not executable > for some reason. Fixed now. --Guido van Rossum (home page: http://www.python.org/~guido/) From bwarsaw@cnri.reston.va.us (Barry A. Warsaw) Wed Jan 19 16:24:41 2000 From: bwarsaw@cnri.reston.va.us (Barry A. Warsaw) (Barry A. Warsaw) Date: Wed, 19 Jan 2000 11:24:41 -0500 (EST) Subject: [Python-Dev] Python Tools/ References: <3884EF48.A6107775@lemburg.com> Message-ID: <14469.58697.116588.501355@anthem.cnri.reston.va.us> >>>>> "M" == M writes: M> To my surprise these executable files did not have a .py M> extension even though were Python source files. Is this M> intended ? I find that scripts like "world" provide useful M> information which would be nice to have in the standard M> lib -- with .py extension... I hadn't thought about making world a module, but if others agree, I can play a little CVS magic to move the file to world.py. M> I noted that at least in my CVS tree the Tools/ht2html dir does M> not include any executable: have I missed something ? If you do a `cvs up -P' (-P for prune) you'll find that that directory goes away. At one point I started to add the ht2html scripts to the Python tools, but then we decided not to. Unfortunately, once a directory's been added to CVS it can never be removed (hence -P). If you're really interested in the ht2html scripts, which are used to build the Python.Org and JPython.Org sites (as well as my personal pages), please see http://www.python.org/~bwarsaw/software/pyware.html -Barry From bwarsaw@cnri.reston.va.us (Barry A. Warsaw) Wed Jan 19 17:32:50 2000 From: bwarsaw@cnri.reston.va.us (Barry A. Warsaw) (Barry A. Warsaw) Date: Wed, 19 Jan 2000 12:32:50 -0500 (EST) Subject: [Python-Dev] Python Tools/ References: <3884EF48.A6107775@lemburg.com> <14469.58697.116588.501355@anthem.cnri.reston.va.us> Message-ID: <14469.62786.178265.983781@anthem.cnri.reston.va.us> >>>>> "BAW" == Barry A Warsaw writes: BAW> If you do a `cvs up -P' (-P for prune) you'll find that that BAW> directory goes away. At one point I started to add the BAW> ht2html scripts to the Python tools, but then we decided not BAW> to. Unfortunately, once a directory's been added to CVS it BAW> can never be removed (hence -P). I just check this and there is no ht2html directory in Tools anymore. We probably did remove it after you (MAL) had checked it out. You can either ignore the directory, or delete it from your working dirs. If cvs complains after deleting it, you may have to manually edit the CVS/Entries file. Sorry about that -- we know better now. -Barry From gerrit@nl.linux.org Wed Jan 19 20:14:27 2000 From: gerrit@nl.linux.org (Gerrit Holl) Date: Wed, 19 Jan 2000 21:14:27 +0100 Subject: [Python-Dev] ''.join in 1.6 Message-ID: <20000119211427.A3755@stopcontact.palga.uucp> Hello, I have a question/suggestion about ''.join in Python 1.6. Suppose I have this list: l = ["This", "is", "a", "test"] Currently, I would join it this way into a tab-delimeted string: s = string.join(l, '\t') In 1.6, I should do it this way: '\t'.join(s) I think it would be better to have that method on the *list*: s.join('\t') That's more clear, isn't it? regards, Gerrit. -- Please correct any bad English you encounter in my email message! -----BEGIN GEEK CODE BLOCK----- http://www.geekcode.com Version: 3.12 GCS dpu s-:-- a14 C++++>$ UL++ P--- L+++ E--- W++ N o? K? w--- !O !M !V PS+ PE? Y? PGP-- t- 5? X? R- tv- b+(++) DI D+ G++ !e !r !y -----END GEEK CODE BLOCK----- From fredrik@pythonware.com Wed Jan 19 20:43:36 2000 From: fredrik@pythonware.com (Fredrik Lundh) Date: Wed, 19 Jan 2000 21:43:36 +0100 Subject: [Python-Dev] ''.join in 1.6 References: <20000119211427.A3755@stopcontact.palga.uucp> Message-ID: <005e01bf62bd$dc8073d0$f29b12c2@secret.pythonware.com> > In 1.6, I should do it this way: > '\t'.join(s) >=20 > I think it would be better to have that method on the *list*: > s.join('\t') >=20 > That's more clear, isn't it? what if "s" is a tuple? an array? a user-defined sequence type? From bwarsaw@cnri.reston.va.us (Barry A. Warsaw) Wed Jan 19 20:36:24 2000 From: bwarsaw@cnri.reston.va.us (Barry A. Warsaw) (Barry A. Warsaw) Date: Wed, 19 Jan 2000 15:36:24 -0500 (EST) Subject: [Python-Dev] ''.join in 1.6 References: <20000119211427.A3755@stopcontact.palga.uucp> Message-ID: <14470.8264.686274.888365@anthem.cnri.reston.va.us> >>>>> "GH" == Gerrit Holl writes: GH> I think it would be better to have that method on the *list*: GH> s.join('\t') GH> That's more clear, isn't it? Perhaps, but you want join to work on any sequence don't you? By making it a method on string objects, you sort of get that for free (as opposed to putting it on lists, sequences, and requiring all class authors to add it as well). -Barry From da@ski.org Wed Jan 19 20:54:03 2000 From: da@ski.org (David Ascher) Date: Wed, 19 Jan 2000 12:54:03 -0800 Subject: [Python-Dev] ''.join in 1.6 In-Reply-To: <20000119211427.A3755@stopcontact.palga.uucp> Message-ID: <003b01bf62bf$5191abc0$c355cfc0@ski.org> Gerrit Holl > Currently, I would join it this way into a tab-delimeted string: > s = string.join(l, '\t') > > In 1.6, I should do it this way: > '\t'.join(s) > > I think it would be better to have that method on the *list*: > s.join('\t') > > That's more clear, isn't it? As Tim pointed out when they were discussed, the clearest way to express it with the new methods is to do: tab = '\t' tab.join(s) Similarly space = ' ' space.join(s) etc. --david ascher From da@ski.org Wed Jan 19 22:41:47 2000 From: da@ski.org (David Ascher) Date: Wed, 19 Jan 2000 14:41:47 -0800 Subject: [Python-Dev] SOAP Message-ID: <000101bf62ce$5e509e70$c355cfc0@ski.org> This is a multi-part message in MIME format. ------=_NextPart_000_0002_01BF628B.502D5E70 Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: 7bit Who if anyone is working on SOAP clients and servers for Python? --david ascher ------=_NextPart_000_0002_01BF628B.502D5E70 Content-Type: text/x-vcard; name="David Ascher.vcf" Content-Transfer-Encoding: quoted-printable Content-Disposition: attachment; filename="David Ascher.vcf" BEGIN:VCARD VERSION:2.1 N:Ascher;David FN:David Ascher ORG:Smith Kettlewell Eye Research Institute TEL;WORK;VOICE:415-345-2095 TEL;HOME;VOICE:415-345-2095 TEL;WORK;FAX:415-345-8455 ADR;WORK:;;2318 Fillmore St;San Francisco;CA;94115;US LABEL;WORK;ENCODING=3DQUOTED-PRINTABLE:2318 Fillmore St=3D0D=3D0ASan = Francisco, CA 94115=3D0D=3D0AUS ADR;HOME:;;522A Green St;San Francisco;CA;94133;US LABEL;HOME;ENCODING=3DQUOTED-PRINTABLE:522A Green St=3D0D=3D0ASan = Francisco, CA 94133=3D0D=3D0AUS EMAIL;PREF;INTERNET:da@ski.org REV:20000107T184849Z END:VCARD ------=_NextPart_000_0002_01BF628B.502D5E70-- From akuchlin@mems-exchange.org Thu Jan 20 04:19:33 2000 From: akuchlin@mems-exchange.org (A.M. Kuchling) Date: Wed, 19 Jan 2000 23:19:33 -0500 Subject: [Python-Dev] Changing existing class instances Message-ID: <200001200419.XAA01969@mira.erols.com> Currently, when you replace a class definition with an updated version, it's really difficult to change existing class instances; you'd have to essentially sweep every Python object and check if it's an instance, starting at roots such as __main__ and sys.modules. This makes developing code in a long-running process difficult, Zope being the best example of this. When you modify a class definition used by Zope code, you can't update existing instances floating around in memory. Over dinner, a friend and I were discussing this, and we thought it probably isn't difficult to add an extra level of indirection to allow fixing this. The only other option we could think of is either the complete scan of all objects, or inserting a forwarding pointer into PyClassObjects that points to the replacing class if !NULL, and then chase pointers when accessing PyInstanceObject->in_class. A quick hack to implement the extra indirection took about half an hour. It does these things: * Defines a PyClassHandle type: struct _PyClassHandle { PyClassHandle *next; /* ptr to next PyClassHandle in linked list */ PyClassObject *klass; /* The class object */ } ; * The in_class attribute of PyInstanceObject becomes a PyClassHandle* instead of a PyClassObject*, and all code such as inst->in_class becomes inst->in_class->klass. * As a quick hack to allow changing the class object referenced by a handle, I added a .forward( ) method to class objects. This basically does self.handle->klass = . The end result is that obj.__class__.forward(newclass) changes obj to be an instance of newclass, and all other instances of obj.__class__ also mutate to become newclass instances. Making this purely automatic seems hard; you'd have to catch things like 'import ftplib; ftplib.FTP = myclass', which would require automatically calling ftplib.FTP.forward( myclass ) to make all existing FTP instances mutate. Would it be worthwhile to export some hook for doing this in 1.6? The cost is adding an extra pointer deref to all access to PyInstanceObject->in_class. (This could probably also be added to ExtensionClass, and probably doesn't need to be added to core Python to help out Zope. Just a thought...) -- A.M. Kuchling http://starship.python.net/crew/amk/ Here the skull of a consumptive child becomes part of a great machine for calculating the motions of the stars. Here, a yellow bird frets within the ribcage of an unjust man. -- Welcome to Orqwith, in DOOM PATROL #22 From guido@CNRI.Reston.VA.US Thu Jan 20 04:41:29 2000 From: guido@CNRI.Reston.VA.US (Guido van Rossum) Date: Wed, 19 Jan 2000 23:41:29 -0500 Subject: [Python-Dev] Changing existing class instances In-Reply-To: Your message of "Wed, 19 Jan 2000 23:19:33 EST." <200001200419.XAA01969@mira.erols.com> References: <200001200419.XAA01969@mira.erols.com> Message-ID: <200001200441.XAA20952@eric.cnri.reston.va.us> > Currently, when you replace a class definition with an updated > version, it's really difficult to change existing class instances; > you'd have to essentially sweep every Python object and check if it's > an instance, starting at roots such as __main__ and sys.modules. This > makes developing code in a long-running process difficult, Zope being > the best example of this. When you modify a class definition used by > Zope code, you can't update existing instances floating around in > memory. There might be another solution. When you reload a module, the module object and its dictionary are reused. Perhaps class and function objects could similarly be reused? It would mean that a class or def statement looks for an existing object with the same name and type, and overwrites that. Voila, all references are automatically updated. This is more work (e.g. for classes, a new bytecode may have to be invented because the class creation process must be done differently) but it's much less of a hack, and I think it would be more reliable. (Even though it alters borderline semantics a bit.) (Your extra indirection also slows things down, although I don't know by how much -- not just the extra memory reference but also less locality of reference so more cache hits.) --Guido van Rossum (home page: http://www.python.org/~guido/) From tim_one@email.msn.com Thu Jan 20 05:59:51 2000 From: tim_one@email.msn.com (Tim Peters) Date: Thu, 20 Jan 2000 00:59:51 -0500 Subject: [Python-Dev] Changing existing class instances In-Reply-To: <200001200441.XAA20952@eric.cnri.reston.va.us> Message-ID: <000b01bf630b$91a409a0$31a2143f@tim> [Guido, on Andrew's idea for automagically updating classes] > There might be another solution. When you reload a module, > the module object and its dictionary are reused. > > Perhaps class and function objects could similarly be > reused? It would mean that a class or def statement > looks for an existing object with the same name and type, > and overwrites that. Voila, all references are > automatically updated. Too dangerous, I think. While uncommon in general, I've certainly seen (even written) functions that e.g. return a contained def or class. The intent in such cases is very much to create distinct defs or classes (despite having the same names). In this case I assume "the same name" wouldn't *usually* be found, since the "contained def or class"'s name is local to the containing function. But if there ever happened to be a module-level function or class of the same name, brrrr. Modules differ because their namespace "search path" consists solely of the more-global-than-global sys.modules. > This is more work (e.g. for classes, a new bytecode may > have to be invented because the class creation process > must be done differently) but it's much less of a hack, > and I think it would be more reliable. (Even though it > alters borderline semantics a bit.) How about an explicit function in the "new" module, new.update(class_or_def_old, class_or_def_new) which overwrites old's guts with new's guts (in analogy with dict.update)? Then no semantics change and you don't need new bytecodes. In return, a user who wants to e.g. replace an existing class C would need to do oldC = C do whatever they do to get the new C new.update(oldC, C) Building on that, a short Python loop could do the magic for every class and function in a module; and building on *that*, a short "updating import" function could be written in Python. View it as providing mechanism instead of policy <0.9 wink>. > (Your extra indirection also slows things down, although > I don't know by how much -- not just the extra memory > reference but also less locality of reference so more > cache hits.) Across the universe of all Python programs on all platforms, weighted by importance, it was a slowdown of nearly 4.317%. if-i-had-used-only-one-digit-everyone-would-have- known-i-was-making-it-up-ly y'rs - tim From gstein@lyra.org Thu Jan 20 07:48:29 2000 From: gstein@lyra.org (Greg Stein) Date: Wed, 19 Jan 2000 23:48:29 -0800 (PST) Subject: [Python-Dev] Changing existing class instances In-Reply-To: <000b01bf630b$91a409a0$31a2143f@tim> Message-ID: Oh man, oh man... I think this is where I get to say something akin to "I told you so." :-) I already described Tim's proposal in my type proposal paper, as a way to deal with incomplete classes. Essentially, a class object is created "empty" and is later "updated" with the correct bits. The empty class allows two classes to refer to each other in the "recursive type" scenario. In other words, I definitely would support a new class object behavior that allows us to update a class' set of bases and dictionary on the fly. This could then be used to support my solution for the recursive type scenario (which, in turn, means that we don't have to introduce Yet Another Namespace into Python to hold type names). Note: I would agree with Guido, however, on the "look for a class object with the same name", but with the restriction that the name is only replaced in the *target* namespace. i.e. a "class Foo" in a function will only look for Foo in the function's local namespace; it would not overwrite a class in the global space, nor would it overwrite class objects returned by a prior invocation of the function. Cheers, -g On Thu, 20 Jan 2000, Tim Peters wrote: > [Guido, on Andrew's idea for automagically updating > classes] > > > There might be another solution. When you reload a module, > > the module object and its dictionary are reused. > > > > Perhaps class and function objects could similarly be > > reused? It would mean that a class or def statement > > looks for an existing object with the same name and type, > > and overwrites that. Voila, all references are > > automatically updated. > > Too dangerous, I think. While uncommon in general, I've certainly seen > (even written) functions that e.g. return a contained def or class. The > intent in such cases is very much to create distinct defs or classes > (despite having the same names). In this case I assume "the same name" > wouldn't *usually* be found, since the "contained def or class"'s name is > local to the containing function. But if there ever happened to be a > module-level function or class of the same name, brrrr. > > Modules differ because their namespace "search path" consists solely of the > more-global-than-global sys.modules. > > > This is more work (e.g. for classes, a new bytecode may > > have to be invented because the class creation process > > must be done differently) but it's much less of a hack, > > and I think it would be more reliable. (Even though it > > alters borderline semantics a bit.) > > How about an explicit function in the "new" module, > > new.update(class_or_def_old, class_or_def_new) > > which overwrites old's guts with new's guts (in analogy with dict.update)? > Then no semantics change and you don't need new bytecodes. In return, a > user who wants to e.g. replace an existing class C would need to do > > oldC = C > do whatever they do to get the new C > new.update(oldC, C) > > Building on that, a short Python loop could do the magic for every class and > function in a module; and building on *that*, a short "updating import" > function could be written in Python. View it as providing mechanism instead > of policy <0.9 wink>. > > > (Your extra indirection also slows things down, although > > I don't know by how much -- not just the extra memory > > reference but also less locality of reference so more > > cache hits.) > > Across the universe of all Python programs on all platforms, weighted by > importance, it was a slowdown of nearly 4.317%. > > if-i-had-used-only-one-digit-everyone-would-have- > known-i-was-making-it-up-ly y'rs - tim > > > > _______________________________________________ > Python-Dev maillist - Python-Dev@python.org > http://www.python.org/mailman/listinfo/python-dev > -- Greg Stein, http://www.lyra.org/ From fredrik@pythonware.com Thu Jan 20 08:06:32 2000 From: fredrik@pythonware.com (Fredrik Lundh) Date: Thu, 20 Jan 2000 09:06:32 +0100 Subject: [Python-Dev] SOAP References: <000101bf62ce$5e509e70$c355cfc0@ski.org> Message-ID: <006901bf631d$449eea50$f29b12c2@secret.pythonware.com> David Ascher wrote: > Who if anyone is working on SOAP clients and servers for Python? we are (or rather, we will). hope to have code available during (late) Q1. From gerrit@nl.linux.org Thu Jan 20 08:08:01 2000 From: gerrit@nl.linux.org (Gerrit Holl) Date: Thu, 20 Jan 2000 09:08:01 +0100 Subject: [Python-Dev] ''.join in 1.6 In-Reply-To: <005e01bf62bd$dc8073d0$f29b12c2@secret.pythonware.com>; from fredrik@pythonware.com on Wed, Jan 19, 2000 at 09:43:36PM +0100 References: <20000119211427.A3755@stopcontact.palga.uucp> <005e01bf62bd$dc8073d0$f29b12c2@secret.pythonware.com> Message-ID: <20000120090801.A903@stopcontact.palga.uucp> Fredrik Lundh wrote on 948314616: > > In 1.6, I should do it this way: > > '\t'.join(s) > > > > I think it would be better to have that method on the *list*: > > s.join('\t') > > > > That's more clear, isn't it? > > what if "s" is a tuple? an array? a user-defined > sequence type? I understand. Thanks for your answers. regards, Gerrit. -- Please correct any bad English you encounter in my email message! -----BEGIN GEEK CODE BLOCK----- http://www.geekcode.com Version: 3.12 GCS dpu s-:-- a14 C++++>$ UL++ P--- L+++ E--- W++ N o? K? w--- !O !M !V PS+ PE? Y? PGP-- t- 5? X? R- tv- b+(++) DI D+ G++ !e !r !y -----END GEEK CODE BLOCK----- From jim@digicool.com Thu Jan 20 14:06:29 2000 From: jim@digicool.com (Jim Fulton) Date: Thu, 20 Jan 2000 09:06:29 -0500 Subject: [Python-Dev] Changing existing class instances References: <200001200419.XAA01969@mira.erols.com> Message-ID: <38871665.C3B6FFEE@digicool.com> "A.M. Kuchling" wrote: > > Currently, when you replace a class definition with an updated > version, it's really difficult to change existing class instances; > you'd have to essentially sweep every Python object and check if it's > an instance, starting at roots such as __main__ and sys.modules. This > makes developing code in a long-running process difficult, Zope being > the best example of this. When you modify a class definition used by > Zope code, you can't update existing instances floating around in > memory. In the case of Zope, if the objects that you care about happen to be persistent objects, then it's relatively easy to arrange to get the objects flushed from memory and reloaded with the new classes. (There are some subtle issues to deal with, like worrying about multiple threads, but in a development environment, you can deal with these, for example, by limiting the server to one thread.) Note that this is really only a special case of a much larger problem. Reloading a module redefines the global variables in a module. It doesn't update any references to those global references from other places, such as instances or *other* modules. For example, imports like: from foo import spam are not updated when foo is reloaded. Maybe you are expecting too much from reload. Jim -- Jim Fulton mailto:jim@digicool.com Technical Director (888) 344-4332 Python Powered! Digital Creations http://www.digicool.com http://www.python.org Under US Code Title 47, Sec.227(b)(1)(C), Sec.227(a)(2)(B) This email address may not be added to any commercial mail list with out my permission. Violation of my privacy with advertising or SPAM will result in a suit for a MINIMUM of $500 damages/incident, $1500 for repeats. From jim@digicool.com Thu Jan 20 14:34:13 2000 From: jim@digicool.com (Jim Fulton) Date: Thu, 20 Jan 2000 09:34:13 -0500 Subject: Python 2 namespace change? (was Re: [Python-Dev] Changing existing class instances) References: <200001200419.XAA01969@mira.erols.com> <38871665.C3B6FFEE@digicool.com> Message-ID: <38871CE5.53FB9D68@digicool.com> Jim Fulton wrote: > > Reloading a module redefines the global variables in a module. > It doesn't update any references to those global references > from other places, such as instances or *other* modules. > > For example, imports like: > > from foo import spam > > are not updated when foo is reloaded. A change to the way that namespaces are handled could make this work and have a number of other benefits, like global name usage without namespace lookups. I've suggested this to Guido in the past. His reasonable response is that this would be too big a change for Python 1. Maybe this is something to consider for Python 2? The basic idea (borrowed from Smalltalk) is to have a kind of dictionary that is a collection of "association" objects. An association object is simply a pairing of a name with a value. Association objects can be shared among multiple namespaces. An import like: from foo import spam would copy the association between the name 'foo' and a value from module 'spam' into the current module. If foo is reloaded or if the name is reassigned in spam, the association is modified and the change is seen in any namespaces that imported foo. Similarly if a function uses a global variable: spam=1 def bar(): global spam return spam*2 the compiled function contains the association between spam and it's value. This means that: - When spam is used in the function, it doesn't have to be looked up, - The function object no longer needs to keep a reference to it's globals. This eliminates an annoying circular reference. (I would not replace existing dictionaries with this new kind. I'd have both kinds available.) I think that this would be a really nice change for Python 2. Jim -- Jim Fulton mailto:jim@digicool.com Technical Director (888) 344-4332 Python Powered! Digital Creations http://www.digicool.com http://www.python.org Under US Code Title 47, Sec.227(b)(1)(C), Sec.227(a)(2)(B) This email address may not be added to any commercial mail list with out my permission. Violation of my privacy with advertising or SPAM will result in a suit for a MINIMUM of $500 damages/incident, $1500 for repeats. From guido@CNRI.Reston.VA.US Thu Jan 20 15:20:45 2000 From: guido@CNRI.Reston.VA.US (Guido van Rossum) Date: Thu, 20 Jan 2000 10:20:45 -0500 Subject: [Python-Dev] Changing existing class instances In-Reply-To: Your message of "Thu, 20 Jan 2000 00:59:51 EST." <000b01bf630b$91a409a0$31a2143f@tim> References: <000b01bf630b$91a409a0$31a2143f@tim> Message-ID: <200001201520.KAA21137@eric.cnri.reston.va.us> > From: "Tim Peters" > > [Guido, on Andrew's idea for automagically updating > classes] > > > There might be another solution. When you reload a module, > > the module object and its dictionary are reused. > > > > Perhaps class and function objects could similarly be > > reused? It would mean that a class or def statement > > looks for an existing object with the same name and type, > > and overwrites that. Voila, all references are > > automatically updated. > > Too dangerous, I think. While uncommon in general, I've certainly seen > (even written) functions that e.g. return a contained def or class. The > intent in such cases is very much to create distinct defs or classes > (despite having the same names). In this case I assume "the same name" > wouldn't *usually* be found, since the "contained def or class"'s name is > local to the containing function. But if there ever happened to be a > module-level function or class of the same name, brrrr. Agreed that that would be bad. But I wouldn't search outer scopes -- I would only look for a class/def that I was about to stomp on. > Modules differ because their namespace "search path" consists solely of the > more-global-than-global sys.modules. "The search path doesn't enter into it." > > This is more work (e.g. for classes, a new bytecode may > > have to be invented because the class creation process > > must be done differently) but it's much less of a hack, > > and I think it would be more reliable. (Even though it > > alters borderline semantics a bit.) > > How about an explicit function in the "new" module, > > new.update(class_or_def_old, class_or_def_new) > > which overwrites old's guts with new's guts (in analogy with dict.update)? > Then no semantics change and you don't need new bytecodes. Only a slight semantics change (which my full proposal would require too): function objects would become mutable -- their func_code, func_defaults, func_doc and func_globals fields (and, why not, func_name too) should be changeable. If you make all these assignable, it doesn't even have to be a privileged function. > In return, a > user who wants to e.g. replace an existing class C would need to do > > oldC = C > do whatever they do to get the new C > new.update(oldC, C) > > Building on that, a short Python loop could do the magic for every class and > function in a module; and building on *that*, a short "updating import" > function could be written in Python. View it as providing mechanism instead > of policy <0.9 wink>. That's certainly a reasonable compromise. Note that the update on a class should imply an update on its methods, right? --Guido van Rossum (home page: http://www.python.org/~guido/) From guido@CNRI.Reston.VA.US Thu Jan 20 15:45:40 2000 From: guido@CNRI.Reston.VA.US (Guido van Rossum) Date: Thu, 20 Jan 2000 10:45:40 -0500 Subject: Python 2 namespace change? (was Re: [Python-Dev] Changing existing class instances) In-Reply-To: Your message of "Thu, 20 Jan 2000 09:34:13 EST." <38871CE5.53FB9D68@digicool.com> References: <200001200419.XAA01969@mira.erols.com> <38871665.C3B6FFEE@digicool.com> <38871CE5.53FB9D68@digicool.com> Message-ID: <200001201545.KAA21304@eric.cnri.reston.va.us> > I've suggested this to Guido in the past. His > reasonable response is that this would be too big a > change for Python 1. Maybe this is something to consider > for Python 2? Note: from now on the new name for Python 2 is Python 3000. :-) > The basic idea (borrowed from Smalltalk) is to have a kind > of dictionary that is a collection of "association" > objects. An association object is simply a pairing of a > name with a value. Association objects can be shared among > multiple namespaces. I've never liked this very much, mostly because it breaks simplicity: the idea that a namespace is a mapping from names to values (e.g. {"limit": 100, "doit": , ...}) is beautifully simple, while the idea of inserting an extra level of indirection, no matter how powerful, is much murkier. There's also the huge change in semantics, as you point out; currently, from foo import bar has the same effect (on bar anyway) as import foo bar = foo.bar # i.e. copying an object reference del foo while under your proposal it would be more akin to changing all references to bar to become references to foo.bar. Of course that's what the moral equivalent of "from ... import ..." does in most other languages anyway, so we might consider this for Python 3000; however it would break a considerable amount of old code, I think. (Not to mention brain and book breakage. :-) --Guido van Rossum (home page: http://www.python.org/~guido/) From guido@CNRI.Reston.VA.US Thu Jan 20 16:01:38 2000 From: guido@CNRI.Reston.VA.US (Guido van Rossum) Date: Thu, 20 Jan 2000 11:01:38 -0500 Subject: [Python-Dev] Python 1.6 timing Message-ID: <200001201601.LAA21359@eric.cnri.reston.va.us> Andrew let me repost this mail of his to this list. It's worth a discussion here (if not in a larger forum). My responses are at the bottom. ------- Forwarded Message Date: Wed, 19 Jan 2000 20:17:55 -0500 From: "A.M. Kuchling" To: guido@python.org Subject: Python 1.6 timing I thought a bit more about the release schedule for 1.6, and like the idea of delaying it less and less. Another bad effect of delaying it is that not having Unicode in the core handicaps developing XML tools; we can continue working with wstrop, or integrate MAL's code into the XML-SIG's CVS tree, but it might mean abandoning the XML processing field to Perl & Tcl because the tools can't be made fully standard compliant in time. Options I can think of: 1) Delegating some control to a pumpkin holder [...]. 2) Releasing the Unicode+sre modules as separate add-ons to 1.5. (But would that impose annoying backward-compatibility constraints when they get integrated into 1.6?) 3) Add Unicode, sre, Distutils, plus other minor things and call it 1.5.5, meaning it's not as big a revision as a 1.6 release, but it's bigger than just another patchlevel of bugfixes. I don't remember what other features were planned for 1.6; was there anything major, if static typing is left for 2.0? - -- A.M. Kuchling http://starship.python.net/crew/amk/ Life's too short for chess. -- H.J. Byron ------- End of Forwarded Message There are several other things I can think of now that were planned for 1.6: revamped import, rich comparisons, revised coercions, parallel for loop (for i in L; j in M: ...), extended slicing for all sequences. I've also been thinking about making classes be types (not as huge a change as you think, if you don't allow subclassing built-in types), and adding a built-in array type suitable for use by NumPy. I've also received a conservative GC patch that seems to be fairly easy to apply and has some of Tim Peters' blessing. For 1.5.5 (what happened to 1.5.3 and 1.5.4?), we can have a more conservative agenda, as suggested by Andrew: Unicode and distutils are probably the most important things to integrate. (The import utilities are not ready for prime time in my opinion; there are too many issues.) Anybody care to be the pumpkin? That would cut the discussion short; otherwise the problem remains that I can't spend too much time on the next release unless I get funded for it; what little money I've received for CP4E I had better spend on getting some CP4E-related results ASAP, because the next installment of this funding is very much at stake... --Guido van Rossum (home page: http://www.python.org/~guido/) Life's better without braces. -- Bruce Eckel From bwarsaw@cnri.reston.va.us (Barry A. Warsaw) Thu Jan 20 16:21:30 2000 From: bwarsaw@cnri.reston.va.us (Barry A. Warsaw) (Barry A. Warsaw) Date: Thu, 20 Jan 2000 11:21:30 -0500 (EST) Subject: [Python-Dev] Python 1.6 timing References: <200001201601.LAA21359@eric.cnri.reston.va.us> Message-ID: <14471.13834.480356.541389@anthem.cnri.reston.va.us> >>>>> "Guido" == Guido van Rossum writes: Guido> There are several other things I can think of now that were Guido> planned for 1.6: revamped import, rich comparisons, revised Guido> coercions, parallel for loop (for i in L; j in M: ...), Guido> extended slicing for all sequences. I've also been Guido> thinking about making classes be types (not as huge a Guido> change as you think, if you don't allow subclassing Guido> built-in types), and adding a built-in array type suitable Guido> for use by NumPy. I've also received a conservative GC Guido> patch that seems to be fairly easy to apply and has some of Guido> Tim Peters' blessing. All very cool things that could easily wait until 1.7. After all, what's in a number? If, as Andrew puts forth, getting a stable Python release with Unicode is very important for Python's future positioning, then I say let's go with his more modest list, mainly Unicode, sre, and Distutils. We've already got string meths, tons of library improvements, and sundry other things. That's a good enough laundry list for the next release. From a political standpoint, I'd call the next release 1.6 and not bother with another installment in 1.5.x series. And I agree with Andrew, we should fast track that release as much as possible. I'm not sure what the state of the Unicode patches, sre, or Distutils current is, although I haven't seen any of that stuff checked into the tree. My free-time plate is pretty full with JPython and Mailman, but I'm willing to help where possible. -Barry From jim@digicool.com Thu Jan 20 16:21:33 2000 From: jim@digicool.com (Jim Fulton) Date: Thu, 20 Jan 2000 11:21:33 -0500 Subject: Version numbering (was Re: [Python-Dev] Python 1.6 timing) References: <200001201601.LAA21359@eric.cnri.reston.va.us> Message-ID: <3887360D.C29A9836@digicool.com> Guido van Rossum wrote: > > Andrew let me repost this mail of his to this list. It's worth a > discussion here (if not in a larger forum). My responses are at the > bottom. > (snip) > > There are several other things I can think of now that were planned > for 1.6: revamped import, rich comparisons, revised coercions, > parallel for loop (for i in L; j in M: ...), extended slicing for all > sequences. I've also been thinking about making classes be types (not > as huge a change as you think, if you don't allow subclassing built-in > types), and adding a built-in array type suitable for use by NumPy. > I've also received a conservative GC patch that seems to be fairly > easy to apply and has some of Tim Peters' blessing. > > For 1.5.5 (what happened to 1.5.3 and 1.5.4?), we can have a more > conservative agenda, as suggested by Andrew: Unicode and distutils are > probably the most important things to integrate. (The import > utilities are not ready for prime time in my opinion; there are too > many issues.) (snip) What is the basis of the Python numbering scheme? I thought that there was a notion that: - The first part changed with huge, possibly backward incompatible, changes, - The second part was for new functionality - The third part was for bug fixes. I thought I saw this scheme referenced somewhere and possibly even attributed to Guido. (?) I think that this is a better scheme that what I've seen with the 1.5 releases. Jim -- Jim Fulton mailto:jim@digicool.com Technical Director (888) 344-4332 Python Powered! Digital Creations http://www.digicool.com http://www.python.org Under US Code Title 47, Sec.227(b)(1)(C), Sec.227(a)(2)(B) This email address may not be added to any commercial mail list with out my permission. Violation of my privacy with advertising or SPAM will result in a suit for a MINIMUM of $500 damages/incident, $1500 for repeats. From petrilli@amber.org Thu Jan 20 16:33:52 2000 From: petrilli@amber.org (Christopher Petrilli) Date: Thu, 20 Jan 2000 11:33:52 -0500 Subject: [Python-Dev] Python 1.6 timing In-Reply-To: <14471.13834.480356.541389@anthem.cnri.reston.va.us>; from bwarsaw@cnri.reston.va.us on Thu, Jan 20, 2000 at 11:21:30AM -0500 References: <200001201601.LAA21359@eric.cnri.reston.va.us> <14471.13834.480356.541389@anthem.cnri.reston.va.us> Message-ID: <20000120113352.A23763@trump.amber.org> Barry A. Warsaw [bwarsaw@cnri.reston.va.us] wrote: > All very cool things that could easily wait until 1.7. After all, > what's in a number? If, as Andrew puts forth, getting a stable Python > release with Unicode is very important for Python's future > positioning, then I say let's go with his more modest list, mainly > Unicode, sre, and Distutils. We've already got string meths, tons of > library improvements, and sundry other things. That's a good enough > laundry list for the next release. Heck, Python is infinately more conservative in its numbering than a lot of projects. All that was mentioned would normally be enough to call it 2.0 easily. :-) Modesty can be counter productive in PR business...also there is the issue of having two copies of 1.5.x installed at the same time, which with Unicode could be a manjor consideraton for some of us. For me, numbering has always been (and I try and keep it this way with Zope): X.Y.Z X = structural changes, backward incompaibility Y = new features Z = bug fixes only Chris -- | Christopher Petrilli | petrilli@amber.org From bwarsaw@cnri.reston.va.us (Barry A. Warsaw) Thu Jan 20 16:30:32 2000 From: bwarsaw@cnri.reston.va.us (Barry A. Warsaw) (Barry A. Warsaw) Date: Thu, 20 Jan 2000 11:30:32 -0500 (EST) Subject: [Python-Dev] Python 1.6 timing References: <200001201601.LAA21359@eric.cnri.reston.va.us> <14471.13834.480356.541389@anthem.cnri.reston.va.us> <20000120113352.A23763@trump.amber.org> Message-ID: <14471.14376.9881.702264@anthem.cnri.reston.va.us> >>>>> "CP" == Christopher Petrilli writes: CP> For me, numbering has always been (and I try and keep it this CP> way with Zope): CP> X.Y.Z | X = structural changes, backward incompaibility | Y = new features | Z = bug fixes only I agree. -Barry From petrilli@amber.org Thu Jan 20 16:41:24 2000 From: petrilli@amber.org (Christopher Petrilli) Date: Thu, 20 Jan 2000 11:41:24 -0500 Subject: [Python-Dev] SOAP In-Reply-To: <006901bf631d$449eea50$f29b12c2@secret.pythonware.com>; from fredrik@pythonware.com on Thu, Jan 20, 2000 at 09:06:32AM +0100 References: <000101bf62ce$5e509e70$c355cfc0@ski.org> <006901bf631d$449eea50$f29b12c2@secret.pythonware.com> Message-ID: <20000120114124.B23763@trump.amber.org> Fredrik Lundh [fredrik@pythonware.com] wrote: > David Ascher wrote: > > Who if anyone is working on SOAP clients and servers for Python? > > we are (or rather, we will). hope to have code > available during (late) Q1. > > For what it's worth, this is also Zope's strategy. We are commited to having full SOAP integration in the system soon (when soon is, is another queston for the marketing department). :-) I am pretty sure that it will be a bi-directional integration. Chris -- | Christopher Petrilli | petrilli@amber.org From akuchlin@mems-exchange.org Thu Jan 20 16:38:53 2000 From: akuchlin@mems-exchange.org (Andrew M. Kuchling) Date: Thu, 20 Jan 2000 11:38:53 -0500 (EST) Subject: [Python-Dev] Python 1.6 timing In-Reply-To: <14471.13834.480356.541389@anthem.cnri.reston.va.us> References: <200001201601.LAA21359@eric.cnri.reston.va.us> <14471.13834.480356.541389@anthem.cnri.reston.va.us> Message-ID: <14471.14877.434886.471929@amarok.cnri.reston.va.us> Barry A. Warsaw writes: > Guido> There are several other things I can think of now that were > Guido> planned for 1.6: revamped import, rich comparisons, revised > Guido> coercions, parallel for loop (for i in L; j in M: ...), > Guido> extended slicing for all sequences. I'm not clear on the status of these various things; how many of these changes are deep ones that need lots of design, or affect massive amounts of the code base? For example, revamped import is a tricky design problem (as we've seen on this list). Is the spec for rich comparisons clearly defined at this point? Something like the parallel for loop seems like a parser modification combined with a code-generator modification, with no subtle implications for the rest of the implementation, and so that seems a simple matter of programming -- a week or so of effort. (Maybe I've missed something?) > Guido> I've also been > Guido> thinking about making classes be types (not as huge a > Guido> change as you think, if you don't allow subclassing > Guido> built-in types), and adding a built-in array type suitable > Guido> for use by NumPy. I've also received a conservative GC > Guido> patch that seems to be fairly easy to apply and has some of > Guido> Tim Peters' blessing. Similarly, does the conservative GC patch splatter changes all over the place, or is it very localized? Is adding the NumPy array type straightforward? Remember, there would presumably be a couple of 1.6 alphas and betas to shake out bugs. >From a political standpoint, I'd call the next release 1.6 and not >bother with another installment in 1.5.x series. And I agree with Fair enough; forget about the 1.5.5 suggestion, and call it as 1.6. >tree. My free-time plate is pretty full with JPython and Mailman, but >I'm willing to help where possible. Ditto. -- A.M. Kuchling http://starship.python.net/crew/amk/ One trouble with being efficient is that it makes everybody hate you so. -- Bob Edwards, the Calgary Eyeopener, March 18, 1916 From jim@digicool.com Thu Jan 20 16:48:18 2000 From: jim@digicool.com (Jim Fulton) Date: Thu, 20 Jan 2000 11:48:18 -0500 Subject: Python 2 namespace change? (was Re: [Python-Dev] Changing existing class instances) References: <200001200419.XAA01969@mira.erols.com> <38871665.C3B6FFEE@digicool.com> <38871CE5.53FB9D68@digicool.com> <200001201545.KAA21304@eric.cnri.reston.va.us> Message-ID: <38873C52.29FEAC6D@digicool.com> Guido van Rossum wrote: > > > I've suggested this to Guido in the past. His > > reasonable response is that this would be too big a > > change for Python 1. Maybe this is something to consider > > for Python 2? > > Note: from now on the new name for Python 2 is Python 3000. :-) I like it. > > The basic idea (borrowed from Smalltalk) is to have a kind > > of dictionary that is a collection of "association" > > objects. An association object is simply a pairing of a > > name with a value. Association objects can be shared among > > multiple namespaces. > > I've never liked this very much, mostly because it breaks simplicity: > the idea that a namespace is a mapping from names to values > (e.g. {"limit": 100, "doit": , ...}) is beautifully > simple, while the idea of inserting an extra level of indirection, no > matter how powerful, is much murkier. How so? It doesn't change the mapping semantics. > There's also the huge change in semantics, as you point out; > currently, > > from foo import bar > > has the same effect (on bar anyway) as > > import foo > bar = foo.bar # i.e. copying an object reference > del foo > > while under your proposal it would be more akin to changing all > references to bar to become references to foo.bar. > > Of course that's what the moral equivalent of "from ... import ..." > does in most other languages anyway, so we might consider this for > Python 3000; Cool. Again, it would also make function global variable access faster and cleaner in some ways. > however it would break a considerable amount of old code, > I think. Really? I wonder. I bet it would break alot less old code that other recent changes. > (Not to mention brain It makes my brain feel much better. :) > and book breakage. :-) Hey, all of the books will have to be rewritten for Python 3000. Jim -- Jim Fulton mailto:jim@digicool.com Technical Director (888) 344-4332 Python Powered! Digital Creations http://www.digicool.com http://www.python.org Under US Code Title 47, Sec.227(b)(1)(C), Sec.227(a)(2)(B) This email address may not be added to any commercial mail list with out my permission. Violation of my privacy with advertising or SPAM will result in a suit for a MINIMUM of $500 damages/incident, $1500 for repeats. From gstein@lyra.org Thu Jan 20 17:22:40 2000 From: gstein@lyra.org (Greg Stein) Date: Thu, 20 Jan 2000 09:22:40 -0800 (PST) Subject: [Python-Dev] Python 1.6 timing In-Reply-To: <200001201601.LAA21359@eric.cnri.reston.va.us> Message-ID: On Thu, 20 Jan 2000, Guido van Rossum wrote: >... > Date: Wed, 19 Jan 2000 20:17:55 -0500 > From: "A.M. Kuchling" > To: guido@python.org > Subject: Python 1.6 timing > > I thought a bit more about the release schedule for 1.6, and like the > idea of delaying it less and less. Another bad effect of delaying it > is that not having Unicode in the core handicaps developing XML tools; > we can continue working with wstrop, or integrate MAL's code into the > XML-SIG's CVS tree, but it might mean abandoning the XML processing > field to Perl & Tcl because the tools can't be made fully standard > compliant in time. I agree with Andrew's basic premise. > Options I can think of: > > 1) Delegating some control to a pumpkin holder [...]. Seems fine. > 2) Releasing the Unicode+sre modules as separate add-ons to > 1.5. (But would that impose annoying > backward-compatibility constraints when they get integrated > into 1.6?) Icky. :-) > 3) Add Unicode, sre, Distutils, plus other minor things and > call it 1.5.5, meaning it's not as big a revision as a 1.6 > release, but it's bigger than just another patchlevel of > bugfixes. I don't remember what other features were > planned for 1.6; was there anything major, if static typing > is left for 2.0? Call it 1.6, per the rest of the thread. >... > For 1.5.5 (what happened to 1.5.3 and 1.5.4?), we can have a more > conservative agenda, as suggested by Andrew: Unicode and distutils are > probably the most important things to integrate. Unicode: definitely. distutils seems pretty early, but I bet that some key concepts could be added to 1.6, to make the transition and continued development easier. Note that if an announcement were made to the effect of "feature freeze on February 15; only bug fixes afterwards," that you would get a lot of people scrambling to submit their pet features. This would be a good way to light some fires, to see what kinds of things get completed (i.e. we may think some things aren't ready or are too far out, put that deadline in and those positions could change...) > (The import > utilities are not ready for prime time in my opinion; there are too > many issues.) I'm waiting for that review :-) If you raise issues, then I can knock them down. I don't see all that many at the moment. But I'm biased :-) > Anybody care to be the pumpkin? That would cut the discussion short; > otherwise the problem remains that I can't spend too much time on the > next release unless I get funded for it; what little money I've > received for CP4E I had better spend on getting some CP4E-related > results ASAP, because the next installment of this funding is very > much at stake... I would volunteer for the pumpkin... around April-ish. My plate is rather full with completing mod_dav and then integrating that into Apache 2.0. Once the Apache integration begins, then I'd have some more free time. But this begs the question of: what does the pumpkin-holder mean in the *Python* world? If it is collating fixes, producing snapshots, etc, then I'm comfy with it. If it also contains responsibility for specific kinds of work, then Fred would probably veto me :-), as I've got an outstanding doc that I owe him (for about six months now... sigh; maybe I'll bribe MAL to write it; he knows the interface :-)). But stll: what's it mean? How does the pumpkin reduce the Guido-load, yet still enable the Guido-control? [ I just had a talk about this with the guys at Inprise, re: InterBase, mentioning that the Dictator model works well for Python, but doesn't necessarily work well for new projects or commercially-started projects due to control/prejudice issues. Python people like it because of the resulting simplicity and cleanliness; I doubt we want a pumpkin approach that would allow that to go away! ] Cheers, -g -- Greg Stein, http://www.lyra.org/ From guido@CNRI.Reston.VA.US Thu Jan 20 17:20:33 2000 From: guido@CNRI.Reston.VA.US (Guido van Rossum) Date: Thu, 20 Jan 2000 12:20:33 -0500 Subject: Python 2 namespace change? (was Re: [Python-Dev] Changing existing class instances) In-Reply-To: Your message of "Thu, 20 Jan 2000 11:48:18 EST." <38873C52.29FEAC6D@digicool.com> References: <200001200419.XAA01969@mira.erols.com> <38871665.C3B6FFEE@digicool.com> <38871CE5.53FB9D68@digicool.com> <200001201545.KAA21304@eric.cnri.reston.va.us> <38873C52.29FEAC6D@digicool.com> Message-ID: <200001201720.MAA21534@eric.cnri.reston.va.us> [me] > > I've never liked this very much, mostly because it breaks simplicity: > > the idea that a namespace is a mapping from names to values > > (e.g. {"limit": 100, "doit": , ...}) is beautifully > > simple, while the idea of inserting an extra level of indirection, no > > matter how powerful, is much murkier. [Jim F] > How so? It doesn't change the mapping semantics. My assumption is that in your version, the dictionary would contain special objects which then would contain the referenced objects. E.g. {"limit": , "doit": >}. Thus, d["limit"] would be that object, while previously it would return 100. > Again, it would also make function global variable access > faster and cleaner in some ways. But I have other plans for that (if the optional static typing stuff ever gets implemented). > > however it would break a considerable amount of old code, > > I think. > > Really? I wonder. I bet it would break alot less old > code that other recent changes. Oh? Name some changes that broke a lot of code? --Guido van Rossum (home page: http://www.python.org/~guido/) From jeremy@cnri.reston.va.us Thu Jan 20 17:36:32 2000 From: jeremy@cnri.reston.va.us (Jeremy Hylton) Date: Thu, 20 Jan 2000 12:36:32 -0500 (EST) Subject: [Python-Dev] Python 1.6 timing In-Reply-To: <14471.13834.480356.541389@anthem.cnri.reston.va.us> References: <200001201601.LAA21359@eric.cnri.reston.va.us> <14471.13834.480356.541389@anthem.cnri.reston.va.us> Message-ID: <14471.18336.257653.730100@bitdiddle.cnri.reston.va.us> >>>>> "BAW" == Barry A Warsaw writes: >>>>> "Guido" == Guido van Rossum writes: Guido> There are several other things I can think of now that were Guido> planned for 1.6: revamped import, rich comparisons, revised Guido> coercions, parallel for loop (for i in L; j in M: ...), Guido> extended slicing for all sequences. I've also been thinking Guido> about making classes be types (not as huge a change as you Guido> think, if you don't allow subclassing built-in types), and Guido> adding a built-in array type suitable for use by NumPy. I've Guido> also received a conservative GC patch that seems to be fairly Guido> easy to apply and has some of Tim Peters' blessing. BAW> All very cool things that could easily wait until 1.7. After BAW> all, what's in a number? If, as Andrew puts forth, getting a BAW> stable Python release with Unicode is very important for BAW> Python's future positioning, then I say let's go with his more BAW> modest list, mainly Unicode, sre, and Distutils. We've already BAW> got string meths, tons of library improvements, and sundry BAW> other things. That's a good enough laundry list for the next BAW> release. We've had this conversation before, so it'll comes as no surprise that I agree with you. Question: If we go with the feature set you've described, when will those features be ready? What kind of schedule could we set for releasing the first alpha? Jeremy From guido@CNRI.Reston.VA.US Thu Jan 20 17:40:51 2000 From: guido@CNRI.Reston.VA.US (Guido van Rossum) Date: Thu, 20 Jan 2000 12:40:51 -0500 Subject: [Python-Dev] Python 1.6 timing In-Reply-To: Your message of "Thu, 20 Jan 2000 09:22:40 PST." References: Message-ID: <200001201740.MAA21608@eric.cnri.reston.va.us> > Call it 1.6, per the rest of the thread. OK. I expect I'll get some complaints from some people who asked when 1.6 would be out (I've generally told them end of 2000); but it sounds like a 1.7 would be necessary to fulfill the other promises, so it shouldn't really matter -- it's all a case of relabeling for PR purposes. > Unicode: definitely. distutils seems pretty early, but I bet that some key > concepts could be added to 1.6, to make the transition and continued > development easier. The point of adding distutils is that it will allow distribution of packages without including distutils with each distribution. Since distutils was about 200K itself last time I looked, this is important. I don't believe it would be good to have to say "My FooBar package is really easy to install. All you need to do is download and install distutils, (which by the way is a 200K package that you have to manually install), and then run "python setup.py" in the FooBar root directory..." This would be enough for the average person to run away screaming. I think I saw a distribution by AMK that had a setup.py that tried to use distutils but had a crude fallback if distutils didn't exist; however that defeats much of the purpose since the package author has to figure out how to do the fallback. Large distributions (e.g. NumPy) can afford to squeeze distutils in a corner of their distribution, but for the average package it wouldn't be of much use. In other words, I'm for putting distutils in the next release, essentially feature-freezing it. Greg Ward, what do you think of that? > Note that if an announcement were made to the effect of "feature freeze on > February 15; only bug fixes afterwards," that you would get a lot of > people scrambling to submit their pet features. This would be a good way > to light some fires, to see what kinds of things get completed (i.e. we > may think some things aren't ready or are too far out, put that deadline > in and those positions could change...) I bet you we couldn't complete the import hooks by that date; I consider imputil.py as a nice prototype, but the integration with the C code is still missing. Also the 50% slowdown is a problem I worry about for inclusion a production version. (Plus breakage of everybody else's code who uses or hacks __import__; e.g. have you tested it with rexec?) > > (The import > > utilities are not ready for prime time in my opinion; there are too > > many issues.) > > I'm waiting for that review :-) It was kept up by the need to get the types documents out. > If you raise issues, then I can knock them down. I don't see all that many > at the moment. But I'm biased :-) > > > Anybody care to be the pumpkin? That would cut the discussion short; > > otherwise the problem remains that I can't spend too much time on the > > next release unless I get funded for it; what little money I've > > received for CP4E I had better spend on getting some CP4E-related > > results ASAP, because the next installment of this funding is very > > much at stake... > > I would volunteer for the pumpkin... around April-ish. My plate is rather > full with completing mod_dav and then integrating that into Apache 2.0. > Once the Apache integration begins, then I'd have some more free time. > > But this begs the question of: what does the pumpkin-holder mean in the > *Python* world? > > If it is collating fixes, producing snapshots, etc, then I'm comfy with > it. If it also contains responsibility for specific kinds of work, then > Fred would probably veto me :-), as I've got an outstanding doc that I owe > him (for about six months now... sigh; maybe I'll bribe MAL to write it; > he knows the interface :-)). > > But stll: what's it mean? How does the pumpkin reduce the Guido-load, yet > still enable the Guido-control? Good questions. I have to say that I feel reluctant to release any kind of control -- yet at the same time I desperately need help getting trivial stuff checked in. One of the most important time-consuming tasks is quality control: collecting fixes is all well and good, but I routinely reject fixes that superficially look fine, because they are subtly broken, or interfere with other plans, or just because the code looks poorly written. I also spend a lot of testing before I check things in; running the standard test suite is a good safeguard against general breakage, but you really have to play with the code affected by the change before you can know that it works as advertised. My work attitude here means that what gets checked in is generally rock solid, and that helps Python's reputation; but it is very costly... > [ I just had a talk about this with the guys at Inprise, re: InterBase, > mentioning that the Dictator model works well for Python, but doesn't > necessarily work well for new projects or commercially-started projects > due to control/prejudice issues. Python people like it because of the > resulting simplicity and cleanliness; I doubt we want a pumpkin approach > that would allow that to go away! ] Agreed, of course. --Guido van Rossum (home page: http://www.python.org/~guido/) From da@ski.org Thu Jan 20 17:57:51 2000 From: da@ski.org (David Ascher) Date: Thu, 20 Jan 2000 09:57:51 -0800 Subject: [Python-Dev] Python 1.6 timing In-Reply-To: <14471.13834.480356.541389@anthem.cnri.reston.va.us> Message-ID: <000701bf636f$de37c5e0$c355cfc0@ski.org> [I just got GvR's post on the topic, but I'll send this anyway] BAW: > All very cool things that could easily wait until 1.7. After all, > what's in a number? Guido has promised some of those features as being in 1.6 at conferences in the past, but I agree that string methods for example are a more major change than I'd expect to see in a 0.0.3-delta version change. Maybe with a deadline (as Greg suggests) we can integrate some of the pending patches (I agree with Greg that I at least would have found the time for a revised patch for rich comparisons if I'd had a deadline -- call me human =). Coercion and extended slicing also seem like relatively minor changes, compared with changing everything to be a class or adding GC! Regardless, just like Greg, I'd like to know what a pumpkin-holder would mean in the Python world. I propose that it be called the Oracle instead. As in, whoever is Oracle would get some training with Tim Peters and learn how to channel G__do. As a Python user, I'd be most comfortable with such a change if the Oracle just took over the technical stuff (reviewing patches, CVS checkins, running tests, corralling help for doc & code, maintaining release notes, building installers, etc.), but that the important decisions (e.g. whether to add a feature to the core language) would be checked with G__do first. We could call the position "Administrative Assistant", but somehow that doesn't have the prestige. A progressive schedule where Guido watches over the Oracle periodically would probably help build trust in the new mechanism. The Oracle would be expected to ask Guido for his opinion with everything at the beginning, and as a trust builds between Guido and the Oracle and the community and the mechanism, progressively less. --david ascher From gstein@lyra.org Thu Jan 20 18:30:52 2000 From: gstein@lyra.org (Greg Stein) Date: Thu, 20 Jan 2000 10:30:52 -0800 (PST) Subject: [Python-Dev] Python 1.6 timing In-Reply-To: <200001201740.MAA21608@eric.cnri.reston.va.us> Message-ID: On Thu, 20 Jan 2000, Guido van Rossum wrote: >... > In other words, I'm for putting distutils in the next release, > essentially feature-freezing it. Greg Ward, what do you think of > that? Oh, don't get me wrong. I'd like to see it in there for at least all the reasons you cite. But it seems (to me) that it is still pretty alpha. But hey: I'm shooting from the peanut gallery; we need GregW's comments. > > Note that if an announcement were made to the effect of "feature freeze on > > February 15; only bug fixes afterwards," that you would get a lot of > > people scrambling to submit their pet features. This would be a good way > > to light some fires, to see what kinds of things get completed (i.e. we > > may think some things aren't ready or are too far out, put that deadline > > in and those positions could change...) > > I bet you we couldn't complete the import hooks by that date; I > consider imputil.py as a nice prototype, but the integration with the > C code is still missing. Also the 50% slowdown is a problem I worry > about for inclusion a production version. (Plus breakage of everybody > else's code who uses or hacks __import__; e.g. have you tested it with > rexec?) hehe... if the static typing is to be deferred, then I'll take that bet! [discussion omitted; too tangental to this thread right now...] >... > Good questions. I have to say that I feel reluctant to release any > kind of control -- yet at the same time I desperately need help > getting trivial stuff checked in. Reading your comments below, we may be able to help. First, presume that at least one (best would be several) people man the "front lines" for any/all patches and bug reports. The front line can deal with the bug reports, mostly by responding with "go away; enter it into Jitterbug." Patches fall under several catagories, detailed below: > One of the most important > time-consuming tasks is quality control: collecting fixes is all well > and good, but I routinely reject fixes that superficially look fine, Conversely, your "lieutenants" (LTs) would filter all ugly-looking patches. > because they are subtly broken, If the LTs didn't catch these, then you could catch them from the checkin diff email. However, the LTs would reduce the number of broken ones that you would review. > or interfere with other plans, The LTs may know of this, but if not: you'd catch it at checkin time. The patches would then be backed out, altered, or whatever. > or just > because the code looks poorly written. The LTs would definitely catch this. If the style was *still* not up to snuff, I'd have to believe it would only be in minor ways that you could then touch up at your leisure. > I also spend a lot of testing > before I check things in; Done by the LTs. > running the standard test suite is a good > safeguard against general breakage, Ditto. > but you really have to play with > the code affected by the change before you can know that it works as > advertised. Ditto. > My work attitude here means that what gets checked in is > generally rock solid, and that helps Python's reputation; but it is > very costly... Based on my responses, I would venture to state that a group of LTs would manage to keep the Python core rock solid, except for: 1) subtle breakages that require your broader knowledge of Python 2) changes that "go against the plan" (and the LTs were ignorant of it) 3) minor format issues You would still review checkins, but the number of reviews would drop since the (obvious) crap has been eliminated. #1 is based on your *broad* knowledge of Python; I presume the LTs would be your match on various subsets of Python. By keeping the LTs well-informed, #2 could be nearly eliminated. #3 isn't that big of a deal, as I think your desired style is relatively well-known and the LTs would simply endeavor to match existing style. You could avoid a lot of testing; you would probably be inclined to do testing of items that you find dubious, but still this would be a reduction. ===== That may be an answer to the checkin problem. How about actual snapshots, alphas, betas, releases, and accompanying notes/news/readme files? I presume your LTs could run the alpha and beta aspects, but you would still issue final releases. Does your mail volume need to be reduced? (I think this has been asked before) Specifically, would patches@python.org (and similar targets) need to be established? (I would think so, as a matter of course, with the expectation that some patches would still end up with you and need to be bounced to patches@) Cheers, -g -- Greg Stein, http://www.lyra.org/ From klm@digicool.com Thu Jan 20 18:31:52 2000 From: klm@digicool.com (Ken Manheimer) Date: Thu, 20 Jan 2000 13:31:52 -0500 (EST) Subject: [Python-Dev] Python 1.6 timing In-Reply-To: <000701bf636f$de37c5e0$c355cfc0@ski.org> Message-ID: I must have missed the historic landmark where "pumpkin" was coined, but i think i get the gist. How about "Python Marshall" or "Python Activity Marshall" (a la the PS_A_)? Ken David Ascher wrote: > [...] > Regardless, just like Greg, I'd like to know what a pumpkin-holder would > mean in the Python world. > > I propose that it be called the Oracle instead. As in, whoever is Oracle > would get some training with Tim Peters and learn how to channel G__do. As > a Python user, I'd be most comfortable with such a change if the Oracle just > took over the technical stuff (reviewing patches, CVS checkins, running > tests, corralling help for doc & code, maintaining release notes, building > installers, etc.), but that the important decisions (e.g. whether to add a > feature to the core language) would be checked with G__do first. We could > call the position "Administrative Assistant", but somehow that doesn't have > the prestige. > > A progressive schedule where Guido watches over the Oracle periodically > would probably help build trust in the new mechanism. The Oracle would be > expected to ask Guido for his opinion with everything at the beginning, and > as a trust builds between Guido and the Oracle and the community and the > mechanism, progressively less. From gstein@lyra.org Thu Jan 20 18:42:43 2000 From: gstein@lyra.org (Greg Stein) Date: Thu, 20 Jan 2000 10:42:43 -0800 (PST) Subject: [Python-Dev] Python 1.6 timing In-Reply-To: Message-ID: On Thu, 20 Jan 2000, Ken Manheimer wrote: > I must have missed the historic landmark where "pumpkin" was coined, but i > think i get the gist. How about "Python Marshall" or "Python Activity > Marshall" (a la the PS_A_)? The "pumpkin" term comes from Perl-land... I'm not super clear on the pumpkin-holders's entire job, but I think it is basically the guy who sees that the version for which he "holds the pumpkin" is completed and shipped. Not necessarily by himself :-), but as the overseer (or "release manager" if you will). The current Perl pumpkin-holder is a guy at ActiveState. I think it changes for each version. Cheers, -g -- Greg Stein, http://www.lyra.org/ From gvwilson@nevex.com Thu Jan 20 18:51:17 2000 From: gvwilson@nevex.com (gvwilson@nevex.com) Date: Thu, 20 Jan 2000 13:51:17 -0500 (EST) Subject: [Python-Dev] Python 1.6 timing (fwd) Message-ID: Guido> There are several other things I can think of now that were Guido> planned for 1.6: revamped import, rich comparisons, revised Guido> coercions, parallel for loop (for i in L; j in M: ...), Guido> extended slicing for all sequences. I've also been thinking Guido> about making classes be types (not as huge a change as you Guido> think, if you don't allow subclassing built-in types), and Guido> adding a built-in array type suitable for use by NumPy. I've Guido> also received a conservative GC patch that seems to be fairly Guido> easy to apply and has some of Tim Peters' blessing. BAW> All very cool things that could easily wait until 1.7. After BAW> all, what's in a number? GVW writes: I agree on all counts except garbage collection --- I'm half-way through the second day of the Python class I teach at Los Alamos (the people who are funding the Python tool design competition), and it's come up a couple of times. People want to be able to prototype meshes, throw callbacks around without worrying about circularity, and some other things that I don't really understand yet. There's also a couple of smart guys in the class who are wondering about CPython vs. JPython ("So this'll be safe in one version of the language, but not in the other?"), and about marketing ("Help me win a feature comparison against Java in my group..."). There's also been questions about tighter integration of NumPy (e.g. overloading operators rather than calling 'greater()' to do comparison), but I think that's a separate discussion... My $0.02, Greg From tismer@tismer.com Thu Jan 20 19:11:13 2000 From: tismer@tismer.com (Christian Tismer) Date: Thu, 20 Jan 2000 20:11:13 +0100 Subject: [Python-Dev] Python 1.6 timing (fwd) References: Message-ID: <38875DD1.B6596@tismer.com> [garbage collection] gvwilson@nevex.com wrote: > I agree on all counts except garbage collection --- I'm half-way through > the second day of the Python class I teach at Los Alamos (the people who > are funding the Python tool design competition), and it's come up a couple > of times. People want to be able to prototype meshes, throw callbacks > around without worrying about circularity, and some other things that I > don't really understand yet. There's also a couple of smart guys in the > class who are wondering about CPython vs. JPython ("So this'll be safe in > one version of the language, but not in the other?"), and about marketing > ("Help me win a feature comparison against Java in my group..."). Guido once posted some proposal of a hybrid system *with* refcounts and some additional garbage collection scheme to match circular things. I believe this is a much better approach than what Java and therefor also JPython does at the moment. Although people might argue differently, I'm pretty sure that reference counting is the stronger concept. By reference counting, the idea of object ownership can be made explicit. This plays a central role in the Corba specification for instance, and I made the same observation when implementing continuations for Stackless Python. Refcounts are no burden but a virtue. Even better: Refcounting can lead to many new optimizations if we pay the cost to make INCREF/DECREF into methods. It has its cost (about 10 percent less pystones), but massive long-term benefits. I'm currently in charge to develop a custom version of Python's builtin types where this concept is used. Everything is refcounted, but without storing the refcounts in the objects. This is possible (proven) and will be shown in my next paper. Conclusion: I vote for a kind of GC that does just what refcounts cannot do, but please keep with the refcounts. cheers - chris -- Christian Tismer :^) Virtual Photonics GmbH : Have a break! Take a ride on Python's Carnotstr. 6 : *Starship* http://starship.python.net 10587 Berlin : PGP key -> http://wwwkeys.pgp.net PGP Fingerprint E182 71C7 1A9D 66E9 9D15 D3CC D4D7 93E2 1FAE F6DF we're tired of banana software - shipped green, ripens at home From tim_one@email.msn.com Thu Jan 20 19:47:01 2000 From: tim_one@email.msn.com (Tim Peters) Date: Thu, 20 Jan 2000 14:47:01 -0500 Subject: [Python-Dev] Changing existing class instances In-Reply-To: <200001201520.KAA21137@eric.cnri.reston.va.us> Message-ID: <000301bf637f$1f1c2d80$b72d153f@tim> [Tim worries about stomping on unintended classes/defs] [Guido] > Agreed that that would be bad. But I wouldn't search outer > scopes -- I would only look for a class/def that I was about > to stomp on. Maybe I just don't grasp what that means, exactly. Fair enough, since I'm not expressing myself clearly either! Suppose someone does from Tkinter import * in my.py, and later in my.py just *happens* to define, at module level, class Misc: blah blah blah Now Misc was already in my.py's global namespace because Tkinter.py just happens to export a class of that name too (more by accident than design -- but accidents are what I'm most worried about here). At the time my.py defines Misc, does Misc count as a class we're "about to stomp on"? If so-- & I've assumed so --it would wreak havoc. But if not, I don't see how this case can be reliably distinguished "by magic" from the cases where update is desired (if people are doing dynamic updates to a long-running program, a new version of a class can come from anywhere, so nothing like original file name or line number can distinguish correctly either). >> Modules differ because their namespace "search path" >> consists solely of the more-global-than-global >> sys.modules. > "The search path doesn't enter into it." I agree, but am at a loss to describe what's happening in the case above using other terminology . In a sense, you need a system-wide "unique handle" to support bulletproof updating, and while sys.modules has supplied that all along for module objects (in the form of the module name), I don't believe there's anything analogous to key off of for function or class objects. >> [suggesting] >> new.update(class_or_def_old, class_or_def_new) > Only a slight semantics change (which my full proposal > would require too): function objects would become mutable > -- their func_code, func_defaults, func_doc and func_globals > fields (and, why not, func_name too) should be changeable. Of course I meant "no new semantics" in the sense of "won't cause current exception-free code to alter behavior in any way". > If you make all these assignable, it doesn't even have to > be a privileged function. I'm all for that! > [sketching a Python approach to "updating import/reload" > building on the hypothetical new.update] > That's certainly a reasonable compromise. Note that the > update on a class should imply an update on its methods, > right? Hadn't considered that! Of course you're right. So make it a pair of nested loops . so-long-as-it-can-be-written-in-python-it's-easy-ly y'rs - tim From guido@CNRI.Reston.VA.US Thu Jan 20 20:02:20 2000 From: guido@CNRI.Reston.VA.US (Guido van Rossum) Date: Thu, 20 Jan 2000 15:02:20 -0500 Subject: [Python-Dev] Changing existing class instances In-Reply-To: Your message of "Thu, 20 Jan 2000 14:47:01 EST." <000301bf637f$1f1c2d80$b72d153f@tim> References: <000301bf637f$1f1c2d80$b72d153f@tim> Message-ID: <200001202002.PAA22435@eric.cnri.reston.va.us> > [Tim worries about stomping on unintended classes/defs] > > [Guido] > > Agreed that that would be bad. But I wouldn't search outer > > scopes -- I would only look for a class/def that I was about > > to stomp on. > > Maybe I just don't grasp what that means, exactly. Fair enough, since I'm > not expressing myself clearly either! > > Suppose someone does > > from Tkinter import * > > in my.py, and later in my.py just *happens* to define, at module level, > > class Misc: > blah blah blah > > Now Misc was already in my.py's global namespace because Tkinter.py just > happens to export a class of that name too (more by accident than design -- > but accidents are what I'm most worried about here). For a second I thought you got me there! > At the time my.py defines Misc, does Misc count as a class we're "about to > stomp on"? If so-- & I've assumed so --it would wreak havoc. > > But if not, I don't see how this case can be reliably distinguished "by > magic" from the cases where update is desired (if people are doing dynamic > updates to a long-running program, a new version of a class can come from > anywhere, so nothing like original file name or line number can distinguish > correctly either). Fortunately, there's magic available: recently, all classes have a __module__ attribute that is set to the full name of the module that defined it (its key in __sys__.modules). For functions, we would have to invent something similar. > >> Modules differ because their namespace "search path" > >> consists solely of the more-global-than-global > >> sys.modules. > > > "The search path doesn't enter into it." > > I agree, but am at a loss to describe what's happening in the case above > using other terminology . In a sense, you need a system-wide "unique > handle" to support bulletproof updating, and while sys.modules has supplied > that all along for module objects (in the form of the module name), I don't > believe there's anything analogous to key off of for function or class > objects. > > >> [suggesting] > >> new.update(class_or_def_old, class_or_def_new) > > > Only a slight semantics change (which my full proposal > > would require too): function objects would become mutable > > -- their func_code, func_defaults, func_doc and func_globals > > fields (and, why not, func_name too) should be changeable. > > Of course I meant "no new semantics" in the sense of "won't cause current > exception-free code to alter behavior in any way". > > > If you make all these assignable, it doesn't even have to > > be a privileged function. > > I'm all for that! > > > [sketching a Python approach to "updating import/reload" > > building on the hypothetical new.update] > > > That's certainly a reasonable compromise. Note that the > > update on a class should imply an update on its methods, > > right? > > Hadn't considered that! Of course you're right. So make it a pair of > nested loops . > > so-long-as-it-can-be-written-in-python-it's-easy-ly > y'rs - tim --Guido van Rossum (home page: http://www.python.org/~guido/) From guido@CNRI.Reston.VA.US Thu Jan 20 20:12:58 2000 From: guido@CNRI.Reston.VA.US (Guido van Rossum) Date: Thu, 20 Jan 2000 15:12:58 -0500 Subject: [Python-Dev] Python 1.6 timing (fwd) In-Reply-To: Your message of "Thu, 20 Jan 2000 20:11:13 +0100." <38875DD1.B6596@tismer.com> References: <38875DD1.B6596@tismer.com> Message-ID: <200001202012.PAA22501@eric.cnri.reston.va.us> > Conclusion: I vote for a kind of GC that does just what refcounts > cannot do, but please keep with the refcounts. The patch that I received and that has Tim's <0.5 blessing> does just that. I haven't had the time to understand why it doesn't have his <1.0 blessing>. --Guido van Rossum (home page: http://www.python.org/~guido/) From tim_one@email.msn.com Thu Jan 20 20:35:44 2000 From: tim_one@email.msn.com (Tim Peters) Date: Thu, 20 Jan 2000 15:35:44 -0500 Subject: [Python-Dev] Python 1.6 timing (fwd) In-Reply-To: <200001202012.PAA22501@eric.cnri.reston.va.us> Message-ID: <000901bf6385$eccfba20$b72d153f@tim> [Christian] > Conclusion: I vote for a kind of GC that does just > what refcounts cannot do, but please keep with the > refcounts. [Guido] > The patch that I received and that has Tim's <0.5 > blessing> does just that. I haven't had the time to > understand why it doesn't have his <1.0 blessing>. Primarily because it doesn't reclaim the most common cycles; e.g., cycles among class instances aren't touched. This seems easily repairable, but at an unknown cost (it needs to do the "reachability" transitive closure business from the set of all "suspicious" objects, and instances are never considered suspicious now; adding them will certainly cause a lot more pointer chasing). Apart from that, the code appears unreasonably expensive as written today, using e.g. splay trees instead of hash tables to keep track of objects. The author hasn't said anything more in a bit over two weeks, so I suspect he's off on other things now. The technical approach is sound, but even its inventor (Rafael Lins; Toby Kelsey may have reinvented it on his own, though) stresses that getting it to run fast is difficult. needs-work!-ly y'rs - tim, who hasn't the time to do it From tismer@tismer.com Thu Jan 20 20:35:27 2000 From: tismer@tismer.com (Christian Tismer) Date: Thu, 20 Jan 2000 21:35:27 +0100 Subject: [Python-Dev] Stackless Python 1.0 + Continuations 0.6 Message-ID: <3887718F.82E1B327@tismer.com> ANNOUNCING: Stackless Python 1.0 A Python Implementation That Does Not Use The C Stack * plus the real toy * Continuation Module 0.6 Continuations as First Class Objects What is it? A plugin-replacement for core Python. It should run any program which runs under Python 1.5.2 . But it does not need space on the C stack. Why did I write it? Stackless Python was never written before (afaik), since it was said to be impossible without major rewrites of core Python. I have proven the controverse: It is easy to write, just hard to think. About 3 times harder was finally the continuation module. The whole project took about 6 man months where 80 percent of the time was thinking and trying. The rest was coding and to become a reference counting champion :-) Recent changes: Version 1.0 has been optimized like hell and is now 3-5 percent faster than Standard Python. Continuation module is in version 0.6, very stable, and it allows to save a program's "future" at any time, in a portable way. Continuations are callable Python objects with a very small footprint. Who needs it? Since the continuations are done, this is no more only useful for C programmers who want to try certain new ideas. Everybody who is interested to develop his own generators, coroutines and tiny threads is invited to check it out. Status of the final 1.0: Pystone works correctly and is 5% faster than standard Python. Version 0.3 was 10 percent slower. Continuations work with PythonWin and Idle. The overall result is now better than expected, and I'm happy to call this *FINAL* (until the next version of course:) Downloadable files can be found at http://www.tismer.com/research/stackless/ Some older documentation: http://www.tismer.com/research/stackless/stackless.htm Some better documentation can be found in my IPC8 paper: http://www.tismer.com/research/stackless/spc_final.zip or be read directly as HTML http://www.tismer.com/research/stackless/spcpaper.htm Source code and a VC++6.0 build for Windows (340K): http://www.tismer.com/research/stackless/spc_win32.zip cheers - chris == Christian Tismer :^) Applied Biometrics GmbH : Have a break! Take a ride on Python's Kaiserin-Augusta-Allee 101 : *Starship* http://starship.python.net 10553 Berlin : PGP key -> http://wwwkeys.pgp.net PGP Fingerprint E182 71C7 1A9D 66E9 9D15 D3CC D4D7 93E2 1FAE F6DF we're tired of banana software - shipped green, ripens at home

Stackless Python 1.0 - a version of Python 1.5.2 that does not need space on the C stack. (20-Jan-00) From bwarsaw@cnri.reston.va.us (Barry A. Warsaw) Thu Jan 20 21:12:37 2000 From: bwarsaw@cnri.reston.va.us (Barry A. Warsaw) (Barry A. Warsaw) Date: Thu, 20 Jan 2000 16:12:37 -0500 (EST) Subject: [Python-Dev] Python 1.6 timing References: Message-ID: <14471.31301.504670.201702@anthem.cnri.reston.va.us> We'd have to rework the CVS arrangement in order to give non-CNRI employees write access to the tree. I think I know how I'd go about this, and it wouldn't be too hard, just a bit time-consuming. If that's the way we're going to go, I can start making plans. -Barry From guido@CNRI.Reston.VA.US Thu Jan 20 21:16:39 2000 From: guido@CNRI.Reston.VA.US (Guido van Rossum) Date: Thu, 20 Jan 2000 16:16:39 -0500 Subject: [Python-Dev] Python 1.6 timing In-Reply-To: Your message of "Thu, 20 Jan 2000 16:12:37 EST." <14471.31301.504670.201702@anthem.cnri.reston.va.us> References: <14471.31301.504670.201702@anthem.cnri.reston.va.us> Message-ID: <200001202116.QAA22943@eric.cnri.reston.va.us> [Barry] > We'd have to rework the CVS arrangement in order to give non-CNRI > employees write access to the tree. I think I know how I'd go about > this, and it wouldn't be too hard, just a bit time-consuming. If > that's the way we're going to go, I can start making plans. I think before you make such changes you'd have to talk to Bob (good luck). I don't mind applying patches and doing the checkins -- it's the decision-making that's time-consuming. --Guido van Rossum (home page: http://www.python.org/~guido/) From da@ski.org Thu Jan 20 21:28:24 2000 From: da@ski.org (David Ascher) Date: Thu, 20 Jan 2000 13:28:24 -0800 Subject: [Python-Dev] Python 1.6 timing (fwd) In-Reply-To: Message-ID: <001401bf638d$486488f0$c355cfc0@ski.org> Daddy Warbucks (uh, Greg Wilson =): > There's also been questions about tighter integration of NumPy (e.g. > overloading operators rather than calling 'greater()' to do comparison), > but I think that's a separate discussion... That's the rich comparison proposal which Guido mentioned. --david From bwarsaw@cnri.reston.va.us (Barry A. Warsaw) Thu Jan 20 21:30:24 2000 From: bwarsaw@cnri.reston.va.us (Barry A. Warsaw) (Barry A. Warsaw) Date: Thu, 20 Jan 2000 16:30:24 -0500 (EST) Subject: [Python-Dev] Python 1.6 timing References: <14471.31301.504670.201702@anthem.cnri.reston.va.us> <200001202116.QAA22943@eric.cnri.reston.va.us> Message-ID: <14471.32368.730988.252872@anthem.cnri.reston.va.us> >>>>> "Guido" == Guido van Rossum writes: Guido> I think before you make such changes you'd have to talk to Guido> Bob (good luck). Heh. Guido> I don't mind applying patches and doing the checkins -- Guido> it's the decision-making that's time-consuming. Then maybe the current CVS arrangement is fine (cool with me). -Barry From klm@digicool.com Thu Jan 20 22:08:28 2000 From: klm@digicool.com (Ken Manheimer) Date: Thu, 20 Jan 2000 17:08:28 -0500 (EST) Subject: [Python-Dev] Python 1.6 timing In-Reply-To: <14471.31301.504670.201702@anthem.cnri.reston.va.us> Message-ID: On Thu, 20 Jan 2000, Barry A. Warsaw wrote: > We'd have to rework the CVS arrangement in order to give non-CNRI > employees write access to the tree. I think I know how I'd go about > this, and it wouldn't be too hard, just a bit time-consuming. If > that's the way we're going to go, I can start making plans. Though it may be moot if guido's going to continue mediating the checkins, maybe this would be interesting (if only for barry, to compare procedures). We basically use a captive cvs-":ext:"-over-ssh method, where the captive .ssh/authorized_keys command is quite succinct: command="set $SSH_ORIGINAL_COMMAND; shift; exec cvs $@" 1024 35 ... The shellisms (set/shift/exec cvs $@) lock the user of the qualifying key into executing a cvs command, and only a cvs command. Also, for us the checkins are to a public mirror of our CVS repository, so penetration of the security there doesn't jepordize the master repository base. We don't currently have any outsiders checking into our master repository, and it doesn't seem to me that CVS provides sufficiently managable discretion for doing that. Oh, and a disappointment - the account under which cvs conducts the checkins is the account on the CVS server host, not that of the host where the checkins are being done. This means that you can't use a single account to serve multiple remote users (preventing masquerading quite reliably by using a separate authorized_key public-key entry for each remote user). Therefore we have to have distinct (nailed-down) accounts for each checkin-privileged person - more management burden. Ken From tim_one@email.msn.com Thu Jan 20 23:53:18 2000 From: tim_one@email.msn.com (Tim Peters) Date: Thu, 20 Jan 2000 18:53:18 -0500 Subject: [Python-Dev] Python 1.6 timing (fwd) In-Reply-To: <001401bf638d$486488f0$c355cfc0@ski.org> Message-ID: <000201bf63a1$8641b1c0$6ea0143f@tim> [Greg Wilson] > There's also been questions about tighter integration > of NumPy (e.g. overloading operators rather than > calling 'greater()' to do comparison), but I think ? that's a separate discussion... [David Ascher] > That's the rich comparison proposal which Guido mentioned. But there's also been talk about moving (at least) the basic NumPy array type into the core. This would be a Good Thing. Speaking for my employer, however, only Unicode is an Important Thing . As a developer, I have railed against schedule-driven release cycles. Python tends toward the opposite end of that spectrum, driven by features no matter how bloody long they take. Add Unicode to what's already waiting to go, and that's *good enough* reason for a major release; heck, it's been 9 months & we haven't even had a 1.5.2 bugfix patch. BTW, do the Perl-Porters have real jobs? pay-me-to-do-python-releases-and-you'll-get-a-major-new- release-every-three-days-ly y'rs - tim From da@ski.org Fri Jan 21 00:01:45 2000 From: da@ski.org (David Ascher) Date: Thu, 20 Jan 2000 16:01:45 -0800 Subject: [Python-Dev] Python 1.6 timing (fwd) In-Reply-To: <000201bf63a1$8641b1c0$6ea0143f@tim> Message-ID: <002601bf63a2$b4acf9b0$c355cfc0@ski.org> Tim Peters > But there's also been talk about moving (at least) the basic NumPy array > type into the core. This would be a Good Thing. IMNSHO, moving the current NumPy array into the core would be a Bad Thing. Moving a new similar object with cleaned up semantics and better implementation in would be a Good Thing. But it won't happen until 1.7 at the earliest, as the semantics haven't even been agreed on, let alone the code written. --david From da@ski.org Fri Jan 21 00:07:16 2000 From: da@ski.org (David Ascher) Date: Thu, 20 Jan 2000 16:07:16 -0800 Subject: [Python-Dev] Conference Schedules Message-ID: <002701bf63a3$79a15ae0$c355cfc0@ski.org> This is a multi-part message in MIME format. ------=_NextPart_000_0028_01BF6360.6B7E1AE0 Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: 7bit Given the rush of interesting discussions and progress which occurs in the two weeks before Python conferences, I propose that we have a bi-weekly conference. We'll just have to remember to cancel them at the last minute except a couple of times a year. --david ascher ------=_NextPart_000_0028_01BF6360.6B7E1AE0 Content-Type: text/x-vcard; name="David Ascher.vcf" Content-Transfer-Encoding: quoted-printable Content-Disposition: attachment; filename="David Ascher.vcf" BEGIN:VCARD VERSION:2.1 N:Ascher;David FN:David Ascher ORG:Smith Kettlewell Eye Research Institute TEL;WORK;VOICE:415-345-2095 TEL;HOME;VOICE:415-345-2095 TEL;WORK;FAX:415-345-8455 ADR;WORK:;;2318 Fillmore St;San Francisco;CA;94115;US LABEL;WORK;ENCODING=3DQUOTED-PRINTABLE:2318 Fillmore St=3D0D=3D0ASan = Francisco, CA 94115=3D0D=3D0AUS ADR;HOME:;;522A Green St;San Francisco;CA;94133;US LABEL;HOME;ENCODING=3DQUOTED-PRINTABLE:522A Green St=3D0D=3D0ASan = Francisco, CA 94133=3D0D=3D0AUS EMAIL;PREF;INTERNET:da@ski.org REV:20000107T184849Z END:VCARD ------=_NextPart_000_0028_01BF6360.6B7E1AE0-- From gstein@lyra.org Fri Jan 21 00:53:59 2000 From: gstein@lyra.org (Greg Stein) Date: Thu, 20 Jan 2000 16:53:59 -0800 (PST) Subject: [Python-Dev] Python 1.6 timing In-Reply-To: <14471.31301.504670.201702@anthem.cnri.reston.va.us> Message-ID: On Thu, 20 Jan 2000, Barry A. Warsaw wrote: > We'd have to rework the CVS arrangement in order to give non-CNRI > employees write access to the tree. I think I know how I'd go about > this, and it wouldn't be too hard, just a bit time-consuming. If > that's the way we're going to go, I can start making plans. Or move the CVS tree off-site. Cheers, -g -- Greg Stein, http://www.lyra.org/ From guido@CNRI.Reston.VA.US Fri Jan 21 01:29:30 2000 From: guido@CNRI.Reston.VA.US (Guido van Rossum) Date: Thu, 20 Jan 2000 20:29:30 -0500 Subject: [Python-Dev] Python 1.6 timing In-Reply-To: Your message of "Thu, 20 Jan 2000 10:30:52 PST." References: Message-ID: <200001210129.UAA28292@eric.cnri.reston.va.us> (I accidentally mailed this only to Greg; here's a repost of the relevant parts to the list:) [me] > > Good questions. I have to say that I feel reluctant to release any > > kind of control -- yet at the same time I desperately need help > > getting trivial stuff checked in. [Greg Stein] > Reading your comments below, we may be able to help. [...Proposal of lieutenants condensed...] > Based on my responses, I would venture to state that a group of LTs would > manage to keep the Python core rock solid, except for: > > 1) subtle breakages that require your broader knowledge of Python > 2) changes that "go against the plan" (and the LTs were ignorant of it) > 3) minor format issues > > You would still review checkins, but the number of reviews would drop > since the (obvious) crap has been eliminated. #1 is based on your *broad* > knowledge of Python; I presume the LTs would be your match on various > subsets of Python. By keeping the LTs well-informed, #2 could be nearly > eliminated. #3 isn't that big of a deal, as I think your desired style is > relatively well-known and the LTs would simply endeavor to match existing > style. > > You could avoid a lot of testing; you would probably be inclined to do > testing of items that you find dubious, but still this would be a > reduction. > > ===== > > That may be an answer to the checkin problem. How about actual snapshots, > alphas, betas, releases, and accompanying notes/news/readme files? I > presume your LTs could run the alpha and beta aspects, but you would still > issue final releases. There's a lot of work in these (you may have noticed that the release notes got sloppier as 1.5.2 neared its completion). I would be happy to have the responsibility to decide to release without the burden of having to do all the work. > Does your mail volume need to be reduced? (I think this has been asked > before) Specifically, would patches@python.org (and similar targets) need > to be established? (I would think so, as a matter of course, with the > expectation that some patches would still end up with you and need to be > bounced to patches@) It's not the mail volume that bothers me -- I can ignore 100s of messages a day very quickly. It's the time it takes to respond to all of them. As an experiment, I've collected about 40 messages with suggested patches in them that I found in my inbox; the oldest are nearly two years old. You can access these from this address: http://www.python.org/~guido/patch/ I would love any help I could get in responding with these, and taking action in the form of patches. I propose that if you decide that a particular patch is worth checking in, you ask the author for the bugrelease or wetsign disclaimer and let me know that I can check it in; if changes to the patch are needed, I propose that you negotiate these with the author first. (I often ask them to test my version of a patch when I have style suggestions but don't have access the target platform or problem it solves.) --Guido van Rossum (home page: http://www.python.org/~guido/) From tim_one@email.msn.com Fri Jan 21 09:38:21 2000 From: tim_one@email.msn.com (Tim Peters) Date: Fri, 21 Jan 2000 04:38:21 -0500 Subject: [Python-Dev] Changing existing class instances In-Reply-To: Message-ID: <001801bf63f3$414e0c60$ec2d153f@tim> [Greg Stein] > ... > In other words, I definitely would support a new class > object behavior that allows us to update a class' set of > bases and dictionary on the fly. This could then be used > to support my solution for the recursive type scenario (which, > in turn, means that we don't have to introduce Yet Another > Namespace into Python to hold type names). Parenthetically, I never grasped the appeal of the parenthetical comment. Yet Another Namespace for Yet Another Entirely New Purpose seems highly *desirable* to me! Trying to overload the current namespace set makes it so much harder to see that these are compile-time gimmicks, and users need to be acutely aware of that if they're to use it effectively. Note that I understand (& wholly agree with) the need for runtime introspection. different-things-different-rules-ly y'rs - tim From tim_one@email.msn.com Fri Jan 21 09:38:24 2000 From: tim_one@email.msn.com (Tim Peters) Date: Fri, 21 Jan 2000 04:38:24 -0500 Subject: [Python-Dev] Python 1.6 timing In-Reply-To: <20000120113352.A23763@trump.amber.org> Message-ID: <001901bf63f3$432404e0$ec2d153f@tim> [Christopher Petrilli] > Heck, Python is infinately more conservative in its > numbering than a lot of projects. All that was mentioned > would normally be enough to call it 2.0 easily. :-) Modesty > can be counter productive in PR business... Indeed, where I work a number of managers met the suggestion to use Python 1.5.x with "what?! we don't want to use software that's barely out of alpha release -- besides, Perl is already on release 5". I hear that Guido got normal American glasses -- time to do normal American hyperinflated version numbering too. heck-ms-windows-will-soon-be-at-version-2000-ly y'rs - tim From tim_one@email.msn.com Fri Jan 21 09:38:26 2000 From: tim_one@email.msn.com (Tim Peters) Date: Fri, 21 Jan 2000 04:38:26 -0500 Subject: [Python-Dev] Python 1.6 timing In-Reply-To: <14471.14877.434886.471929@amarok.cnri.reston.va.us> Message-ID: <001a01bf63f3$4473b660$ec2d153f@tim> [Andrew M. Kuchling] > ... > Similarly, does the conservative GC patch splatter changes > all over the place, or is it very localized? Part of its problem is that it's *too* localized (which was, paradoxically, I suspect part of its initial quick-eyeball appeal to Guido -- it "looks like" an amazingly self-contained patch). For example, all the code to chase pointers in various types of objects is hiding in a single function, which does a string of "if type is list then this else if type is tuple then that ..." tests. This stuff clearly needs to be distributed across the object implementations and dispatched to via a new slot in type objects; there's no code for that now. I expect it would take a minimum of two weeks (full-time work) to make this code ready for prime time (but mostly to slash the space and time use -- and with no certainty of "good enough" in the end). BTW, "conservative" is a misleading adjective for this approach -- it never guesses ("guessing on the safe side" whether or not some bit pattern is a pointer is what "conservative" customarily means in the GC world). > Is adding the NumPy array type straightforward? DavidA nixed that one in no uncertain terms! maybe-hp-will-give-up-unicode-and-we-can-release-tomorrow-ly y'rs - tim From tim_one@email.msn.com Fri Jan 21 09:52:13 2000 From: tim_one@email.msn.com (Tim Peters) Date: Fri, 21 Jan 2000 04:52:13 -0500 Subject: [Python-Dev] Python 1.6 timing (fwd) In-Reply-To: Message-ID: <001d01bf63f5$318e2600$ec2d153f@tim> [Greg Wilson] > ... > There's also a couple of smart guys in the class who are > wondering about CPython vs. JPython ("So this'll be safe in > one version of the language, but not in the other?"), Greg, people who have been exposed to Fortran (this is LANL, right ?) can't possibly have a problem with the concept of "not defined by the standard". Don't sell these as different *versions* of the language, but as different implementations. That's what they are. The Python *language* doesn't define anything about the lifetime of objects. Even when CPython grows "real GC", thanks to refcounting too you'll still be able to *rely* on behaviors in CPython you'll see only accidentally in JPython. You do so at your own risk, same as e.g. you rely on floating point Fortran x+y+z getting evaluated "left to right" at your own risk (BTW, x+y+z *is* "left to right" in Python -- maybe they'll trade that for the lack of GC promises ). From tim_one@email.msn.com Fri Jan 21 10:22:51 2000 From: tim_one@email.msn.com (Tim Peters) Date: Fri, 21 Jan 2000 05:22:51 -0500 Subject: [Python-Dev] Changing existing class instances In-Reply-To: <200001202002.PAA22435@eric.cnri.reston.va.us> Message-ID: <001e01bf63f9$79660980$ec2d153f@tim> [Tim, still worried about stomping on unintended classes/defs] [example abusing Tkinter.Misc] > For a second I thought you got me there! That's twice as long as I thought you'd think that, so I win after all . > Fortunately, there's magic available: recently, all classes > have a __module__ attribute that is set to the full name > of the module that defined it (its key in __sys__.modules). > > For functions, we would have to invent something similar. OK! I didn't know about class.__module__ -- I hope you realize that relying on your time machine is making you lazy . I remain uncomfortable with automagic updating, but not as much so. Both kinds of errors still seem possible to me: 1. Automagically updating when it wasn't wanted. Examples of this are getting harder to come by . Off the top of my head I'm reduced to stuff like this: >>> adders = [] >>> for i in range(10): def adder(y, x=i): return y+x adders.append(adder) >>> adders[2](40) 42 >>> adders[9](33) 42 >>> "That kind of thing" has got to be rare, but can't be non-existent either (well, isn't -- I've done it). 2. Failing to automagically update when it was wanted. Implicit in the discussion so far is that long-running systems want to update code at a granularity no finer than module level. Is that realistic? I'm unsure. It's certainly easy to *imagine* the app running an updater server thread, accepting new source for functions and classes, and offering to compile and install the objects. Under the explicit new.update scheme, such a service needn't bother clients with communicating the full name of the original module; heck, in a *truly* long-running app, over time the source tree will change, and classes and functions will migrate across modules. That will be a problem for the explicit scheme too (how does it know *which* "class Misc" to update) -- but at least it's an explicit problem then, and not a "mysterous failure" of hidden magic. I could live with both of those (#1 is more worrisome); but think it easier all around to give the users some tools and tell them to solve the problems however they see fit. or-maybe-we-already-agreed-about-that-ly y'rs - tim From gstein@lyra.org Fri Jan 21 11:08:19 2000 From: gstein@lyra.org (Greg Stein) Date: Fri, 21 Jan 2000 03:08:19 -0800 (PST) Subject: [Python-Dev] namespaces (was: Changing existing class instances) In-Reply-To: <001801bf63f3$414e0c60$ec2d153f@tim> Message-ID: On Fri, 21 Jan 2000, Tim Peters wrote: > [Greg Stein] > > ... > > In other words, I definitely would support a new class > > object behavior that allows us to update a class' set of > > bases and dictionary on the fly. This could then be used > > to support my solution for the recursive type scenario (which, > > in turn, means that we don't have to introduce Yet Another > > Namespace into Python to hold type names). > > Parenthetically, I never grasped the appeal of the parenthetical comment. > Yet Another Namespace for Yet Another Entirely New Purpose seems highly > *desirable* to me! Trying to overload the current namespace set makes it so > much harder to see that these are compile-time gimmicks, and users need to > be acutely aware of that if they're to use it effectively. Note that I > understand (& wholly agree with) the need for runtime introspection. And that is the crux of the issue: I think the names that are assigned to these classes, interfaces, typedefs, or whatever, can follow the standard Python semantics and be plopped into the appropriate namespace. There is no overloading. The compile-time behavior certainly understands what names have what types; in this case, if a name is a "typedecl", then it can remember the *value*, too. When the name is used later, it knows the corresponding value to use. For instance: IntOrString = typedef int|str def foo(x: IntOrString): ... In this example, the type-checker knows that IntOrString is a typedecl. It also knows the *value* of "int|str" so the name IntOrString now has two items associated with it at type-check time: # not "real" syntax, but you get the idea... namespace["IntOrString"] = (TypeDeclarator, int|str) With the above information in hand, the type-checker knows what IntOrString means in the declaration for foo(). The cool benefit is that the runtime semantics are exactly as you would expect: a typedecl object is created and assigned to IntOrString. That object is also associated with the "x" argument in the function object referred to by the name "foo". There is no "overloading" of namespaces. We are using Python namespaces just like they should be, and the type-checker doesn't even have to be all the smart to track this stuff. To get back to the recursive class problem, consider the following code: decl incomplete class Foo decl incomplete class Bar class Foo: decl a: Bar class Bar: decl b: Foo The "decl" statements would create an empty class object and store that into the "current" namespace. There is no need to shove that off into another namespace. When the "class Foo" comes along, the class object is updated with the class definition for Foo. It is conceivable to remove the need for "decl" if you allow "class" and "def" to omit the ": suite" portion of their grammar: class Foo class Bar class Foo: decl a: Bar ... def some_function(x: some_type, y: another_type) -> third_type ... lots o' code ... def some_function(x, y): ... Guido suggested that it may be possible to omit "decl" altogether. Certainly, it can work for member declarations such as: class Foo: a: Bar Anyhow... my point is that a new namespace is not needed. Assuming we want objects for reflection at runtime, then the above proposal states *how* those objects are realized at runtime. Further, the type-checker can easily follow that information and perform the appropriate compile-time checks. No New Namespaces! (lather, rinse, repeat) Cheers, -g -- Greg Stein, http://www.lyra.org/ From gstein@lyra.org Fri Jan 21 11:12:57 2000 From: gstein@lyra.org (Greg Stein) Date: Fri, 21 Jan 2000 03:12:57 -0800 (PST) Subject: [Python-Dev] Changing existing class instances In-Reply-To: <200001202002.PAA22435@eric.cnri.reston.va.us> Message-ID: On Thu, 20 Jan 2000, Guido van Rossum wrote: > Tim Peters: >... > > At the time my.py defines Misc, does Misc count as a class we're "about to > > stomp on"? If so-- & I've assumed so --it would wreak havoc. > > > > But if not, I don't see how this case can be reliably distinguished "by > > magic" from the cases where update is desired (if people are doing dynamic > > updates to a long-running program, a new version of a class can come from > > anywhere, so nothing like original file name or line number can distinguish > > correctly either). > > Fortunately, there's magic available: recently, all classes have a > __module__ attribute that is set to the full name of the module that > defined it (its key in __sys__.modules). > > For functions, we would have to invent something similar. func.func_globals __module__ and func_globals can prevent *other* modules from redefining something accidentally, but it doesn't prevent Badness from within the module. [ Tim just posted an example of this: his "def adder()" example... ] Cheers, -g -- Greg Stein, http://www.lyra.org/ From bwarsaw@cnri.reston.va.us (Barry A. Warsaw) Fri Jan 21 14:38:52 2000 From: bwarsaw@cnri.reston.va.us (Barry A. Warsaw) (Barry A. Warsaw) Date: Fri, 21 Jan 2000 09:38:52 -0500 (EST) Subject: [Python-Dev] Changing existing class instances References: <200001202002.PAA22435@eric.cnri.reston.va.us> <001e01bf63f9$79660980$ec2d153f@tim> Message-ID: <14472.28540.765858.16133@anthem.cnri.reston.va.us> >>>>> "TP" == Tim Peters writes: TP> Under the explicit new.update scheme, such a service needn't TP> bother clients with communicating the full name of the TP> original module; heck, in a *truly* long-running app, over TP> time the source tree will change, and classes and functions TP> will migrate across modules. That will be a problem for the TP> explicit scheme too (how does it know *which* "class Misc" to TP> update) -- but at least it's an explicit problem then, and not TP> a "mysterous failure" of hidden magic. I completely agree. I think in general, such long running apps are rare, and in those cases you probably want to be explicit about when and how the updates occur anyway. The one place where automatic updates would be convenient would be at the interactive prompt, so it might be nice to add a module that could be imported by PYTHONSTARTUP, and play hook games to enable automatic updates. -Barry From bwarsaw@cnri.reston.va.us (Barry A. Warsaw) Fri Jan 21 14:39:32 2000 From: bwarsaw@cnri.reston.va.us (Barry A. Warsaw) (Barry A. Warsaw) Date: Fri, 21 Jan 2000 09:39:32 -0500 (EST) Subject: [Python-Dev] Python 1.6 timing References: <14471.31301.504670.201702@anthem.cnri.reston.va.us> Message-ID: <14472.28580.945266.658533@anthem.cnri.reston.va.us> >>>>> "GS" == Greg Stein writes: GS> Or move the CVS tree off-site. I don't see what this buys us. -Barry From gstein@lyra.org Fri Jan 21 14:48:40 2000 From: gstein@lyra.org (Greg Stein) Date: Fri, 21 Jan 2000 06:48:40 -0800 (PST) Subject: [Python-Dev] Python 1.6 timing In-Reply-To: <14472.28580.945266.658533@anthem.cnri.reston.va.us> Message-ID: On Fri, 21 Jan 2000, Barry A. Warsaw wrote: > >>>>> "GS" == Greg Stein writes: > > GS> Or move the CVS tree off-site. > > I don't see what this buys us. I was under the impression that CVS access restrictions are based on CNRI security policy. If the CVS repository moves elsewhere, then many people can access it without impact on CNRI's network and security policies. However, if the external access issue is based on legal reasons (for example, only CNRI people should alter Python code), then yes: moving the repository will buy nothing. Cheers, -g -- Greg Stein, http://www.lyra.org/ From bwarsaw@python.org Fri Jan 21 16:08:11 2000 From: bwarsaw@python.org (bwarsaw@python.org) Date: Fri, 21 Jan 2000 11:08:11 -0500 (EST) Subject: [Python-Dev] Python 1.6 timing References: <14472.28580.945266.658533@anthem.cnri.reston.va.us> Message-ID: <14472.33899.20409.602096@anthem.cnri.reston.va.us> >>>>> "GS" == Greg Stein writes: GS> I was under the impression that CVS access restrictions are GS> based on CNRI security policy. If the CVS repository moves GS> elsewhere, then many people can access it without impact on GS> CNRI's network and security policies. Well, access to our /internal/ network is of course restricted. CNRI employees have write access to the tree by virtue of access to the filesystem (i.e. by NFS). My current arrangement for external ssh mediated access to a writable cvs server on an internal machine is a hack and not something that I want to perpetuate if more users were added. GS> However, if the external access issue is based on legal GS> reasons (for example, only CNRI people should alter Python GS> code), then yes: moving the repository will buy nothing. I'll let Guido comment on policy concerning write access to the Python CVS tree. From a technical standpoint, if this is something Guido wanted to extend to non-CNRI employees, the way to do it would be to host the primary repository on a CNRI machine outside our firewall, e.g cvs.python.org. At that point, we'd be accessing the tree the same as anybody else. -Barry From gstein@lyra.org Fri Jan 21 16:19:33 2000 From: gstein@lyra.org (Greg Stein) Date: Fri, 21 Jan 2000 08:19:33 -0800 (PST) Subject: [Python-Dev] Python 1.6 timing In-Reply-To: <14472.33899.20409.602096@anthem.cnri.reston.va.us> Message-ID: On Fri, 21 Jan 2000 bwarsaw@python.org wrote: > >>>>> "GS" == Greg Stein writes: >... > From a technical standpoint, if this is something Guido > wanted to extend to non-CNRI employees, the way to do it would be to > host the primary repository on a CNRI machine outside our firewall, > e.g cvs.python.org. At that point, we'd be accessing the tree the > same as anybody else. Gotcha. Sounds great! I'm not sure yet that Guido is looking for external people to do checkins (as opposed to delivering refined patches to him)... So we probably don't need an assessment from the legal department :-), but if Guido already knows, then I'd be curious. thx! -g -- Greg Stein, http://www.lyra.org/ From paul@prescod.net Fri Jan 21 16:51:24 2000 From: paul@prescod.net (Paul Prescod) Date: Fri, 21 Jan 2000 08:51:24 -0800 Subject: [Python-Dev] Re: [Types-sig] namespaces (was: Changing existing class instances) References: Message-ID: <38888E8C.FE369A86@prescod.net> Greg Stein wrote: > Tim Peters: > > Trying to overload the current namespace set makes it so > > much harder to see that these are compile-time gimmicks, and users need to > > be acutely aware of that if they're to use it effectively. Note that I > > understand (& wholly agree with) the need for runtime introspection. > > And that is the crux of the issue: I think the names that are assigned to > these classes, interfaces, typedefs, or whatever, can follow the standard > Python semantics and be plopped into the appropriate namespace. There is > no overloading. This is indeed the crux of the issue. For those that missed it last time, it became very clear to me that we are working with radically different design aesthetics when we discussed the idea of having an optional keyword that said: "this thing is usually handled at compile time but I want to handle it at runtime. I know what I am doing." Greg complained that that would require the programmer to understand too much what was being done at compile time and what at runtime and what. >From my point of view this is *exactly* what a programmer *needs* to know and if we make it too hard for them to know it then we have failed. > There is no "overloading" of namespaces. We are using Python namespaces > just like they should be, and the type-checker doesn't even have to be all > the smart to track this stuff. There is an overloading of namespaces because we will separately specify the *compile time semantics* of these names. We need to separately specify these semantics because we need all compile time type checkers to behave identically. Yes, it seems elegant to make type objects seem as if they are "just like" Python objects. Unfortunately they aren't. Type objects are evaluated -- and accepted or rejected -- at compile time. Every programmer needs to understand that and it should be blatantly obvious in the syntax, just as everything else in Python syntax is blatantly obvious. -- Paul Prescod - ISOGEN Consulting Engineer speaking for himself Earth will soon support only survivor species -- dandelions, roaches, lizards, thistles, crows, rats. Not to mention 10 billion humans. - Planet of the Weeds, Harper's Magazine, October 1998 From skaller@maxtal.com.au Fri Jan 21 21:01:03 2000 From: skaller@maxtal.com.au (skaller) Date: Sat, 22 Jan 2000 08:01:03 +1100 Subject: [Python-Dev] Re: [Types-sig] namespaces (was: Changing existing class instances) References: <38888E8C.FE369A86@prescod.net> Message-ID: <3888C90F.BECA3FF6@maxtal.com.au> Paul Prescod wrote: > Yes, it seems elegant to make type objects seem as if they are "just > like" Python objects. Unfortunately they aren't. Yes they are. They even have a type, TypeType. -- John (Max) Skaller, mailto:skaller@maxtal.com.au 10/1 Toxteth Rd Glebe NSW 2037 Australia voice: 61-2-9660-0850 homepage: http://www.maxtal.com.au/~skaller download: ftp://ftp.cs.usyd.edu/au/jskaller From tim_one@email.msn.com Sat Jan 22 23:18:14 2000 From: tim_one@email.msn.com (Tim Peters) Date: Sat, 22 Jan 2000 18:18:14 -0500 Subject: [Python-Dev] Python 1.6 timing In-Reply-To: <000701bf636f$de37c5e0$c355cfc0@ski.org> Message-ID: <000401bf652e$f5266b60$132d153f@tim> [David Ascher] > ... > Regardless, just like Greg, I'd like to know what a > pumpkin-holder would mean in the Python world. > > I propose that it be called the Oracle instead. As in, > whoever is Oracle would get some training with Tim Peters > and learn how to channel G__do. I'm afraid that wouldn't work. The whole secret to channeling Guido in the *past* was to have been an ABC user: all you had to do is notice the things about ABC that you loved and the ones that would drive any sane *experienced* programmer mad with frustration. Voila! Guido's mind is your mind . But the more Python sails into uncharted waters, the less reliable my Guido-channeling pseudo-skills get. He is, in Essence, Unfathomable. Also indispensable. > As a Python user, I'd be most comfortable with such a change > if the Oracle just took over the technical stuff (reviewing > patches, CVS checkins, running tests, corralling help for > doc & code, maintaining release notes, building installers, > etc.), but that the important decisions (e.g. whether to add > a feature to the core language) would be checked with G__do > first. Definitely. But where do you find someone like that? It's (or at least *should* be) several full-time jobs. Languages like Icon & Scheme do it via university association (scads of grad student slave labor); REBOL did it by floating a trendy Internet business plan that actually attracted enough venture capital to hire about 30 people; Python, unfortunately , seems to attract people who already have demanding jobs. So I see it as an issue of finding warm bodies more than anything else. In the absence of funding "real jobs", I really don't see much hope. Bits & pieces can be farmed out (e.g., I doubt Guido has had to do any work on the regular expression code since Andrew arrived), but that's it -- I expect the past predicts the future quite accurately here. Certainly much more *could* be "farmed out", but no single volunteer of the kind Python has attracted so far is going to do a lot on their own month after month after month. Even with the best of intentions, their "real life" will interfere severely more often than not (voice of experience, there -- and I'd guess it's the same for *all* of us). if-something-doesn't-change-nothing-will-change-ly y'rs - tim From tim_one@email.msn.com Sat Jan 22 23:18:11 2000 From: tim_one@email.msn.com (Tim Peters) Date: Sat, 22 Jan 2000 18:18:11 -0500 Subject: Python 2 namespace change? (was Re: [Python-Dev] Changing existing class instances) In-Reply-To: <38871CE5.53FB9D68@digicool.com> Message-ID: <000301bf652e$f348d1c0$132d153f@tim> [Jim Fulton] > ... > A change to the way that namespaces are handled > could make this work and have a number of other benefits, > like global name usage without namespace lookups. > > I've suggested this to Guido in the past. His > reasonable response is that this would be too big a > change for Python 1. Maybe this is something to consider > for Python 2? > > The basic idea (borrowed from Smalltalk) is to have a kind > of dictionary that is a collection of "association" > objects. An association object is simply a pairing of a > name with a value. Association objects can be shared among > multiple namespaces. Jim, I've been intrigued by this idea for all the years you've been suggesting it , but I've never understood what it is you're proposing! This is the Python-Dev list, so feel encouraged to present it in concrete implementation terms instead of ambiguous English. Or maybe an interface? interface a_kind_of_dictionary_that_is_a_collection_of_\ association_objects: # ??? beats me ... Or maybe as a C struct? For example, is "an association object" a (char*, PyObject*) pair? Does this kind of dictionary have keys? If so, of what type? What type are the values? Best I can make sense of the above, the values are "association objects", each of which contains a name and a value, and a key is maybe a duplicate of the name in the association object to which it maps. "A name" may or may not be a string -- I can't tell. Or maybe by "dictionary" you didn't intend Python's current meaning for that word at all. I assume "a value" is a PyObject*. The whole thrust *appears* to be to get names to map to a PyObject** instead of PyObject*, but if that's the ticket I don't know what association objeects have to do with it. > An import like: > > from foo import spam > > would copy the association between the name 'foo' and a > value from module 'spam' into the current module. Where does the idea that 'spam' is a *module* here come from? It doesn't make sense to me, and I'm so lost I'll spare everyone my further confusions . suspecting-the-last-actually-doesn't-make-any-sense-ly y'rs - tim From tim_one@email.msn.com Sat Jan 22 23:29:45 2000 From: tim_one@email.msn.com (Tim Peters) Date: Sat, 22 Jan 2000 18:29:45 -0500 Subject: [Python-Dev] Python 1.6 timing (fwd) In-Reply-To: <38875DD1.B6596@tismer.com> Message-ID: <000701bf6530$90cc31c0$132d153f@tim> [hristian Tismer] > ... > Even better: Refcounting can lead to many new optimizations > if we pay the cost to make INCREF/DECREF into methods. It > has its cost (about 10 percent less pystones), but massive > long-term benefits. The GC patch Guido forced me to look at is based on the observation that it's impossible to create cyclic trash unless a decref leaves a nonzero refcount. So the patch adds a function call to the DECREF macro (if the new refcount is > 0, the object must be added to the set of "suspicious" objects; else the object must be removed from that set). So it roughly adds the cost of a method call to each decref anyway. You would think it adds less , but "the set" now is represented as a splay tree, so *gobs* of hairy code get executed in either case (splay trees do mutating rotations even on a lookup). > ... > Conclusion: I vote for a kind of GC that does just what > refcounts cannot do, but please keep with the refcounts. I like 'em too! BTW, Toby posted (at least an earlier version of) the patch to c.l.py, if anyone else wants to dig into it (I may have mentioned before that I'm short on time ). From tim_one@email.msn.com Sun Jan 23 04:59:38 2000 From: tim_one@email.msn.com (Tim Peters) Date: Sat, 22 Jan 2000 23:59:38 -0500 Subject: [Python-Dev] Changing existing class instances In-Reply-To: <14472.28540.765858.16133@anthem.cnri.reston.va.us> Message-ID: <000201bf655e$a6a49b80$732d153f@tim> [Barry A. Warsaw] > I completely agree. That's no fun . > I think in general, such long running apps are rare, By definition, they're non-existent under Windows <0.7 wink>. But it depends on which field you're working in. The closer you get to being part of a business or consumer service, the more important it gets; e.g., I've seen serious RFQs for software systems guaranteed to suffer no more than 5 minutes of downtime per *year* (& stiff penalties for failure to meet that). I've never been on the winning end of such an RFQ, so am not sure what it takes to meet it. It's interesting to ponder. Psion has published a little about the software techniques they use in their PDAs (my Psion 3a's remarkably capable "Agenda" app has been running non-stop for a bit over 3 years!). > and in those cases you probably want to be explicit about when > and how the updates occur anyway. My guess is you'd want to be *paranoidly* explicit, leaving nothing to chance. > The one place where automatic updates would be convenient would > be at the interactive prompt, so it might be nice to add a > module that could be imported by PYTHONSTARTUP, and play hook > games to enable automatic updates. Returning the favor, I completely agree. The single thing people at work gripe most about is how to do development under IDLE in such a way that their package-laden systems exhibit the hoped-for changes in response to editing a module deep in the bowels of the system. I don't have a *good* answer to that now; reduced to stuff like writing custom scripts to selectively clear out sys.modules. non-stop-ly y'rs - tim From bwarsaw@cnri.reston.va.us (Barry A. Warsaw) Sun Jan 23 15:07:26 2000 From: bwarsaw@cnri.reston.va.us (Barry A. Warsaw) (Barry A. Warsaw) Date: Sun, 23 Jan 2000 10:07:26 -0500 (EST) Subject: [Python-Dev] Python 1.6 timing References: <000701bf636f$de37c5e0$c355cfc0@ski.org> <000401bf652e$f5266b60$132d153f@tim> Message-ID: <14475.6446.336166.192186@anthem.cnri.reston.va.us> >>>>> "TP" == Tim Peters writes: TP> REBOL did it by floating a trendy Internet business plan that TP> actually attracted enough venture capital to hire about 30 TP> people; Python, unfortunately , seems to attract people TP> who already have demanding jobs. I think all we have to do is change the name for 1.6 to LinuxPython 2.0, then split off and go IPO. The more money we lose, the higher our stock will go and we can use our market cap to hire all those warm bodies. -Barry From jeremy@cnri.reston.va.us Sun Jan 23 18:54:40 2000 From: jeremy@cnri.reston.va.us (Jeremy Hylton) Date: Sun, 23 Jan 2000 13:54:40 -0500 (EST) Subject: [Python-Dev] Python 1.6 timing In-Reply-To: <000401bf652e$f5266b60$132d153f@tim> References: <000701bf636f$de37c5e0$c355cfc0@ski.org> <000401bf652e$f5266b60$132d153f@tim> Message-ID: <14475.20080.508651.261991@bitdiddle.cnri.reston.va.us> >>>>> "TP" == Tim Peters writes: TP> [David Ascher] >> I propose that it be called the Oracle instead. As in, whoever >> is Oracle would get some training with Tim Peters and learn how >> to channel G__do. TP> I'm afraid that wouldn't work. The whole secret to channeling TP> Guido in the *past* was to have been an ABC user: all you had to TP> do is notice the things about ABC that you loved and the ones TP> that would drive any sane *experienced* programmer mad with TP> frustration. Voila! Guido's mind is your mind . I have discovered another approach. CNRI put in a cleam room on the second floor last year. I recently discovered a little door behind some metrology device in a corner of the clean room. The door opens onto a tunnel that leads directly into Guido's mind. Unfortunately, it won't be of much use for a pumpkin-holder or channeler, because after about 15 minutes you are deposited on the shoulder of the Dulles Toll Road. who-wants-to-be-John-Malkovich-when-they-could-be-Guido-ly y'rs, Jeremy From skip@mojam.com (Skip Montanaro) Wed Jan 26 03:42:06 2000 From: skip@mojam.com (Skip Montanaro) (Skip Montanaro) Date: Tue, 25 Jan 2000 21:42:06 -0600 Subject: [Python-Dev] Multiple dicts for string interpolation? Message-ID: <200001260342.VAA10627@beluga.mojam.com> Every once in awhile I want to perform string interpolation using more than one dictionary. One way is to build a dictionary that's a union of multiple dictionaries: dict = {} dict.update(d1) dict.update(d2) ... s = format % dict Another way is the MultiDict approach that Digital Creations (used to?) use in their DocumentTemplate module (I can't remember the exact usage any more): dict = MultiDict() dict.append(d1) dict.append(d2) ... s = format % dict A MultiDict object maintains a list of the dicts it's been fed and searches them in order when __getitem__ is called. I'd like to propose a third alternative. How about if the string interpolation function accepted a tuple of dictionaries directly: s = format % (d1, d2) It would only be used when named interpolation was expected. I don't think there would be any conflict with current % operator semantics. Skip Montanaro | http://www.mojam.com/ skip@mojam.com | http://www.musi-cal.com/ 847-971-7098 From guido@CNRI.Reston.VA.US Wed Jan 26 04:13:28 2000 From: guido@CNRI.Reston.VA.US (Guido van Rossum) Date: Tue, 25 Jan 2000 23:13:28 -0500 Subject: [Python-Dev] Multiple dicts for string interpolation? In-Reply-To: Your message of "Tue, 25 Jan 2000 21:42:06 CST." <200001260342.VAA10627@beluga.mojam.com> References: <200001260342.VAA10627@beluga.mojam.com> Message-ID: <200001260413.XAA02813@eric.cnri.reston.va.us> > I'd like to propose a third alternative. How about if the string > interpolation function accepted a tuple of dictionaries directly: > > s = format % (d1, d2) > > It would only be used when named interpolation was expected. I don't think > there would be any conflict with current % operator semantics. Gut feeling: it's dangerous to fill up every possible dark corner with specific semantics that are occasionally useful, because if you go too far you lose useful redundancy, and you end up with Perl. Not sure whether this particular suggestion is "going too far." I think it depends on to what extent this is a common, useful idiom. Do you have evidence of that? Examples? --Guido van Rossum (home page: http://www.python.org/~guido/) From skip@mojam.com (Skip Montanaro) Wed Jan 26 04:38:53 2000 From: skip@mojam.com (Skip Montanaro) (Skip Montanaro) Date: Tue, 25 Jan 2000 22:38:53 -0600 (CST) Subject: [Python-Dev] Multiple dicts for string interpolation? In-Reply-To: <200001260413.XAA02813@eric.cnri.reston.va.us> References: <200001260342.VAA10627@beluga.mojam.com> <200001260413.XAA02813@eric.cnri.reston.va.us> Message-ID: <14478.31325.891846.701373@beluga.mojam.com> >> I'd like to propose a third alternative. How about if the string >> interpolation function accepted a tuple of dictionaries directly: >> >> s = format % (d1, d2) Guido> Gut feeling: it's dangerous to fill up every possible dark corner Guido> with specific semantics that are occasionally useful, because if Guido> you go too far you lose useful redundancy, and you end up with Guido> Perl. Yeah, I am kind of taking advantage of the fact that the format operator doesn't happen to use tuples of dicts already, though this seems like a natural extension of the current semantics. Currently, you can have Style of Simple form Complex form Interpolation ------- ----------- ------------ sprintf string tuple of strings named dict tuple of dicts It does complicate the decision making process in the string format routine a bit. Guido> I think it depends on to what extent this is a common, useful Guido> idiom. Do you have evidence of that? Examples? Well, the first place I ran into it was in DocumentTemplates a few years ago. They used an idiom heavily which may have now been replaced by acquisition where you'd effectively push and pop value dicts onto a stack as you entered and exited nested blocks of DTML code. Their solution was a special dict-like object. The example that made the light click for me this evening was having an object whose class dict stores constants and whose instant dict stores varying values. It seemed cleaner to me to do obj = Class() ... s = format % (Class.__dict__, obj.__dict__) than go through the intermediate step of building a separate dict which would just get discarded as soon as this bit of string building was complete. (I will perform this once for each of several thousand instances.) It's not a big deal. If it seems too obscure the other obvious solutions are not gruesome. Skip From skip@mojam.com (Skip Montanaro) Wed Jan 26 04:40:20 2000 From: skip@mojam.com (Skip Montanaro) (Skip Montanaro) Date: Tue, 25 Jan 2000 22:40:20 -0600 (CST) Subject: [Python-Dev] Multiple dicts for string interpolation? In-Reply-To: <14478.31325.891846.701373@beluga.mojam.com> References: <200001260342.VAA10627@beluga.mojam.com> <200001260413.XAA02813@eric.cnri.reston.va.us> <14478.31325.891846.701373@beluga.mojam.com> Message-ID: <14478.31412.36960.440988@beluga.mojam.com> Oh crap... Of course, the table should have been Style of Simple form Complex form Interpolation ------- ----------- ------------ sprintf string tuple of strings named dict (empty fourth cell...) Skip From klm@digicool.com Wed Jan 26 05:01:36 2000 From: klm@digicool.com (Ken Manheimer) Date: Wed, 26 Jan 2000 00:01:36 -0500 (EST) Subject: [Python-Dev] Multiple dicts for string interpolation? In-Reply-To: <14478.31325.891846.701373@beluga.mojam.com> Message-ID: On Tue, 25 Jan 2000, Skip Montanaro wrote: > Guido> Skip: > >> I'd like to propose a third alternative. How about if the string > >> interpolation function accepted a tuple of dictionaries directly: > >> > >> s = format % (d1, d2) > [...] > Guido> I think it depends on to what extent this is a common, useful > Guido> idiom. Do you have evidence of that? Examples? > > Well, the first place I ran into it was in DocumentTemplates a few years > ago. They used an idiom heavily which may have now been replaced by > acquisition where you'd effectively push and pop value dicts onto a stack as > you entered and exited nested blocks of DTML code. Their solution was a > special dict-like object. Implementation of acquisition basically uses a MultiDict underneath. Consider acquisition as a cumulative context composed from the containers of the target of a web request. (Actually, a distinction is made between the object containment hierarchy of the target and the successive components of the path along which the target is reached by the request, with the containment contexts taking precedence - but that's probably not important here:-) Add in incidental things like the server environment (from which you can get HTTP_REFERER and cookies and so forth). Each of the components can be a dictionary or a MultiDict (or a sequence of pairs, i think), and they're ultimately composed in a MultiDict. I think another place in zope where multidicts play prominently is in the security mechanism, where any object can have local roles, and the ultimate role of a user within a context is composed from the union across the containment hierarchy. There probably are lots of other places where multidicts are used. Suffice to say that there's a lot of composing of contexts that goes on in Zope in general, acquistion being a prime example but not the only one, and multidicts play heavily in many. I would be surprised if this need to combine contexts is peculiar to web server, or general server applications. > [...] > It's not a big deal. If it seems too obscure the other obvious solutions > are not gruesome. I suppose we'd be pretty happy to have something like MultiDict as part of python... Ken klm@digicool.com (Who's the only one left in fredericksburg to speak up, at the moment:-) From tim_one@email.msn.com Wed Jan 26 05:39:19 2000 From: tim_one@email.msn.com (Tim Peters) Date: Wed, 26 Jan 2000 00:39:19 -0500 Subject: [Python-Dev] Multiple dicts for string interpolation? In-Reply-To: <200001260413.XAA02813@eric.cnri.reston.va.us> Message-ID: <000101bf67bf$b103e460$592d153f@tim> [Skip, wants to interpolate multiple dicts via "%", suggests passing a tuple of dicts: format % (d1, d2, ...)] [Guido] > ... > I think it depends on to what extent this is a common, useful > idiom. Do you have evidence of that? Examples? You yourself raised one last century : simply wanting to interpolate from both locals() and globals(). At the time, the idea of a new dict-like mapping object (capturing Python's lookup rules) appealed to you. I still like that, and note that the apparent need becomes more acute if "deep nesting" is ever added. I wasn't aware of the MultiDict approach Skip mentioned, but thought it looked spot on for the general case! Skip, is the long-windedness of dict = MultiDict() dict.append(d1) dict.append(d2) ... s = format % dict the part you didn't like about that? If so, how about changing the constructor to def __init__(self, *dicts): ... instead so you could use it as a one-liner format % MultiDict(d1, d2, ...) ? That's exactly the same as the tuple idea, except there's a nice descriptive word in the middle of it . From jack@oratrix.nl Wed Jan 26 09:56:18 2000 From: jack@oratrix.nl (Jack Jansen) Date: Wed, 26 Jan 2000 10:56:18 +0100 Subject: [Python-Dev] Multiple dicts for string interpolation? In-Reply-To: Message by "Tim Peters" , Wed, 26 Jan 2000 00:39:19 -0500 , <000101bf67bf$b103e460$592d153f@tim> Message-ID: <20000126095619.DC67D36E440@snelboot.oratrix.nl> > the part you didn't like about that? If so, how about changing the > constructor to > > def __init__(self, *dicts): > ... > > instead so you could use it as a one-liner > > format % MultiDict(d1, d2, ...) > > ? That's exactly the same as the tuple idea, except there's a nice > descriptive word in the middle of it . I've always wonderer why dict+dict isn't supported (or possibly dict|dict, if the key-collision semantics of + on dict are seen as a problem). Is there a good reason for this, or is it just that there are other more important things to implement? This wouldn't be a replacement for all uses of MultiDict, as it would probably have to create a new dict to keep semantics in line with those of list+list -- Jack Jansen | ++++ stop the execution of Mumia Abu-Jamal ++++ Jack.Jansen@oratrix.com | ++++ if you agree copy these lines to your sig ++++ www.oratrix.nl/~jack | see http://www.xs4all.nl/~tank/spg-l/sigaction.htm From guido@CNRI.Reston.VA.US Wed Jan 26 12:41:45 2000 From: guido@CNRI.Reston.VA.US (Guido van Rossum) Date: Wed, 26 Jan 2000 07:41:45 -0500 Subject: [Python-Dev] Multiple dicts for string interpolation? In-Reply-To: Your message of "Wed, 26 Jan 2000 10:56:18 +0100." <20000126095619.DC67D36E440@snelboot.oratrix.nl> References: <20000126095619.DC67D36E440@snelboot.oratrix.nl> Message-ID: <200001261241.HAA03001@eric.cnri.reston.va.us> [Tim] > > format % MultiDict(d1, d2, ...) > > > > ? That's exactly the same as the tuple idea, except there's a nice > > descriptive word in the middle of it . Nice. [Jack] > I've always wonderer why dict+dict isn't supported (or possibly > dict|dict, if the key-collision semantics of + on dict are seen as a > problem). Is there a good reason for this, or is it just that there > are other more important things to implement? The reason is that + (or |) looks symmetrical, but for the key collisions, one of them has to lose. We now have dict1.update(dict2), which is a bit more cumbersome, but makes it much clearer who is the loser. --Guido van Rossum (home page: http://www.python.org/~guido/) From skip@mojam.com (Skip Montanaro) Wed Jan 26 14:30:09 2000 From: skip@mojam.com (Skip Montanaro) (Skip Montanaro) Date: Wed, 26 Jan 2000 08:30:09 -0600 (CST) Subject: [Python-Dev] Multiple dicts for string interpolation? In-Reply-To: <000101bf67bf$b103e460$592d153f@tim> References: <200001260413.XAA02813@eric.cnri.reston.va.us> <000101bf67bf$b103e460$592d153f@tim> Message-ID: <14479.1265.213769.810138@beluga.mojam.com> Tim> Skip, is the long-windedness of Tim> dict = MultiDict() Tim> dict.append(d1) Tim> dict.append(d2) Tim> ... Tim> s = format % dict Tim> the part you didn't like about that? If so, how about changing the Tim> constructor to Tim> def __init__(self, *dicts): Tim> ... Tim> instead so you could use it as a one-liner Tim> format % MultiDict(d1, d2, ...) Tim> ? That's exactly the same as the tuple idea, except there's a nice Tim> descriptive word in the middle of it . The long-windedness was part of it. The performance hit of composing dictionaries thousands of times to perform a single format operation was also a consideration. Okay, side excursion into the Zope source tree... What I was calling MultiDict is actually MultiMapping (written in C, BTW). As a side effect of my Zope install here, I even already have it in sys.path (go figure!). And it turns out to work just as Tim surmised: >>> d1 = {"a": 1} >>> d2 = {"b": 2} >>> d = MultiMapping.MultiMapping(d1, d2) >>> d["b"] 2 >>> d["a"] 1 Dang! Turns out Jim Fulton has a time machine also. I guess the next question is to extend Ken's comment about getting it into the Python core. Would that be something possible for 1.6? I used a Python version of MultiMapping in an ancient version of DocumentTemplate. I'm sure the C version has been around for at least two or three years and would appear pretty darn stable, since it seems to be at the core of a lot of Zope's coolness. Skip From ping@lfw.org Thu Jan 27 07:06:01 2000 From: ping@lfw.org (Ka-Ping Yee) Date: Wed, 26 Jan 2000 23:06:01 -0800 (PST) Subject: [Python-Dev] Multiple dicts for string interpolation? In-Reply-To: <14478.31325.891846.701373@beluga.mojam.com> Message-ID: On Tue, 25 Jan 2000, Skip Montanaro wrote: > > Guido> I think it depends on to what extent this is a common, useful > Guido> idiom. Do you have evidence of that? Examples? > > Well, the first place I ran into it was in DocumentTemplates a few years > ago. They used an idiom heavily which may have now been replaced by > acquisition where you'd effectively push and pop value dicts onto a stack as > you entered and exited nested blocks of DTML code. Their solution was a > special dict-like object. That's really interesting. I wrote a bunch of Python wrappers for a UI toolkit a little while ago, and there were two main pieces of machinery i built to make the toolkit pleasant to use: 1. a reasonably nice C++ extension class kit (this is where i tried overloading operator new for the first time, so it would allocate memory that could be freed by PyMem_DEL -- i don't know if CXX uses the same approach) 2. a second layer of Python wrapper classes for the extension classes that implements extra methods in Python, and maintains a hierarchy of default keyword argument values along the inheritance hierarchy of widgets The second of these things involved implementing exactly the kind of dictionary stack that you mentioned. The programming idiom for building widgets goes something like: defaultstack = {} # maps class object to list of defaults dictionaries class Label(Component): defaults = _dict(text="Label", align=LEFT) class Button(Label): defaults = _dict(text="Button", align=CENTER, shadow=2) ... w = Window(...) Button.push(fg="white", bg="red", font="-*-courier-bold-r-normal--14-*-*-*-*-*-*-*") a = Button(w, text="one") b = Button(w, text="two") c = Button(w, text="three") Button.pop() This way you can install some options for a while and make a bunch of widgets with your defaults, then pop the options and go back to the previous state. The layers of dictionaries that get composed in every widget's __init__ function are (in order of priority): 1. any non-None keyword arguments to __init__ 2. any non-None values in class.defaults 3. any non-None values in class.__bases__[0].defaults 4. any non-None values in class.__bases__[0].__bases__[0].defaults etc. When a new set of defaults is push()ed, the class's current defaults are saved on the defaultstack for the class, and restored when pop() gets called. I don't *know* if this is really the best way to do things, but it has seemed to work out pretty well in practice. It makes it more convenient to deal with all the options you have to throw around especially when doing UI stuff. Anyway, i noticed the same sort of thing today while wondering about using keyword arguments for HTML tag attributes. (Perhaps HTMLgen does this sort of thing already -- sorry i haven't looked at it.) Anyway, the following sort of helper might be useful in general: class Default: def __init__(self, cl, **defaults): self.cl = cl self.defaults = defaults def __call__(self, *args, **kw): for key, value in self.defaults: if not kw.has_key(key): kw[key] = value return apply(self.cl, args, kw) Then you could do the same thing as above with: MyButton = Default(Button, fg="white", bg="red", font="-*-courier-bold-r-normal--14-*-*-*-*-*-*-*") a = MyButton(w, text="one") b = MyButton(w, text="two") c = MyButton(w, text="three") This is probably a cleaner way to do things. I haven't tried it, but it might be a nice thing to have in Tkinter. -- ?!ng From ping@lfw.org Fri Jan 28 04:36:49 2000 From: ping@lfw.org (Ka-Ping Yee) Date: Thu, 27 Jan 2000 20:36:49 -0800 (PST) Subject: [Python-Dev] Python 1.6 timing In-Reply-To: <14475.20080.508651.261991@bitdiddle.cnri.reston.va.us> Message-ID: On Sun, 23 Jan 2000, Jeremy Hylton wrote: > > I have discovered another approach. CNRI put in a cleam room on the > second floor last year. I recently discovered a little door behind > some metrology device in a corner of the clean room. The door opens > onto a tunnel that leads directly into Guido's mind. Unfortunately, > it won't be of much use for a pumpkin-holder or channeler, because > after about 15 minutes you are deposited on the shoulder of the Dulles > Toll Road. I almost fell out of my chair laughing when i read this. What do you think would happen if Guido went into the tunnel? Perhaps http://www.lfw.org/jminc/Guido/http://www.python.org/ (What you get is a generalization of some earlier silliness... the description of the original is at http://www.lfw.org/jminc/.) -- ?!ng From jim@digicool.com Fri Jan 28 15:02:12 2000 From: jim@digicool.com (Jim Fulton) Date: Fri, 28 Jan 2000 10:02:12 -0500 Subject: [Python-Dev] Multiple dicts for string interpolation? References: <200001260342.VAA10627@beluga.mojam.com> Message-ID: <3891AF74.1E81D7F8@digicool.com> Skip Montanaro wrote: > > Every once in awhile I want to perform string interpolation using more than > one dictionary. One way is to build a dictionary that's a union of multiple > dictionaries: > > dict = {} > dict.update(d1) > dict.update(d2) > ... > s = format % dict > > Another way is the MultiDict approach that Digital Creations (used to?) use > in their DocumentTemplate module (I can't remember the exact usage any > more): > > dict = MultiDict() > dict.append(d1) > dict.append(d2) Actually, push (and pop). The namspaces are managed as a stack. > ... > s = format % dict > > A MultiDict object maintains a list of the dicts it's been fed and searches > them in order when __getitem__ is called. > > I'd like to propose a third alternative. How about if the string > interpolation function accepted a tuple of dictionaries directly: > > s = format % (d1, d2) > > It would only be used when named interpolation was expected. I don't think > there would be any conflict with current % operator semantics. Yes. In the current semantics, you output the two dictionaries. Try: '%s %s' % ({'hello':'skip'},{}) Jim -- Jim Fulton mailto:jim@digicool.com Python Powered! Technical Director (888) 344-4332 http://www.python.org Digital Creations http://www.digicool.com http://www.zope.org Under US Code Title 47, Sec.227(b)(1)(C), Sec.227(a)(2)(B) This email address may not be added to any commercial mail list with out my permission. Violation of my privacy with advertising or SPAM will result in a suit for a MINIMUM of $500 damages/incident, $1500 for repeats. From jim@digicool.com Fri Jan 28 15:07:24 2000 From: jim@digicool.com (Jim Fulton) Date: Fri, 28 Jan 2000 10:07:24 -0500 Subject: [Python-Dev] Multiple dicts for string interpolation? References: Message-ID: <3891B0AC.D39275DF@digicool.com> Ken Manheimer wrote: > > On Tue, 25 Jan 2000, Skip Montanaro wrote: > > > Guido> Skip: > > >> I'd like to propose a third alternative. How about if the string > > >> interpolation function accepted a tuple of dictionaries directly: > > >> > > >> s = format % (d1, d2) > > [...] > > Guido> I think it depends on to what extent this is a common, useful > > Guido> idiom. Do you have evidence of that? Examples? > > > > Well, the first place I ran into it was in DocumentTemplates a few years > > ago. They used an idiom heavily which may have now been replaced by > > acquisition where you'd effectively push and pop value dicts onto a stack as > > you entered and exited nested blocks of DTML code. Their solution was a > > special dict-like object. > > Implementation of acquisition basically uses a MultiDict underneath. No it doesn't. Acquisition achieves combination of multiple namespaces in much the same way that inheritence does (through delagation). > Consider acquisition as a cumulative context composed from the containers > of the target of a web request. (Actually, a distinction is made between > the object containment hierarchy of the target and the successive > components of the path along which the target is reached by the request, > with the containment contexts taking precedence - but that's probably not > important here:-) Add in incidental things like the server environment > (from which you can get HTTP_REFERER and cookies and so forth). Each of > the components can be a dictionary or a MultiDict (or a sequence of pairs, > i think), and they're ultimately composed in a MultiDict. > > I think another place in zope where multidicts play prominently is in the > security mechanism, where any object can have local roles, and the > ultimate role of a user within a context is composed from the union across > the containment hierarchy. There probably are lots of other places where > multidicts are used. Acquisition plays a role in security, but MultiDicts-like things are not used. > Suffice to say that there's a lot of composing of contexts that goes on in > Zope in general, acquistion being a prime example but not the only one, > and multidicts play heavily in many. I would be surprised if this need to > combine contexts is peculiar to web server, or general server > applications. > > > [...] > > It's not a big deal. If it seems too obscure the other obvious solutions > > are not gruesome. > > I suppose we'd be pretty happy to have something like MultiDict as part of > python... Note that Zope actually uses two separate flavors. The one used most in Zope (in DocumentTemplate) has very specific hooks to work with Zope's security machinery. Jim -- Jim Fulton mailto:jim@digicool.com Python Powered! Technical Director (888) 344-4332 http://www.python.org Digital Creations http://www.digicool.com http://www.zope.org Under US Code Title 47, Sec.227(b)(1)(C), Sec.227(a)(2)(B) This email address may not be added to any commercial mail list with out my permission. Violation of my privacy with advertising or SPAM will result in a suit for a MINIMUM of $500 damages/incident, $1500 for repeats. From jim@digicool.com Fri Jan 28 15:10:26 2000 From: jim@digicool.com (Jim Fulton) Date: Fri, 28 Jan 2000 10:10:26 -0500 Subject: [Python-Dev] Multiple dicts for string interpolation? References: <000101bf67bf$b103e460$592d153f@tim> Message-ID: <3891B162.554622E2@digicool.com> Tim Peters wrote: > (snip) > I wasn't aware of the MultiDict approach Skip mentioned, See the MultiMapping module in ExtensionClass. You can get the latest flavor of this in the latest Zope release. > but thought it > looked spot on for the general case! Skip, is the long-windedness of > > dict = MultiDict() > dict.append(d1) > dict.append(d2) > ... > s = format % dict Note the rather important *stack* sematics of MultiMappings. We often push and pop namespaces on and off of MultiMappings in use. > the part you didn't like about that? If so, how about changing the > constructor to > > def __init__(self, *dicts): > ... > > instead so you could use it as a one-liner > > format % MultiDict(d1, d2, ...) > > ? That's exactly the same as the tuple idea, except there's a nice > descriptive word in the middle of it . This is exactly what the current MultiMapping "class" does. Jim -- Jim Fulton mailto:jim@digicool.com Python Powered! Technical Director (888) 344-4332 http://www.python.org Digital Creations http://www.digicool.com http://www.zope.org Under US Code Title 47, Sec.227(b)(1)(C), Sec.227(a)(2)(B) This email address may not be added to any commercial mail list with out my permission. Violation of my privacy with advertising or SPAM will result in a suit for a MINIMUM of $500 damages/incident, $1500 for repeats. From gward@cnri.reston.va.us Fri Jan 28 16:39:54 2000 From: gward@cnri.reston.va.us (Greg Ward) Date: Fri, 28 Jan 2000 11:39:54 -0500 Subject: [Python-Dev] To-do for Distutils 0.2 (and beyond) Message-ID: <20000128113954.A12965@cnri.reston.va.us> Hi all -- [oops: I *said* that I was cc'ing this to python-dev when I posted it to distutils-sig, but I just plain forgot to. So here it is again, still presumed relevant to python-dev'ers because it directly affects the planned Python 1.6 feature set. Please reply either to me directly or to distutils-sig, because that's where the implementation will be done.] recent developments in the planned release schedule for Python 1.6 (Guido doesn't want to wait for everything planned, but get something out the door in the next couple of months) are lighting a fire under me to get a seriously usable version of Distutils ready *really* soon now. This will be Distutils 0.2; I anticipate that 0.2.x will be included in Python 1.6, where x is the number of attempts it takes me to get something reasonably bug-free out the door. Those if you who were at the Python Conference this past week will have seen bits and pieces of my "laundry list" of desired features that should be added to the Distutils at some point in the future. Given the shortened schedule, it looks like it's necessary to do some pruning and concentrate on the essentials to get something in Python 1.6. So, here is my current laundry list, sorted into a couple of categories: essential for 0.2 (Python 1.6) ----------------- * fix the "dist" command (two-phase manifest, better feedback) (steal ideas and hopefully code from Gordon Macmillan's installer) * fix the "install" command (have the right interface and do the right thing for installating to non-standard or personal directories) * fix some bad nomenclature in the command classes (most likely 'options' -> 'user_options', 'set_default_options()' -> 'initialize_options()', and 'set_final_options()' -> ??? (maybe 'finalize_options()'?)) * build C libraries (for PIL, and other similar distributions) * documentation (two small manuals that should become standard Python manuals: "Installing Python Modules" and "Developing and Distributing Python Modules") * add a bdist command; should at least be able to generate dumb archives of built distributions (eg. a tarball that you unpack from /usr/local, or maybe /usr/local/lib/python1.5/site-packages) desirable for 0.2 ----------------- * "what's installed" database * dependency checking ("is version 1.3 of foo installed?") * don't automatically clobber an existing installation -- confirm, or require a "force" option, or something * command to install C headers (assuming more extensions than NumPy need to do this) put off to 0.3 (Python 1.7?) ---------------------------- * JPython support (most importantly, know where to install .py modules when run from JPython and be able to build Java extensions for JPython) * build static Python binary (for shared-library-challenged OSs) * SWIG support (mainly, know how to run it before building the C extension it generates) * PyFort support (ditto) * Mac support * allow overlapping multi-architecture installations (Michel Sanner's pet peeve and Guido's nightmare ;-) (this would *not* be the default; it would have to be explicitly chosen by brave/cheap/foolhardy installers) * support for archive sites (Parnassus) to pull out meta-info Anyone feel strongly about moving any of these items around, or discarding any entirely, or adding anything? Please let me know by email; I'll summarize to the list. Thanks -- Greg From jeremy@cnri.reston.va.us Fri Jan 28 23:52:53 2000 From: jeremy@cnri.reston.va.us (Jeremy Hylton) Date: Fri, 28 Jan 2000 18:52:53 -0500 (EST) Subject: [Python-Dev] To-do for Distutils 0.2 (and beyond) In-Reply-To: <20000128113954.A12965@cnri.reston.va.us> References: <20000128113954.A12965@cnri.reston.va.us> Message-ID: <14482.11221.451866.695357@bitdiddle.cnri.reston.va.us> >>>>> "GW" == Greg Ward writes: GW> desirable for 0.2 GW> ----------------- GW> * "what's installed" database GW> * dependency checking ("is version 1.3 of foo installed?") These are *not* desirable for version 0.2. Paul Dubois expressed some concern about the complexity of these tasks. I agree completely. I think the chances of getting this done correctly in the next month are slim to none. Don't waste your time adding the kitchen sink to distutils :-); just bang on the simple stuff until it's rock solid. Jeremy From jim@digicool.com Sat Jan 29 01:40:22 2000 From: jim@digicool.com (Jim Fulton) Date: Fri, 28 Jan 2000 20:40:22 -0500 Subject: [Python-Dev] Multiple dicts for string interpolation? References: <200001260413.XAA02813@eric.cnri.reston.va.us> <000101bf67bf$b103e460$592d153f@tim> <14479.1265.213769.810138@beluga.mojam.com> Message-ID: <38924506.808D34F5@digicool.com> Skip Montanaro wrote: > (snip) > I guess the next question is to extend Ken's comment about getting it into > the Python core. Would that be something possible for 1.6? I used a Python > version of MultiMapping in an ancient version of DocumentTemplate. I'm sure > the C version has been around for at least two or three years and would > appear pretty darn stable, Yes. I'm sure you'd have to de-ExtensionClass-ify it to get it into the core. :) > since it seems to be at the core of a lot of > Zope's coolness. Actually, it isn't, as there is a separate similar thing (TemplateDict) used in DocumentTemplate. Jim -- Jim Fulton mailto:jim@digicool.com Python Powered! Technical Director (888) 344-4332 http://www.python.org Digital Creations http://www.digicool.com http://www.zope.org Under US Code Title 47, Sec.227(b)(1)(C), Sec.227(a)(2)(B) This email address may not be added to any commercial mail list with out my permission. Violation of my privacy with advertising or SPAM will result in a suit for a MINIMUM of $500 damages/incident, $1500 for repeats. From guido@CNRI.Reston.VA.US Sun Jan 30 13:32:18 2000 From: guido@CNRI.Reston.VA.US (Guido van Rossum) Date: Sun, 30 Jan 2000 08:32:18 -0500 Subject: [Python-Dev] Adding C ternary select (a?b:c) to Python? Message-ID: <200001301332.IAA12252@eric.cnri.reston.va.us> Dear developers, Eric Raymond has sent me the following patch, which adds conditional expressions to Python. I'd like to hear opinions on whether this is a good thing to add to Python, and whether this is the right syntax. I am a bit skeptical about whether this is sufficiently Pythonic, but on the other hand there have always been requests for such a feature, and the existing solutions are ugly: a and b or c only works when you know for sure that b will never be false, and (a and [b] or [c])[0] is dead ugly... --Guido van Rossum (home page: http://www.python.org/~guido/) Subject: Ternary select -- here it is. From: "Eric S. Raymond" To: Guido Van Rossum Date: Sat, 29 Jan 2000 17:40:31 -0500 X-Eric-Conspiracy: There is no conspiracy Dang, Guido, this was *fun*! This patch extends the Python interpreter to support the C ternary operator, and documents the extension in the Reference Manual. The implementation is dead simple and robust: it's adapted from the existing code for if statements, and adds or changes less than 70 lines of code all told. Diffs between last version checked in and current workfile(s): --- Grammar/Grammar 2000/01/28 17:10:18 1.1 +++ Grammar/Grammar 2000/01/29 22:14:05 @@ -61,7 +61,8 @@ except_clause: 'except' [test [',' test]] suite: simple_stmt | NEWLINE INDENT stmt+ DEDENT -test: and_test ('or' and_test)* | lambdef +test: bool_test ['?' bool_test ':' bool_test] +bool_test: and_test ('or' and_test)* | lambdef and_test: not_test ('and' not_test)* not_test: 'not' not_test | comparison comparison: expr (comp_op expr)* --- Include/token.h 2000/01/28 17:38:55 1.1 +++ Include/token.h 2000/01/29 01:27:00 @@ -74,10 +74,11 @@ #define LEFTSHIFT 34 #define RIGHTSHIFT 35 #define DOUBLESTAR 36 +#define QUERY 37 /* Don't forget to update the table _PyParser_TokenNames in tokenizer.c! */ -#define OP 37 -#define ERRORTOKEN 38 -#define N_TOKENS 39 +#define OP 38 +#define ERRORTOKEN 39 +#define N_TOKENS 34 /* Special definitions for cooperation with parser */ --- Modules/parsermodule.c 2000/01/28 18:03:27 1.1 +++ Modules/parsermodule.c 2000/01/29 22:13:45 @@ -945,6 +945,7 @@ #define validate_star(ch) validate_terminal(ch, STAR, "*") #define validate_vbar(ch) validate_terminal(ch, VBAR, "|") #define validate_doublestar(ch) validate_terminal(ch, DOUBLESTAR, "**") +#define validate_query(ch) validate_terminal(ch, QUERY, "?") #define validate_dot(ch) validate_terminal(ch, DOT, ".") #define validate_name(ch, str) validate_terminal(ch, NAME, str) @@ -963,7 +964,8 @@ VALIDATER(exec_stmt); VALIDATER(compound_stmt); VALIDATER(while); VALIDATER(for); VALIDATER(try); VALIDATER(except_clause); -VALIDATER(test); VALIDATER(and_test); +VALIDATER(test); +VALIDATER(bool_test); VALIDATER(and_test); VALIDATER(not_test); VALIDATER(comparison); VALIDATER(comp_op); VALIDATER(expr); VALIDATER(xor_expr); VALIDATER(and_expr); @@ -1829,12 +1831,34 @@ } /* validate_except_clause() */ +/* bool_test ( | bool_test ? bool_test ) + * + */ static int validate_test(tree) node *tree; { + if (!validate_ntype(tree, test)) + return 0; + else if (NCH(tree) == 1) + return(validate_bool_test(CHILD(tree, 0))); + else if (validate_numnodes(tree, 5, "expr")) + { + return validate_bool_test(CHILD(tree, 0)) + && validate_query(CHILD(tree, 1)) + && validate_bool_test(CHILD(tree, 2)) + && validate_colon(CHILD(tree, 3)) + && validate_bool_test(CHILD(tree, 4)); + } +} /* validate_test() */ + + +static int +validate_bool_test(tree) + node *tree; +{ int nch = NCH(tree); - int res = validate_ntype(tree, test) && is_odd(nch); + int res = validate_ntype(tree, bool_test) && is_odd(nch); if (res && (TYPE(CHILD(tree, 0)) == lambdef)) res = ((nch == 1) @@ -1848,7 +1872,7 @@ } return (res); -} /* validate_test() */ +} /* validate_bool_test() */ static int --- Parser/tokenizer.c 2000/01/28 17:37:48 1.1 +++ Parser/tokenizer.c 2000/01/29 01:27:26 @@ -99,6 +99,7 @@ "LEFTSHIFT", "RIGHTSHIFT", "DOUBLESTAR", + "QUERY", /* This table must match the #defines in token.h! */ "OP", "", @@ -384,6 +385,7 @@ case '}': return RBRACE; case '^': return CIRCUMFLEX; case '~': return TILDE; + case '?': return QUERY; default: return OP; } } --- Python/compile.c 2000/01/28 23:17:19 1.1 +++ Python/compile.c 2000/01/29 22:19:29 @@ -1698,11 +1698,11 @@ } static void -com_test(c, n) +com_bool_test(c, n) struct compiling *c; node *n; { - REQ(n, test); /* and_test ('or' and_test)* | lambdef */ + REQ(n, bool_test); /* and_test ('or' and_test)* | lambdef */ if (NCH(n) == 1 && TYPE(CHILD(n, 0)) == lambdef) { PyObject *v; int i; @@ -1738,6 +1738,32 @@ } static void +com_test(c, n) + struct compiling *c; + node *n; +{ + int op; + REQ(n, test); + com_bool_test(c, CHILD(n, 0)); + + /* is there a following ternary operator? */ + /* XXX optimize the compilation when the guard is a constant */ + if (NCH(n) == 5) + { + int anchor1 = 0, anchor2 = 0; + com_addfwref(c, JUMP_IF_FALSE, &anchor2); + com_addbyte(c, POP_TOP); + com_pop(c, 1); + com_node(c, CHILD(n, 2)); + com_addfwref(c, JUMP_FORWARD, &anchor1); + com_backpatch(c, anchor2); + com_addbyte(c, POP_TOP); + com_node(c, CHILD(n, 4)); + com_backpatch(c, anchor1); + } +} + +static void com_list(c, n, toplevel) struct compiling *c; node *n; @@ -2931,6 +2957,9 @@ break; case test: com_test(c, n); + break; + case bool_test: + com_bool_test(c, n); break; case and_test: com_and_test(c, n); --- Doc/ref/ref5.tex 2000/01/29 21:28:13 1.1 +++ Doc/ref/ref5.tex 2000/01/29 22:00:02 @@ -764,7 +764,7 @@ \section{Boolean operations\label{Booleans}} \indexii{Boolean}{operation} -Boolean operations have the lowest priority of all Python operations: +Boolean operations have the lowest priority of all Python binary operations: \begin{verbatim} expression: or_test | lambda_form @@ -832,6 +832,24 @@ def make_incrementor(increment): return lambda x, n=increment: x+n \end{verbatim} + +\section{Select\label{select}} +\index{select} + +The select operator is a ternary operator with lower priority than +boolean operations (and thus lower priority than all other binary and +unary operators). + +\begin{verbatim} +select_expr: xor_expr | xor_expr "?" xor_expr ":" xor_expr +\end{verbatim} + +If its first operand is nonempty, the value of a select operation is +its second operand; otherwise the value is the third operand. + +(The semantics and precedence level of select are intended to be +unsurprising to programmers familiar with \C's ternary select +operator.) \section{Expression lists\label{exprlists}} \indexii{expression}{list} End of diffs. -- Eric S. Raymond You know why there's a Second Amendment? In case the government fails to follow the first one. -- Rush Limbaugh, in a moment of unaccustomed profundity 17 Aug 1993 From jim@digicool.com Sun Jan 30 13:52:32 2000 From: jim@digicool.com (Jim Fulton) Date: Sun, 30 Jan 2000 08:52:32 -0500 Subject: [Python-Dev] Adding C ternary select (a?b:c) to Python? References: <200001301332.IAA12252@eric.cnri.reston.va.us> Message-ID: <38944220.3177B402@digicool.com> Guido van Rossum wrote: > > Dear developers, > > Eric Raymond has sent me the following patch, which adds conditional > expressions to Python. I'd like to hear opinions on whether this is a > good thing to add to Python, and whether this is the right syntax. Yee ha! I think that this is a great idea. I'm surprised that using the colon doesn't cause problems. I'm not a grammer lawyer, and don't care that much. I very much would like to see a conditional expression. I wouldn't object if it was spelled differently than C's. > I am a bit skeptical about whether this is sufficiently Pythonic, but > on the other hand there have always been requests for such a feature, > and the existing solutions are ugly: > > a and b or c > > only works when you know for sure that b will never be false, and > > (a and [b] or [c])[0] > > is dead ugly... Yup. (a and (b,) or (c,))[0] is even worse. ;) Jim -- Jim Fulton mailto:jim@digicool.com Technical Director (888) 344-4332 Python Powered! Digital Creations http://www.digicool.com http://www.python.org Under US Code Title 47, Sec.227(b)(1)(C), Sec.227(a)(2)(B) This email address may not be added to any commercial mail list with out my permission. Violation of my privacy with advertising or SPAM will result in a suit for a MINIMUM of $500 damages/incident, $1500 for repeats. From esr@thyrsus.com Sun Jan 30 15:59:42 2000 From: esr@thyrsus.com (Eric S. Raymond) Date: Sun, 30 Jan 2000 10:59:42 -0500 Subject: [Python-Dev] Adding C ternary select (a?b:c) to Python? In-Reply-To: <38944220.3177B402@digicool.com>; from Jim Fulton on Sun, Jan 30, 2000 at 08:52:32AM -0500 References: <200001301332.IAA12252@eric.cnri.reston.va.us> <38944220.3177B402@digicool.com> Message-ID: <20000130105941.A10861@thyrsus.com> Jim Fulton : > I'm surprised that using the colon doesn't cause problems. Pgen doesn't tag this ambiguous. The LL(1) traversal actually helps here; by the time you see a colon, you already know whether or not you're parsing a ternary telect. -- Eric S. Raymond Don't think of it as `gun control', think of it as `victim disarmament'. If we make enough laws, we can all be criminals. From guido@CNRI.Reston.VA.US Sun Jan 30 16:40:32 2000 From: guido@CNRI.Reston.VA.US (Guido van Rossum) Date: Sun, 30 Jan 2000 11:40:32 -0500 Subject: [Python-Dev] Adding C ternary select (a?b:c) to Python? In-Reply-To: Your message of "Sun, 30 Jan 2000 10:59:42 EST." <20000130105941.A10861@thyrsus.com> References: <200001301332.IAA12252@eric.cnri.reston.va.us> <38944220.3177B402@digicool.com> <20000130105941.A10861@thyrsus.com> Message-ID: <200001301640.LAA12598@eric.cnri.reston.va.us> > Jim Fulton : > > I'm surprised that using the colon doesn't cause problems. [ESR] > Pgen doesn't tag this ambiguous. The LL(1) traversal actually helps > here; by the time you see a colon, you already know whether or not you're > parsing a ternary telect. Interestingly, the very ad-hoc parsing that I described in the compiling/parsing session on devday would be hit by this... I was looking for a colon at nesting level zero. Serves me right for not using a real parse :-) --Guido van Rossum (home page: http://www.python.org/~guido/) From da@ski.org Sun Jan 30 18:07:51 2000 From: da@ski.org (David Ascher) Date: Sun, 30 Jan 2000 10:07:51 -0800 Subject: [Python-Dev] Adding C ternary select (a?b:c) to Python? References: <200001301332.IAA12252@eric.cnri.reston.va.us> <38944220.3177B402@digicool.com> <20000130105941.A10861@thyrsus.com> <200001301640.LAA12598@eric.cnri.reston.va.us> Message-ID: <004101bf6b4c$ed2ab9b0$0100000a@ski.org> FWIW, the lack of a ternary select is one of the frequently asked questions in my Python courses. It would make TomC happier as well. I'm not sure the latter is a feature. =) On the topic of aesthetics, the C syntax doesn't strike me as the ultimate in pythonicity but it's not too bad either. I can't think of an alternative that doesn't involve a new reserved word. --david From gvwilson@nevex.com Sun Jan 30 20:22:21 2000 From: gvwilson@nevex.com (gvwilson@nevex.com) Date: Sun, 30 Jan 2000 15:22:21 -0500 (EST) Subject: [Python-Dev] Eight suggestions for Python books Message-ID: I realize this is a bit off-topic, but based on discussions with various publishers over the last couple of years, and on conversations at the conference last week, I wrote up some notes on books that I think would help Python succeed, and posted them to comp.lang.python under the heading "Eight suggestions for Python books". Some of the books are specificially about Python, while others try to use Python to fill holes in the curriculum, and thereby get Python into colleges through the side door (in the same way that networking and computer graphics texts helped C become more popular). Hope it's useful... Greg From mal@lemburg.com Sun Jan 30 21:34:51 2000 From: mal@lemburg.com (M.-A. Lemburg) Date: Sun, 30 Jan 2000 22:34:51 +0100 Subject: [Python-Dev] Adding C ternary select (a?b:c) to Python? References: <200001301332.IAA12252@eric.cnri.reston.va.us> Message-ID: <3894AE7A.BE89D9B4@lemburg.com> > --- Include/token.h 2000/01/28 17:38:55 1.1 > +++ Include/token.h 2000/01/29 01:27:00 > @@ -74,10 +74,11 @@ > #define LEFTSHIFT 34 > #define RIGHTSHIFT 35 > #define DOUBLESTAR 36 > +#define QUERY 37 > /* Don't forget to update the table _PyParser_TokenNames in tokenizer.c! */ > -#define OP 37 > -#define ERRORTOKEN 38 > -#define N_TOKENS 39 > +#define OP 38 > +#define ERRORTOKEN 39 > +#define N_TOKENS 34 Shouldn't this read #define N_TOKENS 40 ?! Apart from that I wouldn't mind having this patch in the core :-) -- Marc-Andre Lemburg ______________________________________________________________________ Business: http://www.lemburg.com/ Python Pages: http://www.lemburg.com/python/ From tim_one@email.msn.com Sun Jan 30 23:25:30 2000 From: tim_one@email.msn.com (Tim Peters) Date: Sun, 30 Jan 2000 18:25:30 -0500 Subject: [Python-Dev] Adding C ternary select (a?b:c) to Python? In-Reply-To: <200001301332.IAA12252@eric.cnri.reston.va.us> Message-ID: <000301bf6b79$4f0c8a60$482d153f@tim> [Guido van Rossum] > Eric Raymond has sent me the following patch, which adds conditional > expressions to Python. I'd like to hear opinions on whether this > is a good thing to add to Python, Marginal; not evil, but of minor utility. > and whether this is the right syntax. If and only if you were a C programmer first. BTW, insert s where needed throughout . > I am a bit skeptical about whether this is sufficiently Pythonic, > but on the other hand there have always been requests for such a > feature, There have always been requests for the union of all features from all other languages. > and the existing solutions are ugly: > > a and b or c > > only works when you know for sure that b will never be false, Too error prone. > and > > (a and [b] or [c])[0] > > is dead ugly... Well, I'm the guy who invented that one! The thread that spawned it was just playfully wondering whether it was *possible* -- and if I didn't solve it, Majewski would have using even uglier __xxx__ trickery. I've never used it in a real program, and shoot people who do. So there is no reasonable way to spell ?: as a one-liner today, period. The question is whether that's "a lack" worth doing something about. I can live without it. Surprised that Jim (Fulton) seems so keen on it: his cPickle.c uses ?: exactly once in 4400 lines of C, and in a line that would have been clearer if C had a max function (or is it min? it can take a while to reverse-engineer the intent of a ?:! ... not good when it happens; and I recall one of the contributed patches that went into 1.5.2 longobject.c, that had Guido & I both cracking a C manual just to figure out how C would *parse* a particularly nutso blob of nested ?: thingies). If this goes in (I'm not deadly opposed, just more opposed than in favor), I'd like to see "else" used instead of the colon (cond "?" true "else" false). The question mark is reasonably mnemonic, but a colon makes no sense here. Now let's see whether people really want the functionality or are just addicted to C syntax . BTW, a number of other changes would be needed to the Lang Ref manual (e.g., section 2.6 (Delimeters) explicitly says that "?" isn't used in Python today, and that its appeareance outside a string literal or comment is "an unconditional error"; etc). crabby-old-man-ly y'rs - tim From esr@thyrsus.com Sun Jan 30 23:43:17 2000 From: esr@thyrsus.com (Eric S. Raymond) Date: Sun, 30 Jan 2000 18:43:17 -0500 Subject: [Python-Dev] Adding C ternary select (a?b:c) to Python? In-Reply-To: <000301bf6b79$4f0c8a60$482d153f@tim>; from Tim Peters on Sun, Jan 30, 2000 at 06:25:30PM -0500 References: <200001301332.IAA12252@eric.cnri.reston.va.us> <000301bf6b79$4f0c8a60$482d153f@tim> Message-ID: <20000130184317.A12833@thyrsus.com> Tim Peters : > If this goes in (I'm not deadly opposed, just more opposed than in favor), > I'd like to see "else" used instead of the colon (cond "?" true "else" > false). The question mark is reasonably mnemonic, but a colon makes no > sense here. I have to say that I think any ternary syntax that mixes a single-character operator with a keyword would be intolerably ugly. > Now let's see whether people really want the functionality or are just > addicted to C syntax . It's not that simple. People clearly want the functionality; we've seen ample evidence of that. Given that, I think the presumption has to be in favor of using the familiar C syntax rather than an invention that would necessarily be more obscure. > BTW, a number of other changes would be needed to the Lang Ref manual (e.g., > section 2.6 (Delimeters) explicitly says that "?" isn't used in Python > today, and that its appeareance outside a string literal or comment is "an > unconditional error"; etc). I'm certainly willing to fix that. -- Eric S. Raymond [The disarming of citizens] has a double effect, it palsies the hand and brutalizes the mind: a habitual disuse of physical forces totally destroys the moral [force]; and men lose at once the power of protecting themselves, and of discerning the cause of their oppression. -- Joel Barlow, "Advice to the Privileged Orders", 1792-93 From dascher@mindspring.com Mon Jan 31 00:09:39 2000 From: dascher@mindspring.com (David Ascher) Date: Sun, 30 Jan 2000 16:09:39 -0800 Subject: [Python-Dev] Adding C ternary select (a?b:c) to Python? References: <200001301332.IAA12252@eric.cnri.reston.va.us> <000301bf6b79$4f0c8a60$482d153f@tim> <20000130184317.A12833@thyrsus.com> Message-ID: <005c01bf6b7f$7a3a8f60$0100000a@ski.org> > > Now let's see whether people really want the functionality or are just > > addicted to C syntax . > > It's not that simple. People clearly want the functionality; we've > seen ample evidence of that. I personally haven't been stunned by the ample evidence you mention. While folks do ask about the ternary select periodically in classes and on the net, none of my students at least are especially upset when I point out the readability of: if a: b = c else: b = d > Given that, I think the presumption has > to be in favor of using the familiar C syntax rather than an invention > that would necessarily be more obscure. The presumption from the language design point of view is to do what's right regardless of language background, not what's in C -- when Guido remembered that, he chose 'and' and 'or' over '&&' and '||'. When Guido forgot that, he chose integer division =). While all of the folks on this list are comfortable with C, I can point out that a (possibly surprisingly) large proportion of the Python programmers I have taught have never used C or never felt comfortable with it. If CP4E succeeds, that proportion will grow, not shrink. I do think that taking a page from Randy Pausch would be a good idea in this case. My guess is that english words would emerge from trying to teach non-programmers the concept, but I of course don't have data on the topic. I wonder how high-school teachers teach the hook-colon in C intro classes, specifically what _words_ they use. Those words might lead to alternative syntaxes. Finally, something at the edge of my brain is trying to combine the logic of the ternary select (which is clearly related to control flow) and a more generalized switch statement. But I'm not seeing anything syntactically appealing at present. That said, the hook-colon syntax is appealing from a release management perspective because it fits within the current set of reserved words and clearly isn't the hardest concept to teach. --david From petrilli@amber.org Mon Jan 31 00:54:06 2000 From: petrilli@amber.org (Christopher Petrilli) Date: Sun, 30 Jan 2000 19:54:06 -0500 Subject: [Python-Dev] Adding C ternary select (a?b:c) to Python? In-Reply-To: <005c01bf6b7f$7a3a8f60$0100000a@ski.org>; from dascher@mindspring.com on Sun, Jan 30, 2000 at 04:09:39PM -0800 References: <200001301332.IAA12252@eric.cnri.reston.va.us> <000301bf6b79$4f0c8a60$482d153f@tim> <20000130184317.A12833@thyrsus.com> <005c01bf6b7f$7a3a8f60$0100000a@ski.org> Message-ID: <20000130195406.A25682@trump.amber.org> The question comes from what "problem" you're trying to solve. The ?: syntax does not introduce any new "functionality" to the language, nor does it make it capable of solving problems or requirements that it can not do at the current time. The second qustion I'd ask is, who is this aimed at? It's certainly not aimed at first-time programmers, as I know from experience that the ?: is one of the hardest things to teach people in C (after pointers), and often I leave it out of training when I did it. It's simply a "shorthand" not a new functionality. If its aimed at experienced programmers, I'd argue that it's at best "non-pythonic" and at worst a hack, taken from a language in which it exposes the "macro assembler" approach. Python is not a language that has been optimized for "minimal typing", it's much more verbose than most languages, and so that argument shouldn' be applied. Perhaps it's for optimization? That was I believe the original argument made for it in K&R, in that optimizers in that day were rather antiquated, wheras today, I believe that any C compiler would get it right if it were expressed in its full form. (Timbot?) So, it comes down to a few questions for me: Does it solve a new problem? No Is it pythonic? No Does it make it faster? No Given Pyton's CP4E goals, and its general place as an easy to use language, I'd argue this patch would be counter to all of those goals. Sorry if I pushed someone's buton, but... I saw a lot of hints at making Python MUCH more complex, which is counter to why I changed and dropped many other languags. Chris -- | Christopher Petrilli | petrilli@amber.org From tim_one@email.msn.com Mon Jan 31 00:44:34 2000 From: tim_one@email.msn.com (Tim Peters) Date: Sun, 30 Jan 2000 19:44:34 -0500 Subject: [Python-Dev] Adding C ternary select (a?b:c) to Python? In-Reply-To: <20000130184317.A12833@thyrsus.com> Message-ID: <000801bf6b84$588c2d60$482d153f@tim> [Tim, tosses off cond "?" true "else" false in apparent hatred of colons] [Eric S. Raymond] > I have to say that I think any ternary syntax that mixes a > single-character operator with a keyword would be intolerably ugly. It's certainly not attractive . Guido is the Master of Syntax; if he decides the functionality is Pythonic, he'll dream up a good Pythonic syntax. I'll refrain from suggesting "if" cond "lambda" true "else" false . >> Now let's see whether people really want the functionality or are just >> addicted to C syntax . > It's not that simple. People clearly want the functionality; we've > seen ample evidence of that. I have not. Really! This has been debated for nearly a decade, with no consensus (the invention of the (a and [b] or [c])[0] atrocity predates c.l.py!). *Some* people certainly want ?: (or equivalent) a lot; but others are equally opposed. Note that lack of ?: didn't have enough of a constituency in Andrew Kuchling's eyes either to make his original "Python Warts" paper, or its revisions: http://starship.python.net/crew/amk/python/writing/warts.html No change ever proposed has failed to attract vocal & persistent supporters, so it's not as simple as *that* either <0.5 wink>. > Given that, I think the presumption has to be in favor of using the > familiar C syntax rather than an invention that would necessarily be > more obscure. By count, I'm sure many more languages (from virtually all functional languages to Icon) use "if cond then true else false" for this purpose; obscurity is relative to your background. At least "if x then y else z" is clear on the face of it (which may betray my background ). "then" has no chance of getting into Python1, though. My core objection is that ?: doesn't "look pretty": it's not at all suggestive of what it means, and the effects on precedence and associativity are unattractive ("see C, copy C" is the only sense there is to it, and rules for ?: are-- as I noted last time --obscure). Good syntax counts for a lot in Python -- which is why it doesn't look like C now. Get a good syntax, and most of my objections vanish; I don't have a good syntax to suggest, though. passing-the-ball-back-to-guido-where-he-always-knew-it- would-land-ly y'rs - tim From esr@thyrsus.com Mon Jan 31 01:07:11 2000 From: esr@thyrsus.com (Eric S. Raymond) Date: Sun, 30 Jan 2000 20:07:11 -0500 Subject: [Python-Dev] Adding C ternary select (a?b:c) to Python? In-Reply-To: <20000130195406.A25682@trump.amber.org>; from Christopher Petrilli on Sun, Jan 30, 2000 at 07:54:06PM -0500 References: <200001301332.IAA12252@eric.cnri.reston.va.us> <000301bf6b79$4f0c8a60$482d153f@tim> <20000130184317.A12833@thyrsus.com> <005c01bf6b7f$7a3a8f60$0100000a@ski.org> <20000130195406.A25682@trump.amber.org> Message-ID: <20000130200711.A13063@thyrsus.com> Christopher Petrilli : > The question comes from what "problem" you're trying to solve. The ?: syntax > does not introduce any new "functionality" to the language, nor does it > make it capable of solving problems or requirements that it can not do > at the current time. Well, in a theoretical sense, you're right. But then, even troff macros and INTERCAL are Turing-complete . One of the lessons of Python to this old LISPer is that *notation matters*. Theoretically, Python is a subset of Scheme-with-objects using a vaguely C-like surface notation. But even I would rather write a for-loop than the equivalent recursion. That's why I code in Python now instead of trying to rescue LISP from its desuetitude. So while it is *theoretically* true that ?: adds nothing, it is *practically* true that it enables a large class of idioms that can't otherwise be comfortably expressed. That matters. Now, you can argue that the complexity ?: adds to language is not paid for by the additional convenience; I disagree, but that's at least a defensible argument. But simply saying it "adds nothing to the language" is a red herring -- neither do many of the other base language features. Why, for example, do we have more than one kind of loop construct? Unecessary. Wasteful. Clearly either "for" or "while" must go. As an exercise, try editing your complaint so that it refers to "for" everywhere it now refers to ?:. Contemplate the edited version until you achieve enlightenment ;-). -- Eric S. Raymond The same applies for other kinds of long-lasting low-level pain. [...] The body's response to being jabbed, pierced, and cut is to produce endorphins. [...] So here's my programme for breaking that cycle of dependency on Windows: get left arm tattooed with dragon motif, buy a crate of Jamaican Hot! Pepper Sauce, get nipples pierced. With any luck that will produce enough endorphins to make Windows completely redundant, and I can then upgrade to Linux and get on with things. -- Pieter Hintjens From ping@lfw.org Mon Jan 31 01:29:43 2000 From: ping@lfw.org (Ka-Ping Yee) Date: Sun, 30 Jan 2000 19:29:43 -0600 (EST) Subject: [Python-Dev] Adding C ternary select (a?b:c) to Python? In-Reply-To: <000301bf6b79$4f0c8a60$482d153f@tim> Message-ID: On Sun, 30 Jan 2000, Tim Peters wrote: > If this goes in (I'm not deadly opposed, just more opposed than in favor), > I'd like to see "else" used instead of the colon (cond "?" true "else" > false). The question mark is reasonably mnemonic, but a colon makes no > sense here. I agree with that sentiment (along the lines of the philosophy that chose "and" over "&&"), and it seems to me that it makes the most sense to use words for both: a = x > 0 then x else -x I don't have the time to do it right this second, but i suggest that a scan through a decent chunk of Python would be useful to find out how often this construct (in its "and"/"or" incarnation) actually gets used. I promise to give it a try as soon as i get my notebook battery charged up again. -- ?!ng From tim_one@email.msn.com Mon Jan 31 02:41:59 2000 From: tim_one@email.msn.com (Tim Peters) Date: Sun, 30 Jan 2000 21:41:59 -0500 Subject: [Python-Dev] Adding C ternary select (a?b:c) to Python? In-Reply-To: <20000130195406.A25682@trump.amber.org> Message-ID: <000201bf6b94$bfabc360$ee2d153f@tim> [Christopher Petrilli] > ... > Python is not a language that has been optimized for "minimal > typing", it's much more verbose than most languages, and so that > argument shouldn't be applied. Concise expression of common concepts is a Good Thing, though, and there's nothing inherently evil about wanting one of two outcomes . My impression is that the people historically most in favor of ?: ("or something like it") are also the ones most strongly in favor of embedded assignment ("or something like it"), and I can't *dismiss* either gripe. The Python while 1: x = something_or_other() if not x: break consume(x) idiom is truly grating at first -- more so than the multi-line ?: alternatives, in my eyes. > Perhaps it's for optimization? That was I believe the original > argument made for it in K&R, in that optimizers in that day were rather > antiquated, wheras today, I believe that any C compiler would get it > right if it were expressed in its full form. (Timbot?) Indeed, a couple weeks ago we tracked down a "mysterious slowdown" of our core speech recognizer to a particular compiler failing to optimize *unless* we changed a ?: into a long winded if/else! There's really nothing you can say about "any C compiler" -- optimization is much more a black art than anyone in that business will admit to in public <0.9 wink>. C was definitely designed with "by hand" optimization in mind, and, ironically, it's those features (particularly pointer aliasing) that make it harder for compilers to optimize than is, say, Fortran. But regardless of origin, ?: stands or falls on its other merits now. Python's own implementation uses it often enough, and to good effect. So it can't be that Guido hates the idea . It's just hard to love the syntax. > So, it comes down to a few questions for me: > > Does it solve a new problem? No > Is it pythonic? No > Does it make it faster? No Would a nice syntax allow clearer expression of some common computations? Probably yes. That's the same basis on which, e.g., list.pop and list.extend and dict.get and 3-argument getattr and ... were adopted. "Faster" applied to those too, but nobody pushed for 'em on that basis. Clearer! That's what really matters. It's the same argument for list comprehensions too. > ... > Sorry if I pushed someone's buton, but... I saw a lot of hints at making > Python MUCH more complex, which is counter to why I changed and dropped > many other languags. A good antitode to feature panic is reviewing Misc/HISTORY: Guido's willingness to entertain suggestions far exceeds his willingness to adopt them . it-would-be-different-if-features-were-just-as-easy-to- take-out-ly y'rs - tim From tismer@tismer.com Mon Jan 31 11:46:50 2000 From: tismer@tismer.com (Christian Tismer) Date: Mon, 31 Jan 2000 12:46:50 +0100 Subject: [Python-Dev] Adding C ternary select (a?b:c) to Python? References: Message-ID: <3895762A.C1706E8@tismer.com> Ka-Ping Yee wrote: > > On Sun, 30 Jan 2000, Tim Peters wrote: > > If this goes in (I'm not deadly opposed, just more opposed than in favor), > > I'd like to see "else" used instead of the colon (cond "?" true "else" > > false). The question mark is reasonably mnemonic, but a colon makes no > > sense here. > > I agree with that sentiment (along the lines of the philosophy that > chose "and" over "&&"), and it seems to me that it makes the most sense > to use words for both: > > a = x > 0 then x else -x I would favorise this as well instead of using ?: . Maybe it would make sense to be even more verbose and use an "if" as well? a = if x > 0 then x else -x sign = lambda x: if x > 0 then 1 elif x then -1 else 0 ciao - chris -- Christian Tismer :^) Applied Biometrics GmbH : Have a break! Take a ride on Python's Düppelstr. 31 : *Starship* http://starship.python.net 12163 Berlin : PGP key -> http://wwwkeys.pgp.net PGP Fingerprint E182 71C7 1A9D 66E9 9D15 D3CC D4D7 93E2 1FAE F6DF we're tired of banana software - shipped green, ripens at home From gward@cnri.reston.va.us Mon Jan 31 14:15:08 2000 From: gward@cnri.reston.va.us (Greg Ward) Date: Mon, 31 Jan 2000 09:15:08 -0500 Subject: [Python-Dev] Adding C ternary select (a?b:c) to Python? In-Reply-To: ; from ping@lfw.org on Sun, Jan 30, 2000 at 07:29:43PM -0600 References: <000301bf6b79$4f0c8a60$482d153f@tim> Message-ID: <20000131091507.A17073@cnri.reston.va.us> On 30 January 2000, Ka-Ping Yee said: > On Sun, 30 Jan 2000, Tim Peters wrote: > > If this goes in (I'm not deadly opposed, just more opposed than in favor), > > I'd like to see "else" used instead of the colon (cond "?" true "else" > > false). The question mark is reasonably mnemonic, but a colon makes no > > sense here. > > I agree with that sentiment (along the lines of the philosophy that > chose "and" over "&&"), and it seems to me that it makes the most sense > to use words for both: > > a = x > 0 then x else -x Yeah, I agree with Tim: it's a handy feature and I frequently wish I could do simple conditional assignment without resorting to a full-blown if/else. (I think I stumbled across "a and b or c" myself -- either that or it was suggested by *Learning Python*, but lay dormant in my subconscious for several months -- which means that I missed the "b must always be true" subtlety until it bit me. Ouch. I avoid that idiom now.) BUT the C line-noise syntax is not appropriate. It's fine in C, and it's eminently appropriate in Perl -- both languages designed to minimise wear-and-tear of programmers' keyboards. But keyboards are cheap nowadays, so perhaps we can be a bit more profligate with them. I find Ping's proposed syntax intriguing. Personally, I've always been partial to the x = if a then b else c syntax, even though I don't think I've ever used a language that includes it. (Oh wait, the toy ALGOL-knockoff that we used in Intro to Compilers had it, so I *have* written a parser and simplistic code generator for a language that includes it. Perhaps that's why I like it...) But either of these -- ie. elevate "then" to keywordhood, with or without "if", and no colons to be seen -- smell like they would play havoc with Python's grammar. And they turn a statement keyword "if" into an expression keyword. Not being at all familiar with Python's parser, I should just shut up now, but it feels tricky. And of course, any proposed syntax changes nowadays have to take JPython into account. Greg From guido@CNRI.Reston.VA.US Mon Jan 31 14:36:52 2000 From: guido@CNRI.Reston.VA.US (Guido van Rossum) Date: Mon, 31 Jan 2000 09:36:52 -0500 Subject: [Python-Dev] Adding C ternary select (a?b:c) to Python? In-Reply-To: Your message of "Mon, 31 Jan 2000 09:15:08 EST." <20000131091507.A17073@cnri.reston.va.us> References: <000301bf6b79$4f0c8a60$482d153f@tim> <20000131091507.A17073@cnri.reston.va.us> Message-ID: <200001311436.JAA15213@eric.cnri.reston.va.us> > I find Ping's proposed syntax intriguing. Personally, I've always been > partial to the > > x = if a then b else c > > syntax, even though I don't think I've ever used a language that > includes it. (Oh wait, the toy ALGOL-knockoff that we used in Intro to > Compilers had it, so I *have* written a parser and simplistic code > generator for a language that includes it. Perhaps that's why I like > it...) Yes, this was in original Algol 60 and, by magic of a completely different kind, again in Algol 68 (which was a completely different language, and the Mount Everest of languages). > But either of these -- ie. elevate "then" to keywordhood, with or > without "if", and no colons to be seen -- smell like they would play > havoc with Python's grammar. And they turn a statement keyword "if" > into an expression keyword. Not being at all familiar with Python's > parser, I should just shut up now, but it feels tricky. The solution can be the same as what Algol used: 'if' outside parentheses is a statement, and inside parentheses is an expression. It's a bit of a grammar rearrangement, but totally unambiguous. However, the added keyword means it won't be in 1.6. The lively discussion means that Eric's patch will have a hard time getting in too... --Guido van Rossum (home page: http://www.python.org/~guido/) From jim@digicool.com Mon Jan 31 15:04:45 2000 From: jim@digicool.com (Jim Fulton) Date: Mon, 31 Jan 2000 10:04:45 -0500 Subject: [Python-Dev] Adding C ternary select (a?b:c) to Python? References: <200001301332.IAA12252@eric.cnri.reston.va.us> <000301bf6b79$4f0c8a60$482d153f@tim> <20000130184317.A12833@thyrsus.com> <005c01bf6b7f$7a3a8f60$0100000a@ski.org> <20000130195406.A25682@trump.amber.org> Message-ID: <3895A48D.F69B3DFA@digicool.com> Christopher Petrilli wrote: > > The question comes from what "problem" you're trying to solve. It would allow you to incorporate logic into expressions. There are contexts where only expressions are allowed, such as: - lambdas - DTML expr attributes in which I'd very much like to incorporate tests. > The ?: syntax > does not introduce any new "functionality" to the language, Yes it does. > nor does it > make it capable of solving problems or requirements that it can not do > at the current time. Ditto. > The second qustion I'd ask is, who is this aimed at? It's certainly not > aimed at first-time programmers, as I know from experience that the ?: > is one of the hardest things to teach people in C (after pointers), Hm. I can't agree. Smalltalk, came out of an essentially CP4E effort two decades ago at Xerox PARC. Smalltalk *only* had conditional expressions. The message: [condition] ifTrue: [do something ...] ifFalse: [do something else ...] is an expression in Smalltalk. > and > often I leave it out of training when I did it. It's simply a "shorthand" > not a new functionality. No, it allows testing in expressions. > If its aimed at experienced programmers, I'd > argue that it's at best "non-pythonic" and at worst a hack, taken from > a language in which it exposes the "macro assembler" approach. I don't agree. > Python is not a language that has been optimized for "minimal typing", That's not the issue. > it's > much more verbose than most languages, and so that argument shouldn' be > applied. Perhaps it's for optimization? That was I believe the original > argument made for it in K&R, in that optimizers in that day were rather > antiquated, wheras today, I believe that any C compiler would get it > right if it were expressed in its full form. (Timbot?) > > So, it comes down to a few questions for me: > > Does it solve a new problem? No Yes. > Is it pythonic? No Pythonicity is relative. > Does it make it faster? No Who cares? Jim -- Jim Fulton mailto:jim@digicool.com Python Powered! Technical Director (888) 344-4332 http://www.python.org Digital Creations http://www.digicool.com http://www.zope.org Under US Code Title 47, Sec.227(b)(1)(C), Sec.227(a)(2)(B) This email address may not be added to any commercial mail list with out my permission. Violation of my privacy with advertising or SPAM will result in a suit for a MINIMUM of $500 damages/incident, $1500 for repeats. From tismer@tismer.com Mon Jan 31 15:59:15 2000 From: tismer@tismer.com (Christian Tismer) Date: Mon, 31 Jan 2000 16:59:15 +0100 Subject: [Python-Dev] Riskless deletion of nested structures Message-ID: <3895B153.3D2E763D@tismer.com> This is a multi-part message in MIME format. --------------D9F780CECED602EF245D7526 Content-Type: text/plain; charset=iso-8859-1 Content-Transfer-Encoding: 8bit Howdy, Please review! While implementing Stackless Python, a new problem arose: Nested structures like frame chains and tracebacks can now easily grow somuch that they cause a stack overflow on deallocation. To protect lists, tuples, frames, dicts and tracebacks against this, I wrote a stackless deallocator. At the moment, everything is done in trashcan.c . This gives a slight performance loss of 5% for pystone, most probably due to the double indirection and non-local code reference. It is yet a hack, since I'm grabbing the tp->dealloc pointers of these types and replace them by safe versions. This just in order to try out things quickly. Later I will change this and incorporate the stack checks into the affected modules, after I got some feedback on this. This patch applies to Stackless and standard Python as well: Deallocation of deeply nested structures will never again cause a stack overflow. Installation for the intermediate version: Insert a line _Py_trashcan_install(); at the end of Py_Initialize in pythonrun.c Please try it and check my code wether there is a better solution. cheers - chris -- Christian Tismer :^) Applied Biometrics GmbH : Have a break! Take a ride on Python's Düppelstr. 31 : *Starship* http://starship.python.net 12163 Berlin : PGP key -> http://wwwkeys.pgp.net PGP Fingerprint E182 71C7 1A9D 66E9 9D15 D3CC D4D7 93E2 1FAE F6DF we're tired of banana software - shipped green, ripens at home --------------D9F780CECED602EF245D7526 Content-Type: application/x-unknown-content-type-cfile; name="trashcan.c" Content-Transfer-Encoding: base64 Content-Disposition: inline; filename="trashcan.c" LyoNCiAgdHJhc2hjYW4NCiAgQ1QgMmswMTMwDQogIG5vbi1yZWN1cnNpdmVseSBkZXN0cm95 IG5lc3RlZCBvYmplY3RzDQoqLw0KDQojaW5jbHVkZSAiUHl0aG9uLmgiDQojaW5jbHVkZSAi Y29tcGlsZS5oIg0KI2luY2x1ZGUgImZyYW1lb2JqZWN0LmgiDQojaW5jbHVkZSAidHJhY2Vi YWNrLmgiDQoNCiNpbmNsdWRlICJ0cmFzaGNhbi5oIg0KDQpzdGF0aWMgUHlPYmplY3QgKiBk ZWxldGVfbGF0ZXIgPSBOVUxMOw0Kc3RhdGljIGludCBkZWxldGVfbmVzdGluZyA9IDA7DQoN CiNkZWZpbmUgVU5XSU5EX0xFVkVMIDUwDQoNCnZvaWQgc2FmZV9kZWxldGUob2IsIGRlc3Ry KQ0KCVB5T2JqZWN0ICogb2I7DQoJZGVzdHJ1Y3RvciBkZXN0cjsNCnsNCgkrK2RlbGV0ZV9u ZXN0aW5nOw0KCWlmIChkZWxldGVfbmVzdGluZyA8IFVOV0lORF9MRVZFTCkgew0KCQlkZXN0 cihvYik7DQoJfQ0KCWVsc2Ugew0KCQlpZiAoIWRlbGV0ZV9sYXRlcikNCgkJCWRlbGV0ZV9s YXRlciA9IFB5TGlzdF9OZXcoMCk7DQoJCWlmIChkZWxldGVfbGF0ZXIpIHsNCgkJCVB5TGlz dF9BcHBlbmQoZGVsZXRlX2xhdGVyLCBvYik7DQoJCX0NCgl9DQoJLS1kZWxldGVfbmVzdGlu ZzsNCgl3aGlsZSAoZGVsZXRlX25lc3RpbmcgPT0gMCAmJiBkZWxldGVfbGF0ZXIpIHsNCgkJ LyogcGljayB0by1kbyBsaXN0IGFuZCB0cnkgdG8gZXZpY3QgaXQgKi8NCgkJUHlPYmplY3Qg KiBzaHJlZGRlciA9IGRlbGV0ZV9sYXRlcjsNCgkJZGVsZXRlX2xhdGVyID0gTlVMTDsNCgkJ KytkZWxldGVfbmVzdGluZzsNCgkJUHlfREVDUkVGKHNocmVkZGVyKTsNCgkJLS1kZWxldGVf bmVzdGluZzsNCgl9DQp9DQoNCnN0YXRpYyBkZXN0cnVjdG9yIGxpc3RfZGVhbGxvY19vcmln ID0gTlVMTDsNCg0Kc3RhdGljIHZvaWQgbGlzdF9kZWFsbG9jX3NhZmUob2IpDQoJUHlPYmpl Y3QgKiBvYjsNCnsNCglzYWZlX2RlbGV0ZShvYiwgbGlzdF9kZWFsbG9jX29yaWcpOw0KfQ0K DQpzdGF0aWMgZGVzdHJ1Y3RvciB0dXBsZV9kZWFsbG9jX29yaWcgPSBOVUxMOw0KDQpzdGF0 aWMgdm9pZCB0dXBsZV9kZWFsbG9jX3NhZmUob2IpDQoJUHlPYmplY3QgKiBvYjsNCnsNCglz YWZlX2RlbGV0ZShvYiwgdHVwbGVfZGVhbGxvY19vcmlnKTsNCn0NCg0Kc3RhdGljIGRlc3Ry dWN0b3IgZGljdF9kZWFsbG9jX29yaWcgPSBOVUxMOw0KDQpzdGF0aWMgdm9pZCBkaWN0X2Rl YWxsb2Nfc2FmZShvYikNCglQeU9iamVjdCAqIG9iOw0Kew0KCXNhZmVfZGVsZXRlKG9iLCBk aWN0X2RlYWxsb2Nfb3JpZyk7DQp9DQoNCnN0YXRpYyBkZXN0cnVjdG9yIGZyYW1lX2RlYWxs b2Nfb3JpZyA9IE5VTEw7DQoNCnN0YXRpYyB2b2lkIGZyYW1lX2RlYWxsb2Nfc2FmZShvYikN CglQeU9iamVjdCAqIG9iOw0Kew0KCXNhZmVfZGVsZXRlKG9iLCBmcmFtZV9kZWFsbG9jX29y aWcpOw0KfQ0KDQpzdGF0aWMgZGVzdHJ1Y3RvciB0cmFjZWJhY2tfZGVhbGxvY19vcmlnID0g TlVMTDsNCg0Kc3RhdGljIHZvaWQgdHJhY2ViYWNrX2RlYWxsb2Nfc2FmZShvYikNCglQeU9i amVjdCAqIG9iOw0Kew0KCXNhZmVfZGVsZXRlKG9iLCB0cmFjZWJhY2tfZGVhbGxvY19vcmln KTsNCn0NCg0KDQpzdGF0aWMgaW50IHRyYXNoY2FuX2luc3RhbGxlZCA9IDA7DQoNCnZvaWQg X1B5X3RyYXNoY2FuX2luc3RhbGwoKQ0Kew0KCWlmICh0cmFzaGNhbl9pbnN0YWxsZWQpIHJl dHVybjsNCg0KCWxpc3RfZGVhbGxvY19vcmlnID0gUHlMaXN0X1R5cGUudHBfZGVhbGxvYzsN CglQeUxpc3RfVHlwZS50cF9kZWFsbG9jID0gbGlzdF9kZWFsbG9jX3NhZmU7DQoNCgl0dXBs ZV9kZWFsbG9jX29yaWcgPSBQeVR1cGxlX1R5cGUudHBfZGVhbGxvYzsNCglQeVR1cGxlX1R5 cGUudHBfZGVhbGxvYyA9IHR1cGxlX2RlYWxsb2Nfc2FmZTsNCg0KCWRpY3RfZGVhbGxvY19v cmlnID0gUHlEaWN0X1R5cGUudHBfZGVhbGxvYzsNCglQeURpY3RfVHlwZS50cF9kZWFsbG9j ID0gZGljdF9kZWFsbG9jX3NhZmU7DQoNCglmcmFtZV9kZWFsbG9jX29yaWcgPSBQeUZyYW1l X1R5cGUudHBfZGVhbGxvYzsNCglQeUZyYW1lX1R5cGUudHBfZGVhbGxvYyA9IGZyYW1lX2Rl YWxsb2Nfc2FmZTsNCg0KCXRyYWNlYmFja19kZWFsbG9jX29yaWcgPSBQeVRyYWNlQmFja19U eXBlLnRwX2RlYWxsb2M7DQoJUHlUcmFjZUJhY2tfVHlwZS50cF9kZWFsbG9jID0gdHJhY2Vi YWNrX2RlYWxsb2Nfc2FmZTsNCg0KCXRyYXNoY2FuX2luc3RhbGxlZCA9IDE7DQp9DQo= --------------D9F780CECED602EF245D7526 Content-Type: application/x-unknown-content-type-hfile; name="trashcan.h" Content-Transfer-Encoding: base64 Content-Disposition: inline; filename="trashcan.h" I2lmbmRlZiBQeV9UUkFTSENBTl9IDQojZGVmaW5lIFB5X1RSQVNIQ0FOX0gNCiNpZmRlZiBf X2NwbHVzcGx1cw0KZXh0ZXJuICJDIiB7DQojZW5kaWYNCi8qDQogIHRyYXNoY2FuDQogIENU IDJrMDEzMA0KICBub24tcmVjdXJzaXZlbHkgZGVzdHJveSBuZXN0ZWQgb2JqZWN0cw0KKi8N Cg0KRExfSU1QT1JUKHZvaWQpIF9QeV90cmFzaGNhbl9pbnN0YWxsIFB5X1BST1RPKCgpKTsN Cg0KI2VuZGlmIC8qICFQeV9UUkFTSENBTl9IICov --------------D9F780CECED602EF245D7526-- From fdrake@acm.org Mon Jan 31 17:08:11 2000 From: fdrake@acm.org (Fred L. Drake, Jr.) Date: Mon, 31 Jan 2000 12:08:11 -0500 (EST) Subject: [Python-Dev] Adding C ternary select (a?b:c) to Python? In-Reply-To: References: <000301bf6b79$4f0c8a60$482d153f@tim> Message-ID: <14485.49531.600935.643400@weyr.cnri.reston.va.us> Ka-Ping Yee writes: > a scan through a decent chunk of Python would be useful to find out how > often this construct (in its "and"/"or" incarnation) actually gets used. I'm not sure what the survey provides other than a lower bound. I think most Python programmers who want the ?: functionality avoid the and/or approach because of the ugliness. I know I do. But I'd really like to have the functionality if the syntax is reasonable! I could live with something like "if cond then true else false"; the leading "if" is visually important; without it, you have to scan over the test expression to find the "then", and that makes it harder to read. -Fred -- Fred L. Drake, Jr. Corporation for National Research Initiatives From bwarsaw@cnri.reston.va.us (Barry A. Warsaw) Mon Jan 31 17:33:25 2000 From: bwarsaw@cnri.reston.va.us (Barry A. Warsaw) (Barry A. Warsaw) Date: Mon, 31 Jan 2000 12:33:25 -0500 (EST) Subject: [Python-Dev] Adding C ternary select (a?b:c) to Python? References: <000301bf6b79$4f0c8a60$482d153f@tim> <14485.49531.600935.643400@weyr.cnri.reston.va.us> Message-ID: <14485.51045.97448.830202@anthem.cnri.reston.va.us> Put me in the camp of "yeah, occasionally I wish I had it, but I can always hack around it, and the C syntax just blows". I'm sure if it's wedgeable into CPython it would also be in JPython, but I dislike ?: syntax enough to vote strongly against it for CPython 1.6. A Forth-ish syntax might be more acceptable x = y > z if y else z but come on! You'll give ordinarily dandruff-free Python programmers plenty of other reasons to scratch their heads with this one. head-and-shoulders-above-the-rest-ly y'rs, -Barry From gvwilson@nevex.com Mon Jan 31 17:44:53 2000 From: gvwilson@nevex.com (gvwilson@nevex.com) Date: Mon, 31 Jan 2000 12:44:53 -0500 (EST) Subject: [Python-Dev] Adding C ternary select (a?b:c) to Python? In-Reply-To: <3895A48D.F69B3DFA@digicool.com> Message-ID: > It (?:) would allow you to incorporate logic into expressions. > There are contexts where only expressions are allowed, such as: > - lambdas > - DTML expr attributes > in which I'd very much like to incorporate tests. Don't know much about DTML, but believe that being able to put conditionals in lambdas would make the latter much more useful. > > The ?: syntax > > does not introduce any new "functionality" to the language, > Yes it does. Is anything possible with ?: that's impossible without? No --- Python is Turing-equivalent before and after the change. Is anything easier with ?: --- yes. Does this make up for the added complexity? Dunno (see below). > > The second qustion I'd ask is, who is this aimed at? It's certainly not > > aimed at first-time programmers, as I know from experience that the ?: > > is one of the hardest things to teach people in C (after pointers), > Hm. I can't agree. Strongly agree with the first author --- IME, ?: is very hard to teach. Greg From klm@digicool.com Mon Jan 31 17:58:07 2000 From: klm@digicool.com (Ken Manheimer) Date: Mon, 31 Jan 2000 12:58:07 -0500 (EST) Subject: [Python-Dev] Adding C ternary select (a?b:c) to Python? In-Reply-To: <14485.49531.600935.643400@weyr.cnri.reston.va.us> Message-ID: On Mon, 31 Jan 2000, Fred L. Drake, Jr. wrote: > Ka-Ping Yee writes: > > a scan through a decent chunk of Python would be useful to find out how > > often this construct (in its "and"/"or" incarnation) actually gets used. > > I'm not sure what the survey provides other than a lower bound. I > think most Python programmers who want the ?: functionality avoid the > and/or approach because of the ugliness. I know I do. Good point. Just because the workaround is bad doesn't mean the thing being worked-around is unimportant... I should weigh in to say that i have really really wanted, in particular, the ability to have a condition on the right hand side of an assignement. IIR, on some occasions it seemed less clear to have to use separate statements for what was essentially a single assignment that just, eg, differed by a single term. I wanted (want) some reasonable way to express the condition in an expression. I can see how this compactness could lead to regex-style convolution of expressions, but that could be avoided by providing a not-too-terse syntax. (I should admit that may have succumbed to the (a and (b,) or (c,))[0] grotesquerie at some point! Not sure. Wish i could recall what might have justified succumbing - the mere fact that i may have, without compelling justification, might-should disqualify my judgement on the matter, ay? Hey, maybe i didn't, i was just imagining it - now am i not a sterling judge?-) Ken klm@digicool.com From tismer@tismer.com Mon Jan 31 19:55:36 2000 From: tismer@tismer.com (Christian Tismer) Date: Mon, 31 Jan 2000 20:55:36 +0100 Subject: [Python-Dev] Ann: Stackless Python 1.02 Message-ID: <3895E8B8.995CA560@tismer.com> Stackless Python is a Python without C stack usage. It allows for all kinds of non-local control flow. For info see http://www.tismer.com/research/stackless/ Update for Stackless Python V. 1.02: - passes all standard tests - should work with Zope now (try...finally was incorrect) - has a smart object destructor for really deeply nested stuff The "5 percent speedup" is no longer there currently, since the smart object destructor needs to be optimized into the objects. It is not done in this test phase but will come. Please visit the Stackless Python homepage at http://www.tismer.com/research/stackless/ Fact sheet, links to documentation, source and binaries can be found there. cheers - chris

Stackless Python 1.02 + Continuations 0.6 - a version of Python 1.5.2 that does not need space on the C stack, and first-class callable continuation objects for Python. (31-Jan-2000) Christian Tismer Mission Impossible 5oftware Team From hon2559@orgio.net Sun Jan 9 01:50:35 2000 From: hon2559@orgio.net (=?ks_c_5601-1987?B?wMy757j0KDI0bWFsbCk=?=) Date: Sun, 09 Jan 2000 10:50:35 +0900 Subject: [Python-Dev] =?ks_c_5601-1987?B?IsDMu+citbUgx8+w7SAiwaS89rHiIrW1ILnesO0uLi4gW7GksO1d?= Message-ID: This is a multi-part message in MIME format. ------=_NextPart_000_0107_01C0F09A.93A50C00 Content-Type: text/plain; charset="ks_c_5601-1987" Content-Transfer-Encoding: base64 VW50aXRsZWQgRG9jdW1lbnRBOmFjdGl2ZSB7CUNPTE9SOiAjMDAwMDAwOyBGT05ULVNJWkU6 IDEycHg7IFRFWFQtREVDT1JBVElPTjogbm9uZSB9QTpsaW5rIHsgCUNPTE9SOiAjMDAwMDAw OyBGT05ULVNJWkU6IDEycHg7IFRFWFQtREVDT1JBVElPTjogbm9uZSB9QTp2aXNpdGVkIHsJ Q09MT1I6ICMwMDAwMDA7IEZPTlQtU0laRTogMTJweDsgVEVYVC1ERUNPUkFUSU9OOiBub25l IH1BOmhvdmVyIHsJQ09MT1I6ICMwMDAwMDA7IEZPTlQtU0laRTogMTJweDsgVEVYVC1ERUNP UkFUSU9OOiBub25lIH1URCB7CUZPTlQtU0laRTogMTJweDsgZm9udC1mYWNlOiCxvLiyIH0g ICAgICAgICAgICAgICAgICAgv8K288DOILDovuDAuyDHz73FILDtsLS60LXpv6Gw1CC5q7fh waaw+MfPtMIgvK268b26t84gQS9TILnfu/29wyDAzLvnvvfDvLChIMOlwNPAuyDIuMfHx9K2 pyAgtb++58itwOe/obytIMPWsO0gMTAwMLi4v/ix7sH2ILmwx7C56LvzwLsgx9ggteW4rrTC ILytuvG9usDUtM+02SAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICDAzLvn uKYgx9/AuLTPIMH9tenAzLimIMfPseQgx9i+37DatMK1pS4uLr3DsKO1tSAgvviw7SDA2r3F tbUgvviw7S4uLg0KIMPiwOW/5LiutMIguvG9zrytIL72tc61tSC+yLOqsO0sDQogxKPBpL72 uLa1tSDAzMGoILj4x9G02SDHz73DsO0uLi4NCiANCiDAzMGoILDGwaTHz8H2ILi2vLy/5C4g ICAgICAgICAgICAgICAgICAgICAgICAgDQq79SC6uLHdwNq4rr+hvK3AxyDD4rnfILH6sv3H z7DUIL3DwNvHz7y8v+QhIQ0KIMH9vsjAxyCxuLyusbi8riC5rcC6ILanuKYguLuy+8fPsNQg w7O4rsfYILXluLO0z7TZLg0KIA0KIFvAzLvnw7u80iwgwNTB1sO7vNIsILDFwdbDu7zSXQ0K ICAgICAgICAgICAgICAgICAgICAgICAgICANCsDMu+e1+7fOISEgv6G+7sTBILX7t84hIQ0K IA0KIL+hvu7EwSDAzMD8vK268b26IMDMwaggwPy5rrChv80gx9SysiDHz73KvcO/5C4NCiAg ICAgICAgICAgICAgICAgICAgICAgICAgDQqw7bC0tNTAxyC8scXDu+fH17+hIL7LuMKw1CDA zLvnvcMgud+7/cfSILz2IMDWtMIgxeu9xcDMwPwgILytuvG9urimILTrx+DH2CC15biutMIg vK268b26IMDUtM+02S4NCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIL7Is+fHz7y8 v+Q/ILTrx9G5zrG5ILTrx6UgwM7FzbPdwMy75yDAzLvnuPQgICh3d3cuMjRtYWxsLmNvLmty KSDA1LTPtNkuDQogx+O29CC++MDMILjewM/AuyC6uLO7IMHLvNvH1bTPtNkuILHNx8/AxyC4 3sDPwLogwKUgvK3HziDB3yC+y7DUILXIILDNwMy45yANCiDBpLq4IMXrvcW6ziCxx7DtILvn x9e/oSDAx7DFIFuxpLDtXbfOIMelvcO1yCDIq7q4uN7AzyDA1LTPtNkuDQogDQogwK/AzcfR IMGkuri287DtILv9sKK1x77uILq4s7uzqiC60sbtwLsgteW3yLTZuOkgvPa9xbDFus64piAg tK23r8HWvLy/5C4uDQogtNm9xSC6uLO7wfYgvsqw2r3AtM+02S4NCiA= ------=_NextPart_000_0107_01C0F09A.93A50C00 Content-Type: text/html; charset="ks_c_5601-1987" Content-Transfer-Encoding: base64 PGh0bWw+DQo8aGVhZD4NCjx0aXRsZT5VbnRpdGxlZCBEb2N1bWVudDwvdGl0bGU+DQo8bWV0 YSBodHRwLWVxdWl2PSJDb250ZW50LVR5cGUiIGNvbnRlbnQ9InRleHQvaHRtbDsgY2hhcnNl dD1ldWMta3IiPg0KPFNUWUxFIHR5cGU9dGV4dC9jc3M+DQpBOmFjdGl2ZSB7DQoJQ09MT1I6 ICMwMDAwMDA7IEZPTlQtU0laRTogMTJweDsgVEVYVC1ERUNPUkFUSU9OOiBub25lDQogICAg ICAgIH0NCkE6bGluayB7IA0KCUNPTE9SOiAjMDAwMDAwOyBGT05ULVNJWkU6IDEycHg7IFRF WFQtREVDT1JBVElPTjogbm9uZQ0KICAgICAgIH0NCkE6dmlzaXRlZCB7DQoJQ09MT1I6ICMw MDAwMDA7IEZPTlQtU0laRTogMTJweDsgVEVYVC1ERUNPUkFUSU9OOiBub25lDQogICAgICAg IH0NCkE6aG92ZXIgew0KCUNPTE9SOiAjMDAwMDAwOyBGT05ULVNJWkU6IDEycHg7IFRFWFQt REVDT1JBVElPTjogbm9uZQ0KICAgICAgICB9DQpURCB7DQoJRk9OVC1TSVpFOiAxMnB4OyBm b250LWZhY2U6ILG8uLINCiAgIH0NCjwvc3R5bGU+DQo8L2hlYWQ+DQoNCjxib2R5IGJnY29s b3I9IiNGRkZGRkYiIHRleHQ9IiMwMDAwMDAiIGxlZnRtYXJnaW49IjAiIHRvcG1hcmdpbj0i MCIgbWFyZ2lud2lkdGg9IjAiIG1hcmdpbmhlaWdodD0iMCI+DQo8dGFibGUgd2lkdGg9IjYw MCIgYm9yZGVyPSIwIiBjZWxsc3BhY2luZz0iMCIgY2VsbHBhZGRpbmc9IjAiIGFsaWduPSJj ZW50ZXIiPg0KICA8dHI+DQogICAgPHRkPjxhIGhyZWY9Imh0dHA6Ly93d3cuMjRtYWxsLmNv LmtyL21haW4uYXNwP29ra2luZD1tYWlsIiB0YXJnZXQ9Im5ldyI+PGltZyBzcmM9Imh0dHA6 Ly93d3cuMjRtYWxsLmNvLmtyL21haWwvaW1nL2VtYWlsXzEuZ2lmIiB3aWR0aD0iNjAwIiBo ZWlnaHQ9IjUwIiBuYW1lPSJzZXJ2aWNlIiBib3JkZXI9IjAiPjwvYT48L3RkPg0KICA8L3Ry Pg0KICA8dHI+DQogICAgPHRkPjxhIGhyZWY9Imh0dHA6Ly93d3cuMjRtYWxsLmNvLmtyL21h aW4uYXNwP29ra2luZD1tYWlsIiB0YXJnZXQ9Im5ldyI+PGltZyBzcmM9Imh0dHA6Ly93d3cu MjRtYWxsLmNvLmtyL21haWwvaW1nL2VtYWlsXzIuZ2lmIiB3aWR0aD0iNjAwIiBoZWlnaHQ9 IjE2MiIgYm9yZGVyPSIwIiBuYW1lPSJzZXJ2aWNlIj48L2E+PC90ZD4NCiAgPC90cj4NCiAg PHRyPg0KICAgIDx0ZCBiYWNrZ3JvdW5kPSJodHRwOi8vd3d3LjI0bWFsbC5jby5rci9tYWls L2ltZy9lbWFpbF8zLmdpZiIgaGVpZ2h0PSI2MSI+DQogICAgICA8dGFibGUgd2lkdGg9IjU5 MCIgYm9yZGVyPSIwIiBjZWxsc3BhY2luZz0iMCIgY2VsbHBhZGRpbmc9IjAiIGhlaWdodD0i NjEiPg0KICAgICAgICA8dHI+IA0KICAgICAgICAgIDx0ZCB3aWR0aD0iMTEwIj4mbmJzcDs8 L3RkPg0KICAgICAgICAgIDx0ZCB3aWR0aD0iNDgwIiBoZWlnaHQ9IjI1Ij4mbmJzcDs8L3Rk Pg0KICAgICAgICA8L3RyPg0KICAgICAgICA8dHI+IA0KICAgICAgICAgIDx0ZCB3aWR0aD0i MTEwIj4mbmJzcDs8L3RkPg0KICAgICAgICAgIDx0ZCB3aWR0aD0iNDgwIj6/wrbzwM4gsOi+ 4MC7IMfPvcUgsO2wtLrQtem/obDUILmrt+HBprD4x8+0wiC8rbrxvbq3ziBBL1Mgud+7/b3D IMDMu+e+98O8sKEgw6XA08C7IMi4x8fH0ranIA0KICAgICAgICAgICAgtb++58itwOe/obyt IMPWsO0gMTAwMLi4v/ix7sH2ILmwx7C56LvzwLsgx9ggteW4rrTCILytuvG9usDUtM+02SA8 L3RkPg0KICAgICAgICA8L3RyPg0KICAgICAgPC90YWJsZT4NCiAgICA8L3RkPg0KICA8L3Ry Pg0KICA8dHI+DQogICAgPHRkPg0KICAgICAgPHRhYmxlIHdpZHRoPSI2MDAiIGJvcmRlcj0i MCIgY2VsbHNwYWNpbmc9IjAiIGNlbGxwYWRkaW5nPSIwIj4NCiAgICAgICAgPHRyPiANCiAg ICAgICAgICA8dGQgd2lkdGg9IjQiIGJhY2tncm91bmQ9Imh0dHA6Ly93d3cuMjRtYWxsLmNv LmtyL21haWwvaW1nL2VtYWlsX2xlZnQuZ2lmIj48L3RkPg0KICAgICAgICAgIDx0ZCB3aWR0 aD0iNTkxIj4gDQogICAgICAgICAgICA8dGFibGUgd2lkdGg9IjU5MSIgYm9yZGVyPSIwIiBj ZWxsc3BhY2luZz0iMCIgY2VsbHBhZGRpbmc9IjAiPg0KICAgICAgICAgICAgICA8dHI+DQog ICAgICAgICAgICAgICAgPHRkIGNvbHNwYW49IjMiIGhlaWdodD0iMTAiPjwvdGQ+DQogICAg ICAgICAgICAgIDwvdHI+DQogICAgICAgICAgICAgIDx0ciBhbGlnbj0iY2VudGVyIj4gDQog ICAgICAgICAgICAgICAgPHRkIGNvbHNwYW49IjMiIGhlaWdodD0iMjAiPiZuYnNwOzxpbWcg c3JjPSJodHRwOi8vd3d3LjI0bWFsbC5jby5rci9tYWlsL2ltZy9lbWFpbF90aXRsZS5naWYi IHdpZHRoPSI0MDAiIGhlaWdodD0iMjIiPjwvdGQ+DQogICAgICAgICAgICAgIDwvdHI+DQog ICAgICAgICAgICAgIDx0cj4gDQogICAgICAgICAgICAgICAgPHRkIGNvbHNwYW49IjMiIGhl aWdodD0iMTAiPjwvdGQ+DQogICAgICAgICAgICAgIDwvdHI+DQogICAgICAgICAgICAgIDx0 cj4gDQogICAgICAgICAgICAgICAgPHRkIHdpZHRoPSIxMzEiPjxhIGhyZWY9Imh0dHA6Ly93 d3cuMjRtYWxsLmNvLmtyL21lbnVfYWRkaXRpb24vaG9tZS9kZWZhdWx0LmFzcD9PS2tpbmQ9 bWFpbCIgdGFyZ2V0PSJuZXciPjxpbWcgc3JjPSJodHRwOi8vd3d3LjI0bWFsbC5jby5rci9t YWlsL2ltZy9lbWFpbF9sXzIuZ2lmIiB3aWR0aD0iMTMxIiBoZWlnaHQ9Ijk1IiBib3JkZXI9 IjAiIG5hbWU9InNlcnZpY2UiPjwvYT48L3RkPg0KICAgICAgICAgICAgICAgIDx0ZCB3aWR0 aD0iNDYwIiBjb2xzcGFuPSIyIj4gDQogICAgICAgICAgICAgICAgICA8dGFibGUgd2lkdGg9 IjQ2MCIgYm9yZGVyPSIwIiBjZWxsc3BhY2luZz0iMCIgY2VsbHBhZGRpbmc9IjAiPg0KICAg ICAgICAgICAgICAgICAgICA8dHI+IA0KICAgICAgICAgICAgICAgICAgICAgIDx0ZCBjb2xz cGFuPSIyIiBoZWlnaHQ9IjIzIj48aW1nIHNyYz0iaHR0cDovL3d3dy4yNG1hbGwuY28ua3Iv bWFpbC9pbWcvZW1haWxfdHh0XzEuZ2lmIiB3aWR0aD0iMjQxIiBoZWlnaHQ9IjIyIj48L3Rk Pg0KICAgICAgICAgICAgICAgICAgICA8L3RyPg0KICAgICAgICAgICAgICAgICAgICA8dHI+ IA0KICAgICAgICAgICAgICAgICAgICAgIDx0ZCBoZWlnaHQ9IjUiIHdpZHRoPSIyMCI+PC90 ZD4NCiAgICAgICAgICAgICAgICAgICAgICA8dGQgaGVpZ2h0PSI1IiB3aWR0aD0iNDQwIj48 L3RkPg0KICAgICAgICAgICAgICAgICAgICA8L3RyPg0KICAgICAgICAgICAgICAgICAgICA8 dHI+IA0KICAgICAgICAgICAgICAgICAgICAgIDx0ZCB3aWR0aD0iMjAiPiZuYnNwOzwvdGQ+ DQogICAgICAgICAgICAgICAgICAgICAgPHRkIHdpZHRoPSI0NDAiPjxmb250IGNvbG9yPSIj MzMzMzMzIj7AzLvnuKYgx9/AuLTPIMH9tenAzLimIMfPseQgx9i+37DatMK1pS4uLr3DsKO1 tSANCiAgICAgICAgICAgICAgICAgICAgICAgIL74sO0gwNq9xbW1IL74sO0uLi48YnI+DQog ICAgICAgICAgICAgICAgICAgICAgICDD4sDlv+S4rrTCILrxvc68rSC+9rXOtbUgvsizqrDt LDxicj4NCiAgICAgICAgICAgICAgICAgICAgICAgIMSjwaS+9ri2tbUgwMzBqCC4+MfRtNkg x8+9w7DtLi4uPGJyPg0KICAgICAgICAgICAgICAgICAgICAgICAgPGJyPg0KICAgICAgICAg ICAgICAgICAgICAgICAgwMzBqCCwxsGkx8/B9iC4try8v+QuPC9mb250PjwvdGQ+DQogICAg ICAgICAgICAgICAgICAgIDwvdHI+DQogICAgICAgICAgICAgICAgICA8L3RhYmxlPg0KICAg ICAgICAgICAgICAgIDwvdGQ+DQogICAgICAgICAgICAgIDwvdHI+DQogICAgICAgICAgICAg IDx0cj4gDQogICAgICAgICAgICAgICAgPHRkIHdpZHRoPSIxMzEiPjxpbWcgc3JjPSJodHRw Oi8vd3d3LjI0bWFsbC5jby5rci9tYWlsL2ltZy9lbWFpbF9sXzMuZ2lmIiB3aWR0aD0iMTMx IiBoZWlnaHQ9IjE4Ij48L3RkPg0KICAgICAgICAgICAgICAgIDx0ZCB3aWR0aD0iNDYwIiBj b2xzcGFuPSIyIj4mbmJzcDs8L3RkPg0KICAgICAgICAgICAgICA8L3RyPg0KICAgICAgICAg ICAgICA8dHI+IA0KICAgICAgICAgICAgICAgIDx0ZCB3aWR0aD0iMTMxIj48YSBocmVmPSJo dHRwOi8vd3d3LjI0bWFsbC5jby5rci9tZW51X2FkZGl0aW9uL2NsZWFuL2RlZmF1bHQuYXNw P29ra2luZD1tYWlsIiB0YXJnZXQ9Im5ldyI+PGltZyBzcmM9Imh0dHA6Ly93d3cuMjRtYWxs LmNvLmtyL21haWwvaW1nL2VtYWlsX2xfNC5naWYiIHdpZHRoPSIxMzEiIGhlaWdodD0iOTYi IGJvcmRlcj0iMCIgbmFtZT0ic2VydmljZSI+PC9hPjwvdGQ+DQogICAgICAgICAgICAgICAg PHRkIHdpZHRoPSI0NjAiIHZhbGlnbj0idG9wIiBjb2xzcGFuPSIyIj4gDQogICAgICAgICAg ICAgICAgICA8dGFibGUgd2lkdGg9IjQ2MCIgYm9yZGVyPSIwIiBjZWxsc3BhY2luZz0iMCIg Y2VsbHBhZGRpbmc9IjAiPg0KICAgICAgICAgICAgICAgICAgICA8dHI+IA0KICAgICAgICAg ICAgICAgICAgICAgIDx0ZCBjb2xzcGFuPSIyIiBoZWlnaHQ9IjIzIj48aW1nIHNyYz0iaHR0 cDovL3d3dy4yNG1hbGwuY28ua3IvbWFpbC9pbWcvZW1haWxfdHh0XzIuZ2lmIiB3aWR0aD0i MjQxIiBoZWlnaHQ9IjIyIj48L3RkPg0KICAgICAgICAgICAgICAgICAgICA8L3RyPg0KICAg ICAgICAgICAgICAgICAgICA8dHI+IA0KICAgICAgICAgICAgICAgICAgICAgIDx0ZCBoZWln aHQ9IjUiIHdpZHRoPSIyMCI+PC90ZD4NCiAgICAgICAgICAgICAgICAgICAgICA8dGQgaGVp Z2h0PSI1IiB3aWR0aD0iNDQwIj48L3RkPg0KICAgICAgICAgICAgICAgICAgICA8L3RyPg0K ICAgICAgICAgICAgICAgICAgICA8dHI+IA0KICAgICAgICAgICAgICAgICAgICAgIDx0ZCB3 aWR0aD0iMjAiPiZuYnNwOzwvdGQ+DQogICAgICAgICAgICAgICAgICAgICAgPHRkIHdpZHRo PSI0NDAiPiANCiAgICAgICAgICAgICAgICAgICAgICAgIDxwPjxmb250IGNvbG9yPSIjMzMz MzMzIj679SC6uLHdwNq4rr+hvK3AxyDD4rnfILH6sv3Hz7DUIL3DwNvHz7y8v+QhITxicj4N CiAgICAgICAgICAgICAgICAgICAgICAgICAgwf2+yMDHILG4vK6xuLyuILmtwLogtqe4piC4 u7L7x8+w1CDDs7iux9ggteW4s7TPtNkuPGJyPg0KICAgICAgICAgICAgICAgICAgICAgICAg ICA8YnI+DQogICAgICAgICAgICAgICAgICAgICAgICAgIFvAzLvnw7u80iwgwNTB1sO7vNIs ILDFwdbDu7zSXTwvZm9udD48L3A+DQogICAgICAgICAgICAgICAgICAgICAgPC90ZD4NCiAg ICAgICAgICAgICAgICAgICAgPC90cj4NCiAgICAgICAgICAgICAgICAgIDwvdGFibGU+DQog ICAgICAgICAgICAgICAgPC90ZD4NCiAgICAgICAgICAgICAgPC90cj4NCiAgICAgICAgICAg ICAgPHRyPiANCiAgICAgICAgICAgICAgICA8dGQgd2lkdGg9IjEzMSI+PGltZyBzcmM9Imh0 dHA6Ly93d3cuMjRtYWxsLmNvLmtyL21haWwvaW1nL2VtYWlsX2xfNS5naWYiIHdpZHRoPSIx MzEiIGhlaWdodD0iMTkiPjwvdGQ+DQogICAgICAgICAgICAgICAgPHRkIHdpZHRoPSI0NjAi IGNvbHNwYW49IjIiPiZuYnNwOzwvdGQ+DQogICAgICAgICAgICAgIDwvdHI+DQogICAgICAg ICAgICAgIDx0cj4gDQogICAgICAgICAgICAgICAgPHRkIHdpZHRoPSIxMzEiPjxhIGhyZWY9 Imh0dHA6Ly93d3cuMjRtYWxsLmNvLmtyL21lbnVfYWRkaXRpb24vYWlyY29uL2RlZmF1bHQu YXNwP29ra2luZD1tYWlsIiB0YXJnZXQ9Im5ldyI+PGltZyBzcmM9Imh0dHA6Ly93d3cuMjRt YWxsLmNvLmtyL21haWwvaW1nL2VtYWlsX2xfNi5naWYiIHdpZHRoPSIxMzEiIGhlaWdodD0i OTciIGJvcmRlcj0iMCIgbmFtZT0ic2VydmljZSI+PC9hPjwvdGQ+DQogICAgICAgICAgICAg ICAgPHRkIHdpZHRoPSI0NjAiIHZhbGlnbj0idG9wIiBjb2xzcGFuPSIyIj4gDQogICAgICAg ICAgICAgICAgICA8dGFibGUgd2lkdGg9IjQ2MCIgYm9yZGVyPSIwIiBjZWxsc3BhY2luZz0i MCIgY2VsbHBhZGRpbmc9IjAiPg0KICAgICAgICAgICAgICAgICAgICA8dHI+IA0KICAgICAg ICAgICAgICAgICAgICAgIDx0ZCBjb2xzcGFuPSIyIiBoZWlnaHQ9IjIzIj48aW1nIHNyYz0i aHR0cDovL3d3dy4yNG1hbGwuY28ua3IvbWFpbC9pbWcvZW1haWxfdHh0XzMuZ2lmIiB3aWR0 aD0iMzAwIiBoZWlnaHQ9IjIyIj48L3RkPg0KICAgICAgICAgICAgICAgICAgICA8L3RyPg0K ICAgICAgICAgICAgICAgICAgICA8dHI+IA0KICAgICAgICAgICAgICAgICAgICAgIDx0ZCBo ZWlnaHQ9IjUiIHdpZHRoPSIyMCI+PC90ZD4NCiAgICAgICAgICAgICAgICAgICAgICA8dGQg aGVpZ2h0PSI1IiB3aWR0aD0iNDQwIj48L3RkPg0KICAgICAgICAgICAgICAgICAgICA8L3Ry Pg0KICAgICAgICAgICAgICAgICAgICA8dHI+IA0KICAgICAgICAgICAgICAgICAgICAgIDx0 ZCB3aWR0aD0iMjAiPiZuYnNwOzwvdGQ+DQogICAgICAgICAgICAgICAgICAgICAgPHRkIHdp ZHRoPSI0NDAiPiANCiAgICAgICAgICAgICAgICAgICAgICAgIDxwPjxmb250IGNvbG9yPSIj MzMzMzMzIj7AzLvntfu3ziEhIL+hvu7EwSC1+7fOISE8YnI+DQogICAgICAgICAgICAgICAg ICAgICAgICAgIDxicj4NCiAgICAgICAgICAgICAgICAgICAgICAgICAgv6G+7sTBIMDMwPy8 rbrxvbogwMzBqCDA/LmusKG/zSDH1LKyIMfPvcq9w7/kLjwvZm9udD48L3A+DQogICAgICAg ICAgICAgICAgICAgICAgPC90ZD4NCiAgICAgICAgICAgICAgICAgICAgPC90cj4NCiAgICAg ICAgICAgICAgICAgIDwvdGFibGU+DQogICAgICAgICAgICAgICAgPC90ZD4NCiAgICAgICAg ICAgICAgPC90cj4NCiAgICAgICAgICAgICAgPHRyPiANCiAgICAgICAgICAgICAgICA8dGQg d2lkdGg9IjEzMSI+PGltZyBzcmM9Imh0dHA6Ly93d3cuMjRtYWxsLmNvLmtyL21haWwvaW1n L2VtYWlsX2xfNy5naWYiIHdpZHRoPSIxMzEiIGhlaWdodD0iMTgiPjwvdGQ+DQogICAgICAg ICAgICAgICAgPHRkIHdpZHRoPSI0NjAiIGNvbHNwYW49IjIiPiZuYnNwOzwvdGQ+DQogICAg ICAgICAgICAgIDwvdHI+DQogICAgICAgICAgICAgIDx0cj4gDQogICAgICAgICAgICAgICAg PHRkIHdpZHRoPSIxMzEiPjxhIGhyZWY9Imh0dHA6Ly93d3cuMjRtYWxsLmNvLmtyL21lbnVf YWRkaXRpb24vbGluZS9kZWZhdWx0LmFzcD9va2tpbmQ9bWFpbCIgdGFyZ2V0PSJuZXciPjxp bWcgc3JjPSJodHRwOi8vd3d3LjI0bWFsbC5jby5rci9tYWlsL2ltZy9lbWFpbF9sXzguZ2lm IiB3aWR0aD0iMTMxIiBoZWlnaHQ9Ijk2IiBib3JkZXI9IjAiIG5hbWU9InNlcnZpY2UiPjwv YT48L3RkPg0KICAgICAgICAgICAgICAgIDx0ZCB3aWR0aD0iNDYwIiB2YWxpZ249InRvcCIg Y29sc3Bhbj0iMiI+IA0KICAgICAgICAgICAgICAgICAgPHRhYmxlIHdpZHRoPSI0NjAiIGJv cmRlcj0iMCIgY2VsbHNwYWNpbmc9IjAiIGNlbGxwYWRkaW5nPSIwIj4NCiAgICAgICAgICAg ICAgICAgICAgPHRyPiANCiAgICAgICAgICAgICAgICAgICAgICA8dGQgY29sc3Bhbj0iMiIg aGVpZ2h0PSIyMyI+PGltZyBzcmM9Imh0dHA6Ly93d3cuMjRtYWxsLmNvLmtyL21haWwvaW1n L2VtYWlsX3R4dF80LmdpZiIgd2lkdGg9IjMwMCIgaGVpZ2h0PSIyMiI+PC90ZD4NCiAgICAg ICAgICAgICAgICAgICAgPC90cj4NCiAgICAgICAgICAgICAgICAgICAgPHRyPiANCiAgICAg ICAgICAgICAgICAgICAgICA8dGQgaGVpZ2h0PSI1IiB3aWR0aD0iMjAiPjwvdGQ+DQogICAg ICAgICAgICAgICAgICAgICAgPHRkIGhlaWdodD0iNSIgd2lkdGg9IjQ0MCI+PC90ZD4NCiAg ICAgICAgICAgICAgICAgICAgPC90cj4NCiAgICAgICAgICAgICAgICAgICAgPHRyPiANCiAg ICAgICAgICAgICAgICAgICAgICA8dGQgd2lkdGg9IjIwIj4mbmJzcDs8L3RkPg0KICAgICAg ICAgICAgICAgICAgICAgIDx0ZCB3aWR0aD0iNDQwIj4gDQogICAgICAgICAgICAgICAgICAg ICAgICA8cD48Zm9udCBjb2xvcj0iIzMzMzMzMyI+sO2wtLTUwMcgvLHFw7vnx9e/oSC+y7jC sNQgwMy7573DILnfu/3H0iC89iDA1rTCIMXrvcXAzMD8IA0KICAgICAgICAgICAgICAgICAg ICAgICAgICC8rbrxvbq4piC068fgx9ggteW4rrTCILytuvG9uiDA1LTPtNkuPC9mb250Pjwv cD4NCiAgICAgICAgICAgICAgICAgICAgICA8L3RkPg0KICAgICAgICAgICAgICAgICAgICA8 L3RyPg0KICAgICAgICAgICAgICAgICAgPC90YWJsZT4NCiAgICAgICAgICAgICAgICA8L3Rk Pg0KICAgICAgICAgICAgICA8L3RyPg0KICAgICAgICAgICAgICA8dHI+IA0KICAgICAgICAg ICAgICAgIDx0ZCB3aWR0aD0iMTMxIiBoZWlnaHQ9IjgwIiBiYWNrZ3JvdW5kPSJodHRwOi8v d3d3LjI0bWFsbC5jby5rci9tYWlsL2ltZy9lbWFpbF9sXzkuZ2lmIj4mbmJzcDs8L3RkPg0K ICAgICAgICAgICAgICAgIDx0ZCB3aWR0aD0iMjUwIiBhbGlnbj0icmlnaHQiIGhlaWdodD0i ODAiPjxhIGhyZWY9Imh0dHA6Ly93d3cuMjRtYWxsLmNvLmtyL21haW4uYXNwP29ra2luZD1t YWlsIiBvbmZvY3VzID0ndGhpcy5ibHVyKCknIHRhcmdldD0ibmV3Ij48aW1nIHNyYz0iaHR0 cDovL3d3dy4yNG1hbGwuY28ua3IvbWFpbC9pbWcvZW1haWxfcmVxLmdpZiIgd2lkdGg9IjE0 NiIgaGVpZ2h0PSI3NCIgYm9yZGVyPSIwIj48L2E+PC90ZD4NCiAgICAgICAgICAgICAgICA8 dGQgd2lkdGg9IjIxMCI+Jm5ic3A7PC90ZD4NCiAgICAgICAgICAgICAgPC90cj4NCiAgICAg ICAgICAgICAgPHRyPiANCiAgICAgICAgICAgICAgICA8dGQgd2lkdGg9IjEzMSIgYmFja2dy b3VuZD0iaHR0cDovL3d3dy4yNG1hbGwuY28ua3IvbWFpbC9pbWcvZW1haWxfbF85LmdpZiI+ Jm5ic3A7PC90ZD4NCiAgICAgICAgICAgICAgICA8dGQgd2lkdGg9IjQ2MCIgY29sc3Bhbj0i MiI+Jm5ic3A7PC90ZD4NCiAgICAgICAgICAgICAgPC90cj4NCiAgICAgICAgICAgIDwvdGFi bGU+DQogICAgICAgICAgPC90ZD4NCiAgICAgICAgICA8dGQgd2lkdGg9IjUiIGJhY2tncm91 bmQ9Imh0dHA6Ly93d3cuMjRtYWxsLmNvLmtyL21haWwvaW1nL2VtYWlsX3JpZ2h0LmdpZiI+ PC90ZD4NCiAgICAgICAgPC90cj4NCiAgICAgIDwvdGFibGU+DQogICAgPC90ZD4NCiAgPC90 cj4NCiAgPHRyPg0KICAgIDx0ZD48aW1nIHNyYz0iaHR0cDovL3d3dy4yNG1hbGwuY28ua3Iv bWFpbC9pbWcvZW1haWxfYnRtLmdpZiIgd2lkdGg9IjYwMCIgaGVpZ2h0PSI0NSI+PC90ZD4N CiAgPC90cj4NCjwvdGFibGU+DQo8dHI+DQogIDx0ZCBhbGlnbj0iY2VudGVyIiB3aWR0aD0i NTkyIj4gDQogICAgPHAgYWxpZ249ImNlbnRlciI+IDxmb250IGNvbG9yPSIjMDAwMDAwIiBz aXplPSIyIj6+yLPnx8+8vL/kPyC068fRuc6xuSC068elIMDOxc2z3cDMu+cgPGEgaHJlZj0i aHR0cDovL3d3dy4yNG1hbGwuY28ua3IvbWFpbi5hc3A/b2traW5kPW1haWwiPsDMu+e49CAN CiAgICAgICh3d3cuMjRtYWxsLmNvLmtyKTwvYT4gwNS0z7TZLjxicj4NCiAgICAgIMfjtvQg vvjAzCC43sDPwLsgurizuyDBy7zbx9W0z7TZLiCxzcfPwMcguN7Az8C6IMClILytx84gwd8g vsuw1CC1yCCwzcDMuOcgPGJyPg0KICAgICAgwaS6uCDF673Fus4gscew7SC758fXv6EgwMew xSBbsaSw7V23ziDHpb3DtcggyKu6uLjewM8gwNS0z7TZLjxicj4NCiAgICAgIDxicj4NCiAg ICAgIMCvwM3H0SDBpLq4tvOw7SC7/bCitce+7iC6uLO7s6ogutLG7cC7ILXlt8i02bjpIDxB IGhyZWY9Im1haWx0bzpob24yNTU5QG9yZ2lvLm5ldD9zdWJqZWN0Pbz2vcWwxbrOJmFtcDti b2R5PbjewM+89r3FwLsgsMW6zsfVtM+02SI+PGZvbnQgY29sb3I9IiNGRjAwMDAiPjxiPrz2 vcWwxbrOPC9iPjwvZm9udD48L2E+uKYgDQogICAgICC0rbevwda8vL/kLi48L2ZvbnQ+PC9w Pg0KICAgIDxwIGFsaWduPSJjZW50ZXIiPjxmb250IGNvbG9yPSIjMDAwMDAwIiBzaXplPSIy Ij4gtNm9xSC6uLO7wfYgvsqw2r3AtM+02S48L2ZvbnQ+PC9wPg0KICA8L3RkPg0KPC90cj4N CjwvQk9EWT4NCjwvSFRNTD4= ------=_NextPart_000_0107_01C0F09A.93A50C00-- From tim_one at email.msn.com Sun Jan 2 06:52:34 2000 From: tim_one at email.msn.com (Tim Peters) Date: Sun, 2 Jan 2000 00:52:34 -0500 Subject: [Python-Dev] Re: [Distutils] Questions about distutils strategy In-Reply-To: <199912091617.LAA05742@eric.cnri.reston.va.us> Message-ID: <000401bf54e5$91587280$1f2d153f@tim> Briefly backtracking to an old thread: [Guido] > ... > The problem lies in which key is used. All versions of > Python 1.5.x (1.5, 1.5.1, 1.5.2) use the same key! This > is a main cause of trouble, because it means that different > versions cannot peacefully live together even if the user > installs them into different directories -- they will all > use the registry keys of the last version installed. This, > in turn, means that someone who writes a Python application > that has a dependency on a particular Python version (and > which application worth distributing doesn't :-) cannot > trust that if a Python installation is present, it is the > right one. But they also cannot simply bundle the standard > installer for the correct Python version with their program, > because its installation would overwrite an existing Python > application, thus breaking some *other* Python apps that > the user might already have installed. Right, that's one class of intractable problem under Windows. *Inside* my workplace, another kind of problem is caused when people try to make a Python app available over the Windows network. They stick the Python they want and its libraries out on the network, with python.exe in the same directory as the app. Now some people have highly customized Python setups, and the network Python picks up "the wrong" site.py etc. That sucks, and there appears no sane way to stop it. Telling internal app distributors they need to invent a unique registry key and fiddle their python.exe's resources is a non-starter. Ditto telling people with highly customized Pythons "don't do that". Ditto telling anyone they have to run any sort of installation script just to use a network app (sometimes they don't even know they're running it! e.g., when it's a subsystem invoked by another app). So while everyone is thinking about the hardest possible scenarios, please give a thought to the dirt simple one too <0.5 wink>: an app distributor who knows exactly what they're doing, and for whom *any* magical inference is simply a barrier to overcome. The latter can be satisfied by any number of means, from an envar that says "please don't try to be helpful, *this* is the directory you look in, and if you don't find stuff there give up" to a cmdline switch that says the same. Nothing Windows-specific there -- any OS with an envar or a cmdline will play along . > ... > I thought a bit about how VB solves this. I think that when > you wrap up a VB app in, all the support code (mostly a big > DLL) is wrapped with it. When the user runs the installer, > the DLL is installed (probably in the WINDOWS directory). If > a user installs several VB apps built with the same VB > version, they all attempt to install the exact same DLL; of > course the installers notice this and optimize it away, keeping > a reference count. This is the way most *MS* DLLs work; stuff like the C runtime libraries and MS database drivers work exactly the same way. It's rare for pkgs other than MS's to attempt to use this mechanism, though (the reason is given below). > (Ignoring for now the fact that those reference counts don't > always work!) ? They work very well, in my experience. Where they fail is when installers & uninstallers break the rules. MS publishes the list of MS DLLs that are to be treated this way: an installer "must" use refcounting on the DLLs in the list. Alas, some (especially older) installation pkgs don't. Then the refcounts get screwed up. That's what makes the mechanism brittle: "the system" doesn't enforce it, it relies on universal & intelligent cooperation. It's very likely that someone distributing a Python app will neglect (out of ignorance) to bump the refcount on their Python components, so the refcount will be artificially low, and a later uninstall of some unrelated pkg that *did* follow the rules will merrily delete Python. Gordon and I will repeat this until it sinks in : almost everyone with a successful Windows product ships the non-MS DLLs they rely on and copies them into their own app directory. It's simple and it works; alternatives are complicated and don't work. Many even ship & copy MS DLLs (e.g., Scriptics copies its own msvcrt.dll (the MS C runtime) into Tcl's directories). Worrying about space consumed by redundant Python components is a bad case of premature optimization <0.3 wink>. > ... > How can we do something similar for Python? Seriously, short of getting MS to distribute Python and put the Python DLLs on The List of refcounted resources, we should pursue this line reluctantly if at all. MS may have a better scheme in the future, but for now better safe than sorry. a-couple-mb-on-a-modern-pc-isn't-worth-the-time-it-took- to-read-this-ly y'rs - tim From gstein at lyra.org Mon Jan 3 03:53:24 2000 From: gstein at lyra.org (Greg Stein) Date: Sun, 2 Jan 2000 18:53:24 -0800 (PST) Subject: [Python-Dev] new imputil.py Message-ID: Happy New Year! I've attached a new imputil.py to this message. It isn't posted on my page yet, as I'd like some feedback before declaring this new version viable. In this imputil, there is an ImportManager class. It gets installed as the import hook, with the presumption that it is the only import hook (technically, it could chain, but I've disabled that for now). I think Python 1.6 should drop the __import__ builtin and move to something like sys.import_hook (to allow examination and change). Another alternative would be sys.get_import_hook() and sys.set_import_hook(). [ I don't think we would want a "set" that returned the old version as the only way to get the current hook function; we want to be able to easily find the ImportManager instance. ] The ImportManager knows how to scan sys.path when it needs to find a top-level module/package (e.g. given a.b.c, the "a" is the top-level; b.c falls "below" that). sys.path can contain strings which specify a filesystem directory, or it can contain Importer instances. The manager also records an ordered list of suffix/importer pairs. The add_suffix() method is used to append new suffixes, but clients can also access the .suffixes attribute for fine-grained manipulation/ordering. There is a new importer called _FilesystemImporter which understands how to look into a directory for Python modules. It borrows/refers to the ImportManager's .suffixes attribute, using that to find modules in a directory. This is also the Importer that gets associated with each filesystem-based module. The importers used for suffix-based importing are derived from SuffixImporter. While a function could be used here, future changes will be easier if we presume class instances. The new imputil works fine (use _test_revamp() to switch to the new import mechanism). Importer subclasses using the old imputil should continue to work, although I am deprecating the 2-tuple return value for get_code(). get_code() should return None or the 3-tuple form now. I think I still have a bit more work to do, to enable something like "import a.b.c" where a.zip is an archive on the path and "b.c" resides in the archive. Note: it *is* possible to do sys.path.append(ZipImporter(filename)) and have "a.b.c" in the Zip file. It would simply be nicer to be able to drop arbitrary .zip files onto the path and use their basename as the top-level name of a package. Anyhow: I haven't looked at this scenario yet to find what the new system is missing (if anything). As always: feedback is more than appreciated! Especially from people using imputil today. Did I break anything? Does the new scheme still feel right to you? etc. Cheers, -g p.s. I'd also like to remove PackageArchiveImporter and PackageArchive. They don't seem to add any real value. I might move DirectoryImporter and PathImporter to an "examples" file, too. -- Greg Stein, http://www.lyra.org/ -------------- next part -------------- # # imputil.py # # Written by Greg Stein. Public Domain. # No Copyright, no Rights Reserved, and no Warranties. # # Utilities to help out with custom import mechanisms. # # Additional modifications were contribed by Marc-Andre Lemburg and # Gordon McMillan. # # This module is maintained by Greg and is available at: # http://www.lyra.org/greg/python/imputil.py # # Since this isn't in the Python distribution yet, we'll use the CVS ID # for tracking: # $Id: imputil.py,v 1.9 2000/01/03 02:38:29 gstein Exp $ # # note: avoid importing non-builtin modules import imp import sys import strop import __builtin__ # for the DirectoryImporter import struct import marshal _StringType = type('') _ModuleType = type(sys) class ImportManager: "Manage the import process." def install(self): ### warning: Python 1.6 will have a different hook mechanism; this ### code will need to change. self.__chain_import = __builtin__.__import__ self.__chain_reload = __builtin__.reload __builtin__.__import__ = self._import_hook ### fix this #__builtin__.reload = None #__builtin__.reload = self._reload_hook def add_suffix(self, suffix, importer): assert isinstance(importer, SuffixImporter) self.suffixes.append((suffix, importer)) ###################################################################### # # PRIVATE METHODS # def __init__(self): # we're definitely going to be importing something in the future, # so let's just load the OS-related facilities. if not _os_stat: _os_bootstrap() # Initialize the set of suffixes that we recognize and import. # The default will import dynamic-load modules first, followed by # .py files (or a .py file's cached bytecode) self.suffixes = [ ] for desc in imp.get_suffixes(): if desc[2] == imp.C_EXTENSION: self.suffixes.append((desc[0], DynLoadSuffixImporter(desc))) self.suffixes.append(('.py', PySuffixImporter())) # This is the importer that we use for grabbing stuff from the # filesystem. It defines one more method (import_from_dir) for our use. self.fs_imp = _FilesystemImporter(self.suffixes) def _import_hook(self, fqname, globals=None, locals=None, fromlist=None): """Python calls this hook to locate and import a module.""" parts = strop.split(fqname, '.') # determine the context of this import parent = self._determine_import_context(globals) # if there is a parent, then its importer should manage this import if parent: module = parent.__importer__._do_import(parent, parts, fromlist) if module: return module # has the top module already been imported? try: top_module = sys.modules[parts[0]] except KeyError: # look for the topmost module top_module = self._import_top_module(parts[0]) if not top_module: # the topmost module wasn't found at all. raise ImportError, 'No module named ' + fqname return self.__chain_import(name, globals, locals, fromlist) # fast-path simple imports if len(parts) == 1: if not fromlist: return top_module if not top_module.__dict__.get('__ispkg__'): # __ispkg__ isn't defined (the module was not imported by us), or # it is zero. # # In the former case, there is no way that we could import # sub-modules that occur in the fromlist (but we can't raise an # error because it may just be names) because we don't know how # to deal with packages that were imported by other systems. # # In the latter case (__ispkg__ == 0), there can't be any sub- # modules present, so we can just return. # # In both cases, since len(parts) == 1, the top_module is also # the "bottom" which is the defined return when a fromlist exists. return top_module importer = top_module.__dict__.get('__importer__') if importer: return importer._finish_import(top_module, parts[1:], fromlist) # If the importer does not exist, then we have to bail. A missing importer # means that something else imported the module, and we have no knowledge # of how to get sub-modules out of the thing. raise ImportError, 'No module named ' + fqname return self.__chain_import(name, globals, locals, fromlist) def _determine_import_context(self, globals): """Returns the context in which a module should be imported. The context could be a loaded (package) module and the imported module will be looked for within that package. The context could also be None, meaning there is no context -- the module should be looked for as a "top-level" module. """ if not globals or not globals.get('__importer__'): # globals does not refer to one of our modules or packages. That # implies there is no relative import context (as far as we are # concerned), and it should just pick it off the standard path. return None # The globals refer to a module or package of ours. It will define # the context of the new import. Get the module/package fqname. parent_fqname = globals['__name__'] # if a package is performing the import, then return itself (imports # refer to pkg contents) if globals['__ispkg__']: parent = sys.modules[parent_fqname] assert globals is parent.__dict__ return parent i = strop.rfind(parent_fqname, '.') # a module outside of a package has no particular import context if i == -1: return None # if a module in a package is performing the import, then return the # package (imports refer to siblings) parent_fqname = parent_fqname[:i] parent = sys.modules[parent_fqname] assert parent.__name__ == parent_fqname return parent def _import_top_module(self, name): # scan sys.path looking for a location in the filesystem that contains # the module, or an Importer object that can import the module. for item in sys.path: if type(item) == _StringType: module = self.fs_imp.import_from_dir(item, name) else: module = item.import_top(name) if module: return module return None def _reload_hook(self, module): "Python calls this hook to reload a module." # reloading of a module may or may not be possible (depending on the # importer), but at least we can validate that it's ours to reload importer = module.__dict__.get('__importer__') if not importer: return self.__chain_reload(module) # okay. it is using the imputil system, and we must delegate it, but # we don't know what to do (yet) ### we should blast the module dict and do another get_code(). need to ### flesh this out and add proper docco... raise SystemError, "reload not yet implemented" class Importer: "Base class for replacing standard import functions." def install(self): sys.path.insert(0, self) def import_top(self, name): "Import a top-level module." return self._import_one(None, name, name) ###################################################################### # # PRIVATE METHODS # def _finish_import(self, top, parts, fromlist): # if "a.b.c" was provided, then load the ".b.c" portion down from # below the top-level module. bottom = self._load_tail(top, parts) # if the form is "import a.b.c", then return "a" if not fromlist: # no fromlist: return the top of the import tree return top # the top module was imported by self. # # this means that the bottom module was also imported by self (just # now, or in the past and we fetched it from sys.modules). # # since we imported/handled the bottom module, this means that we can # also handle its fromlist (and reliably use __ispkg__). # if the bottom node is a package, then (potentially) import some modules. # # note: if it is not a package, then "fromlist" refers to names in # the bottom module rather than modules. # note: for a mix of names and modules in the fromlist, we will # import all modules and insert those into the namespace of # the package module. Python will pick up all fromlist names # from the bottom (package) module; some will be modules that # we imported and stored in the namespace, others are expected # to be present already. if bottom.__ispkg__: self._import_fromlist(bottom, fromlist) # if the form is "from a.b import c, d" then return "b" return bottom def _import_one(self, parent, modname, fqname): "Import a single module." # has the module already been imported? try: return sys.modules[fqname] except KeyError: pass # load the module's code, or fetch the module itself result = self.get_code(parent, modname, fqname) if result is None: return None ### backwards-compat if len(result) == 2: result = result + ({},) module = self._process_result(result, fqname) # insert the module into its parent if parent: setattr(parent, modname, module) return module def _process_result(self, (ispkg, code, values), fqname): # did get_code() return an actual module? (rather than a code object) is_module = type(code) is _ModuleType # use the returned module, or create a new one to exec code into if is_module: module = code else: module = imp.new_module(fqname) ### record packages a bit differently?? module.__importer__ = self module.__ispkg__ = ispkg # insert additional values into the module (before executing the code) module.__dict__.update(values) # the module is almost ready... make it visible sys.modules[fqname] = module # execute the code within the module's namespace if not is_module: exec code in module.__dict__ return module def _load_tail(self, m, parts): """Import the rest of the modules, down from the top-level module. Returns the last module in the dotted list of modules. """ for part in parts: fqname = "%s.%s" % (m.__name__, part) m = self._import_one(m, part, fqname) if not m: raise ImportError, "No module named " + fqname return m def _import_fromlist(self, package, fromlist): 'Import any sub-modules in the "from" list.' # if '*' is present in the fromlist, then look for the '__all__' variable # to find additional items (modules) to import. if '*' in fromlist: fromlist = list(fromlist) + list(package.__dict__.get('__all__', [])) for sub in fromlist: # if the name is already present, then don't try to import it (it # might not be a module!). if sub != '*' and not hasattr(package, sub): subname = "%s.%s" % (package.__name__, sub) submod = self._import_one(package, sub, subname) if not submod: raise ImportError, "cannot import name " + subname def _do_import(self, parent, parts, fromlist): """Attempt to import the module relative to parent. This method is used when the import context specifies that imported the parent module. """ top_name = parts[0] top_fqname = parent.__name__ + '.' + top_name top_module = self._import_one(parent, top_name, top_fqname) if not top_module: # this importer and parent could not find the module (relatively) return None return self._finish_import(top_module, parts[1:], fromlist) ###################################################################### # # METHODS TO OVERRIDE # def get_code(self, parent, modname, fqname): """Find and retrieve the code for the given module. parent specifies a parent module to define a context for importing. It may be None, indicating no particular context for the search. modname specifies a single module (not dotted) within the parent. fqname specifies the fully-qualified module name. This is a (potentially) dotted name from the "root" of the module namespace down to the modname. If there is no parent, then modname==fqname. This method should return None, or a 3-tuple. * If the module was not found, then None should be returned. * The first item of the 2- or 3-tuple should be the integer 0 or 1, specifying whether the module that was found is a package or not. * The second item is the code object for the module (it will be executed within the new module's namespace). This item can also be a fully-loaded module object (e.g. loaded from a shared lib). * The third item is a dictionary of name/value pairs that will be inserted into new module before the code object is executed. This is provided in case the module's code expects certain values (such as where the module was found). When the second item is a module object, then these names/values will be inserted *after* the module has been loaded/initialized. """ raise RuntimeError, "get_code not implemented" ###################################################################### # # Some handy stuff for the Importers # # byte-compiled file suffic character _suffix_char = __debug__ and 'c' or 'o' # byte-compiled file suffix _suffix = '.py' + _suffix_char # the C_EXTENSION suffixes _c_suffixes = filter(lambda x: x[2] == imp.C_EXTENSION, imp.get_suffixes()) def _compile(pathname, timestamp): """Compile (and cache) a Python source file. The file specified by is compiled to a code object and returned. Presuming the appropriate privileges exist, the bytecodes will be saved back to the filesystem for future imports. The source file's modification timestamp must be provided as a Long value. """ codestring = open(pathname, 'r').read() if codestring and codestring[-1] != '\n': codestring = codestring + '\n' code = __builtin__.compile(codestring, pathname, 'exec') # try to cache the compiled code try: f = open(pathname + _suffix_char, 'wb') except IOError: pass else: f.write('\0\0\0\0') f.write(struct.pack(' ':': a = a + ':' return a + b else: raise ImportError, 'no os specific module found' if join is None: def join(a, b, sep=sep): if a == '': return b lastchar = a[-1:] if lastchar == '/' or lastchar == sep: return a + b return a + sep + b global _os_stat _os_stat = stat global _os_path_join _os_path_join = join def _os_path_isdir(pathname): "Local replacement for os.path.isdir()." try: s = _os_stat(pathname) except OSError: return None return (s[0] & 0170000) == 0040000 def _timestamp(pathname): "Return the file modification time as a Long." try: s = _os_stat(pathname) except OSError: return None return long(s[8]) def _fs_import(dir, modname, fqname): "Fetch a module from the filesystem." pathname = _os_path_join(dir, modname) if _os_path_isdir(pathname): values = { '__pkgdir__' : pathname, '__path__' : [ pathname ] } ispkg = 1 pathname = _os_path_join(pathname, '__init__') else: values = { } ispkg = 0 # look for dynload modules for desc in _c_suffixes: file = pathname + desc[0] try: fp = open(file, desc[1]) except IOError: pass else: module = imp.load_module(fqname, fp, file, desc) values['__file__'] = file return 0, module, values t_py = _timestamp(pathname + '.py') t_pyc = _timestamp(pathname + _suffix) if t_py is None and t_pyc is None: return None code = None if t_py is None or (t_pyc is not None and t_pyc >= t_py): file = pathname + _suffix f = open(file, 'rb') if f.read(4) == imp.get_magic(): t = struct.unpack('., where can be located using a subclass-specific mechanism and the is found in the archive using a subclass-specific mechanism. This class defines two hooks for subclasses: one to locate an archive (and possibly return some context for future subfile lookups), and one to locate subfiles. """ def get_code(self, parent, modname, fqname): if parent: # the Importer._finish_import logic ensures that we handle imports # under the top level module (package / archive). assert parent.__importer__ == self # if a parent "package" is provided, then we are importing a sub-file # from the archive. result = self.get_subfile(parent.__archive__, modname) if result is None: return None if type(result) == type(()): return (0,) + result return 0, result # no parent was provided, so the archive should exist somewhere on the # default "path". archive = self.get_archive(modname) if archive is None: return None return 1, "", {'__archive__':archive} def get_archive(self, modname): """Get an archive of modules. This method should locate an archive and return a value which can be used by get_subfile to load modules from it. The value may be a simple pathname, an open file, or a complex object that caches information for future imports. Return None if the archive was not found. """ raise RuntimeError, "get_archive not implemented" def get_subfile(self, archive, modname): """Get code from a subfile in the specified archive. Given the specified archive (as returned by get_archive()), locate and return a code object for the specified module name. A 2-tuple may be returned, consisting of a code object and a dict of name/values to place into the target module. Return None if the subfile was not found. """ raise RuntimeError, "get_subfile not implemented" class PackageArchive(PackageArchiveImporter): "PackageArchiveImporter subclass that refers to a specific archive." def __init__(self, modname, archive_pathname): self.__modname = modname self.__path = archive_pathname def get_archive(self, modname): if modname == self.__modname: return self.__path return None # get_subfile is passed the full pathname of the archive ###################################################################### # # Emulate the standard directory-based import mechanism # class DirectoryImporter(Importer): "Importer subclass to emulate the standard importer." def __init__(self, dir): self.dir = dir def get_code(self, parent, modname, fqname): if parent: dir = parent.__pkgdir__ else: dir = self.dir # defer the loading of OS-related facilities if not _os_stat: _os_bootstrap() # Return the module (and other info) if found in the specified # directory. Otherwise, return None. return _fs_import(dir, modname, fqname) def __repr__(self): return '<%s.%s for "%s" at 0x%x>' % (self.__class__.__module__, self.__class__.__name__, self.dir, id(self)) ###################################################################### # # Emulate the standard path-style import mechanism # class PathImporter(Importer): def __init__(self, path=sys.path): self.path = path # we're definitely going to be importing something in the future, # so let's just load the OS-related facilities. if not _os_stat: _os_bootstrap() def get_code(self, parent, modname, fqname): if parent: # we are looking for a module inside of a specific package return _fs_import(parent.__pkgdir__, modname, fqname) # scan sys.path, looking for the requested module for dir in self.path: result = _fs_import(dir, modname, fqname) if result: return result # not found return None ###################################################################### # # Emulate the import mechanism for builtin and frozen modules # class BuiltinImporter(Importer): def get_code(self, parent, modname, fqname): if parent: # these modules definitely do not occur within a package context return None # look for the module if imp.is_builtin(modname): type = imp.C_BUILTIN elif imp.is_frozen(modname): type = imp.PY_FROZEN else: # not found return None # got it. now load and return it. module = imp.load_module(modname, None, modname, ('', '', type)) return 0, module, { } ###################################################################### # # Internal importer used for importing from the filesystem # class _FilesystemImporter(Importer): def __init__(self, suffixes): # this list is shared with the ImportManager. self.suffixes = suffixes def import_from_dir(self, dir, fqname): result = self._import_pathname(_os_path_join(dir, fqname), fqname) if result: return self._process_result(result, fqname) return None def get_code(self, parent, modname, fqname): # This importer is never used with an empty parent. Its existence is # private to the ImportManager. The ImportManager uses the # import_from_dir() method to import top-level modules/packages. # This method is only used when we look for a module within a package. assert parent return self._import_pathname(_os_path_join(parent.__pkgdir__, modname), fqname) def _import_pathname(self, pathname, fqname): if _os_path_isdir(pathname): result = self._import_pathname(_os_path_join(pathname, '__init__'), fqname) if result: values = result[2] values['__pkgdir__'] = pathname values['__path__'] = [ pathname ] return 1, result[1], values return None for suffix, importer in self.suffixes: filename = pathname + suffix try: finfo = _os_stat(filename) except OSError: pass else: return importer.import_file(filename, finfo, fqname) return None ###################################################################### # # SUFFIX-BASED IMPORTERS # class SuffixImporter: def import_file(self, filename, finfo, fqname): raise RuntimeError class PySuffixImporter(SuffixImporter): def import_file(self, filename, finfo, fqname): file = filename[:-3] + _suffix t_py = long(finfo[8]) t_pyc = _timestamp(file) code = None if t_pyc is not None and t_pyc >= t_py: f = open(file, 'rb') if f.read(4) == imp.get_magic(): t = struct.unpack(' Message-ID: <387095F2.2FA64D8E@lemburg.com> Happy New Year :-) [new imputil.py] I tried the new module with the following code: import imputil,sys if sys.argv[1] != 'standard': print 'Installing imputil...', imputil.ImportManager().install() sys.path.insert(0, imputil.BuiltinImporter()) print 'done.' else: print 'Using builtin importer.' print print 'Importing standard stuff...', import string,re,os,sys print 'done.' print 'Importing mx Extensions...', from mx import DateTime,TextTools,ODBC,HTMLTools,UID,URL print 'done.' ### The new importer does load everything in the test set (top level modules, packages, extensions within packages) without problems on Linux. Some comments: ? Why is the sys.path.insert(0,imputil.BuiltinImporter()) needed in order to get b/w compatibility ? ? Why is there no __path__ aware code in imputil.py (this is definitely needed in order to make it a drop-in replacement) ? ? Performance is still 50% of the Python builtin importer -- a bummer if you ask me. More aggressive caching is definitely needed, perhaps even some recoding of methods in C. ? The old chaining code should be moved into a subclass of its own. ? The code should not import strop directly as this module will probably go away RSN. Use string methods instead. ? The design of the ImportManager has some minor flaws: the FS importer should be settable via class attributes, deinstallation should be possible, a query mechanism to find the importer used by a certain import would also be nice to be able to verify correct setup. ? py/pyc/pyo file piping hooks would be nice to allow imports of signed (and trusted) code and/or encrypted code (a mixin class for these filters would do the trick). ? Wish list: a distutils importer hooked to a list of standard package repositories, a module to file location mapper to speed up file system based imports, -- Marc-Andre Lemburg ______________________________________________________________________ Y2000: Happy New Century ! Business: http://www.lemburg.com/ Python Pages: http://www.lemburg.com/python/ From gstein at lyra.org Mon Jan 3 14:53:00 2000 From: gstein at lyra.org (Greg Stein) Date: Mon, 3 Jan 2000 05:53:00 -0800 (PST) Subject: [Python-Dev] new imputil.py In-Reply-To: <387095F2.2FA64D8E@lemburg.com> Message-ID: Excellent... thanx for the feedback! Comments: On Mon, 3 Jan 2000, M.-A. Lemburg wrote: >... > The new importer does load everything in the test set > (top level modules, packages, extensions within packages) > without problems on Linux. Great! > Some comments: > > ? Why is the sys.path.insert(0,imputil.BuiltinImporter()) > needed in order to get b/w compatibility ? Because I didn't want to build too much knowledge into the ImportManager. Heck, I think adding sys.path removed some of the design elegence; adding real knowledge of builtins... well, we'll just not talk about that. :-) We could certainly do it this way; let's see what Guido says. I'm not truly adverse to it, but I'd recommend against adding a knowledge of BuiltinImporter to the ImportManager. > ? Why is there no __path__ aware code in imputil.py (this is > definitely needed in order to make it a drop-in replacement) ? Because I don't like __path__ :-) I don't think it would be too hard to add, though. If Guido says we need __path__, then I'll add it. I do believe there was a poll a while back where he asked whether anybody truly used it. I don't remember the result and/or Guido's resolution of the matter. > ? Performance is still 50% of the Python builtin importer -- > a bummer if you ask me. More aggressive caching is definitely > needed, perhaps even some recoding of methods in C. I'm scared of caching and the possibility for false positives/negatives. But yes, it is still slower and could use some analysis and/or recoding *if* the speed is a problem. Slower imports does not necessarily mean they are "too slow." > ? The old chaining code should be moved into a subclass of > its own. Good thought. But really: I'd just rather torch it. This kind of depends on whether we can get away with saying the ImportManager is *the* gateway between the interpreter and Python-level import hooks. In other words, will ImportManager be the *only* Python code to ever be allowed to call sys.set_import_hook() ? If the ImportManager doesn't have to "play with other import hooks", then the chaining can be removed altogether. > ? The code should not import strop directly as this module > will probably go away RSN. Use string methods instead. Yah. But I'm running this against 1.5.2 :-) I might be able to do something where the string methods are used if available, and use the strop module if not. [ similar to the 'os' bootstrapping that is done ] Finn Bock emailed me to say that JPython does not have strop, but does have string methods. > ? The design of the ImportManager has some minor flaws: the > FS importer should be settable via class attributes, The class or the object itself? Putting a class in there would be nice, or possibly passing it to the constructor (with a suitable default). This is a good idea, though. Please clarify what you'd like to see, and I'll get it added. > deinstallation > should be possible, Maybe. This is somewhat dependent upon whether it must "play nice." Deinstallation would be quite easy if we move to a sys.get/set style of interface, and it wouldn't be an issue to do de-install code. > a query mechanism to find the importer > used by a certain import would also be nice to be able to > verify correct setup. module.__importer__ provides the importer that was used. This is defined behavior (the system relies on that being set to deal with packages properly). Is this sufficient, or were you looking for something else? module.__ispkg__ is also set to 0/1 accordingly. For backwards compat, __file__ and __path__ are also set. The __all__ attribute in an __init__.py file is used for "from package import *". > ? py/pyc/pyo file piping hooks would be nice to allow > imports of signed (and trusted) code and/or encrypted code > (a mixin class for these filters would do the trick). I'd happily accept a base SuffixImporter class for these "pipes". I don't believe that the ImportManager, Importer, or SuffixImporter base classes would need any changes, though. Note that I probably will rearrange the _fs_import() and friends, per Guido's suggestion to move them into a base class. That may be a step towards having "pipes" available. > ? Wish list: a distutils importer hooked to a list of standard > package repositories, a module to file location mapper to > speed up file system based imports, I'm not sure what the former would do. distutils is still a little nebulous to me right now. For a mapper, we can definitely have a custom Importer that knows where certain modules are found. However, I suspect you're looking for some kind of a cache, but there isn't a hook to say "I found at location" (which would be used to build the mapping). Suggestions on both of these would be most welcome! Cheers, -g -- Greg Stein, http://www.lyra.org/ From gvwilson at nevex.com Mon Jan 3 15:02:32 2000 From: gvwilson at nevex.com (gvwilson at nevex.com) Date: Mon, 3 Jan 2000 09:02:32 -0500 (EST) Subject: [Python-Dev] Software Carpentry: GUI Toolkit? Message-ID: Hi, folks. I'm putting together guidelines for submissions to the Software Carpentry design competition (www.software-carpentry.com), and would like to know what I should recommend as a Python GUI toolkit. As I understand it, the alternatives are: - Tkinter: the "standard" answer, but many people think it's showing its age, and it's an installation and update headaches because of its Tcl dependencies. - some other GUI toolkit: but there's no consensus on which one, and documentation is lacking. - CGI scripts (i.e. all interfaces are web pages): has the virtue of simplicity, but could also make some useful interfaces difficult to build (e.g. no drag and drop), and would require users to run a server, or at least get exec privileges, which can be an installation headache. If I've missed a good answer, or if there's somewhere else I should look for a solution, I'd be grateful for a pointer. Thanks, Greg From jim at interet.com Mon Jan 3 15:31:53 2000 From: jim at interet.com (James C. Ahlstrom) Date: Mon, 03 Jan 2000 09:31:53 -0500 Subject: [Python-Dev] new imputil.py References: Message-ID: <3870B2D9.31D0D350@interet.com> Greg Stein wrote: > I've attached a new imputil.py to this message. It isn't posted on my page I don't think you should be using "public domain" as a copyright because you should be protecting the code. Better to use "all rights transferred to CNRI pursuant to the Python contribution agreement", or just copyright it yourself for now. You didn't incorporate the ZipImporter in ftp://ftp.interet.com/pub/importer.py Is that because you want me to, or doesn't it work? JimA From gmcm at hypernet.com Mon Jan 3 15:38:11 2000 From: gmcm at hypernet.com (Gordon McMillan) Date: Mon, 3 Jan 2000 09:38:11 -0500 Subject: [Python-Dev] new imputil.py In-Reply-To: References: <387095F2.2FA64D8E@lemburg.com> Message-ID: <1265213088-25101227@hypernet.com> Greg Stein wrote: > On Mon, 3 Jan 2000, M.-A. Lemburg wrote: [big snip] > > ? Wish list: a distutils importer hooked to a list of standard > > package repositories, a module to file location mapper to speed > > up file system based imports, > For a mapper, we can definitely have a custom Importer that knows > where certain modules are found. However, I suspect you're > looking for some kind of a cache, but there isn't a hook to say > "I found at location" (which would be used to build > the mapping). > > Suggestions on both of these would be most welcome! Haven't played with the new one yet. But for awhile I've been considering a scheme where sys.path[0] has a cache of known binary extensions { logicalname: fullpath, ... } and sys.path[-1] is the brute force importer. For standalones, sys.path[0] could be hardcoded. For normal installations, sys.path[-1] could inform sys.path[0] when a .so / .dll / .pyd is found. So when a new one is installed, the first use will be expensive, but subsequent sessions would import it in 1 I/O. I'd also like to point out that archives *can* be used in a development situation. Obviously I wouldn't bother putting a module under current development into an archive. But if the source is still installed and you haven't mucked with the __file__ attribute when you put it in the archive, then tracebacks will show you what you need. IDLE doesn't know the difference. So for most developers, the standard library can be served from an archive with no effect (other than speed). - Gordon From gstein at lyra.org Mon Jan 3 15:57:35 2000 From: gstein at lyra.org (Greg Stein) Date: Mon, 3 Jan 2000 06:57:35 -0800 (PST) Subject: [Python-Dev] new imputil.py In-Reply-To: <3870B2D9.31D0D350@interet.com> Message-ID: On Mon, 3 Jan 2000, James C. Ahlstrom wrote: > Greg Stein wrote: > > I've attached a new imputil.py to this message. It isn't posted on my page > > I don't think you should be using "public domain" as a > copyright because you should be protecting the code. > Better to use "all rights transferred to CNRI pursuant > to the Python contribution agreement", or just copyright > it yourself for now. Public Domain means there are no copyrights on the code. Anybody can claim copyright to it. Anybody can start with my version, slap their name and license on it, and do as they wish. There isn't a way for anybody to "control" public domain software, so there is no need for protection. I like to use Public Domain for code that I want to see as broadly used as possible and/or for short things. There is also a lot that I just don't care what happens with it. If I don't have a vested interest in something, then PD is fine. I wrote imputil as a tool for myself. It isn't something that I feel a need to keep my name on it -- it works for me, it does what I want, it doesn't matter what others do it. It does matter than other people *can* do stuff with it, and PD gives them the most options. Shades of grey... hard to fully explain in an email... but that's the general sentiment. I've got a few things under other licenses, but PD seemed best for imputil. > You didn't incorporate the ZipImporter in > ftp://ftp.interet.com/pub/importer.py > Is that because you want me to, or doesn't it work? I had the redesign to do first. When that settles towards something that Guido is happy with (or he has decided to punt the design altogether), then I'll integrate the ZipImporter. Cheers, -g -- Greg Stein, http://www.lyra.org/ From fdrake at acm.org Mon Jan 3 21:05:22 2000 From: fdrake at acm.org (Fred L. Drake, Jr.) Date: Mon, 3 Jan 2000 15:05:22 -0500 (EST) Subject: [Python-Dev] new imputil.py In-Reply-To: <1265213088-25101227@hypernet.com> References: <387095F2.2FA64D8E@lemburg.com> <1265213088-25101227@hypernet.com> Message-ID: <14449.258.374018.919406@weyr.cnri.reston.va.us> Gordon McMillan writes: > I'd also like to point out that archives *can* be used in a > development situation. Obviously I wouldn't bother putting a > module under current development into an archive. But if the > source is still installed and you haven't mucked with the > __file__ attribute when you put it in the archive, then > tracebacks will show you what you need. IDLE doesn't know > the difference. So for most developers, the standard library > can be served from an archive with no effect (other than speed). I don't see why we can't just add the source to the archive as well; this would allow proper tracebacks even outside the development of the library. Not including sources would cleanly result in the same situation as we currently see when there's only a .pyc file. Am I missing something fundamental? -Fred -- Fred L. Drake, Jr. Corporation for National Research Initiatives From mal at lemburg.com Mon Jan 3 19:22:02 2000 From: mal at lemburg.com (M.-A. Lemburg) Date: Mon, 03 Jan 2000 19:22:02 +0100 Subject: [Python-Dev] Better text processing support in py2k? References: <000901bf53e1$eb4248c0$472d153f@tim> Message-ID: <3870E8CA.7294B813@lemburg.com> Tim Peters wrote: > > >> This is why I do complex string processing in Icon <0.9 wink>. > > [MAL] > > You can have all that extra magic via callable tag objects > > or callable matching functions. It's not exactly nice to > > write, but I'm sure that a meta-language could do the > > conversions for you. > > That wasn't my point: I do it in Icon because it *is* "exactly nice to > write", and doesn't require any yet-another meta-language. It's all > straightforward, in a way that separate schemes pasted together can never be > (simply because they *are* "separate schemes pasted together" ). > > The point of my Python examples wasn't that they could do something > mxTextTools can't do, but that they were *Python* examples: every variation > I mentioned (or that you're likely to think of) was easy to handle for any > Python programmer because the "control flow" and "data type" etc aspects > could be handled exactly the way they always are in *non* pattern-matching > Python code too, rather than recoded in pattern-scheme-specific different > ways (e.g., where I had a vanailla "if/break", you set up a special > exception to tickle the matching engine). > > I'm not attacking mxTextTools, so don't feel compelled to defend it -- Oh, I wasn't defending it -- I know that it is cryptic and sometimes a pain to use. But given that you don't have to invoke a C compiler to get a raw speed I find it a rather useful alternative to code fast utility functions which would otherwise have to be written in C. The other reason it exists is simply because I don't like the recursive style of regexps too much. mxTextTools is simple and straightforward. Backtracking is still possible, but not recommended. > people using regexps in those examples are dead in the water. mxTextTools > is very good at what it does; if we have a real disagreement, it's probably > that I'm less optimistic about the prospects for higher-level wrappers > (e.g., MikeF's SimpleParse is much slower than "a real" BNF parsing system > (ARBNFPS), in part because he isn't doing all the optimizations ARBNFPS > does, but also in part because ARBNFPS uses an underlying engine more > optimized to its specific task than mxTextTool's more-general engine *can* > be). So I don't see mxTextTools as being the answer to everything -- and if > you hadn't written it, you would agree with that on first glance . Oh, I'm sure it *is* the answer to all out problems ;-) ... def main(*dummy): ... from mx.TextTools import * tag("",((main, Skip + CallTag, 0),)) > > Anyway, I'll keep focussing on the speed aspect of mxTextTools; > > others can focus on abstractions, so that eventually everybody > > will be happy :-) > > You and I will be, anyway . Happy New Year :-) -- Marc-Andre Lemburg ______________________________________________________________________ Y2000: Happy New Century ! Business: http://www.lemburg.com/ Python Pages: http://www.lemburg.com/python/ From mal at lemburg.com Tue Jan 4 19:36:00 2000 From: mal at lemburg.com (M.-A. Lemburg) Date: Tue, 04 Jan 2000 19:36:00 +0100 Subject: [Python-Dev] new imputil.py References: Message-ID: <38723D90.D2AE1CA4@lemburg.com> Greg Stein wrote: > > Comments: > > On Mon, 3 Jan 2000, M.-A. Lemburg wrote: > >... > > The new importer does load everything in the test set > > (top level modules, packages, extensions within packages) > > without problems on Linux. > > Great! > > > Some comments: > > > > ? Why is the sys.path.insert(0,imputil.BuiltinImporter()) > > needed in order to get b/w compatibility ? > > Because I didn't want to build too much knowledge into the ImportManager. > Heck, I think adding sys.path removed some of the design elegence; adding > real knowledge of builtins... well, we'll just not talk about that. :-) > > We could certainly do it this way; let's see what Guido says. I'm not > truly adverse to it, but I'd recommend against adding a knowledge of > BuiltinImporter to the ImportManager. I was under the impression that the ImportManager should replace the current implementation. In that light it should of course provide all the needed techniques per default without the need to tweak sys.path. > > ? Why is there no __path__ aware code in imputil.py (this is > > definitely needed in order to make it a drop-in replacement) ? > > Because I don't like __path__ :-) I don't think it would be too hard to > add, though. > > If Guido says we need __path__, then I'll add it. I do believe there was a > poll a while back where he asked whether anybody truly used it. I don't > remember the result and/or Guido's resolution of the matter. AFAIK, JimF is using it in Zope. I will use it in the b/w compatibility package for the soon to be released mx Extensions packages (instead of using relative imports, BTW -- can't wait for those to happen). > > ? Performance is still 50% of the Python builtin importer -- > > a bummer if you ask me. More aggressive caching is definitely > > needed, perhaps even some recoding of methods in C. > > I'm scared of caching and the possibility for false positives/negatives. > > But yes, it is still slower and could use some analysis and/or recoding > *if* the speed is a problem. Slower imports does not necessarily mean they > are "too slow." There has been some moaning about the current Python startup speed, so I guess people already find the existing strategy too slow. Anyway, put the cache risks into the user's hands and have them decide whether or not to use them. The important thing is providing a standard approach to caching which all importers can use and hook into rather than having three or four separate cache implementations. > > ? The old chaining code should be moved into a subclass of > > its own. > > Good thought. But really: I'd just rather torch it. This kind of depends > on whether we can get away with saying the ImportManager is *the* gateway > between the interpreter and Python-level import hooks. In other words, > will ImportManager be the *only* Python code to ever be allowed to call > sys.set_import_hook() ? If the ImportManager doesn't have to "play with > other import hooks", then the chaining can be removed altogether. Hmm, nuking the chains might cause some problems with code using the old ni.py or other code such as my old ClassModules.py module which emulates modules using classes (provides all the cool __getattr__ and __setattr__ features to modules as well). > > ? The code should not import strop directly as this module > > will probably go away RSN. Use string methods instead. > > Yah. But I'm running this against 1.5.2 :-) > > I might be able to do something where the string methods are used if > available, and use the strop module if not. > [ similar to the 'os' bootstrapping that is done ] > > Finn Bock emailed me to say that JPython does not have strop, but does > have string methods. Since imputil.py targets 1.6 you can safely assume that string methods are in place. > > ? The design of the ImportManager has some minor flaws: the > > FS importer should be settable via class attributes, > > The class or the object itself? Putting a class in there would be nice, or > possibly passing it to the constructor (with a suitable default). > > This is a good idea, though. Please clarify what you'd like to see, and > I'll get it added. I usually put these things into the class so that subclasses can easily override the setting. > > deinstallation > > should be possible, > > Maybe. This is somewhat dependent upon whether it must "play nice." > Deinstallation would be quite easy if we move to a sys.get/set style of > interface, and it wouldn't be an issue to do de-install code. I was thinking mainly of debugging situations where you play around with new importer code -- its probably not important for production code. > > a query mechanism to find the importer > > used by a certain import would also be nice to be able to > > verify correct setup. > > module.__importer__ provides the importer that was used. This is defined > behavior (the system relies on that being set to deal with packages > properly). > > Is this sufficient, or were you looking for something else? I was thinking of a situations like: if : or if : raise SystemError,'wrong setup' Don't know if these queries are possible with the current flags and attributes. > module.__ispkg__ is also set to 0/1 accordingly. > > For backwards compat, __file__ and __path__ are also set. The __all__ > attribute in an __init__.py file is used for "from package import *". > > > ? py/pyc/pyo file piping hooks would be nice to allow > > imports of signed (and trusted) code and/or encrypted code > > (a mixin class for these filters would do the trick). > > I'd happily accept a base SuffixImporter class for these "pipes". I don't > believe that the ImportManager, Importer, or SuffixImporter base classes > would need any changes, though. > > Note that I probably will rearrange the _fs_import() and friends, per > Guido's suggestion to move them into a base class. That may be a step > towards having "pipes" available. It would be nice to be able to use the concept of stackable streams as source for byte and source code. For this to work one would have to make the file reading process a little more abstract by using e.g. a StreamReader instead (see the current unicode-proposal.txt version). > > ? Wish list: a distutils importer hooked to a list of standard > > package repositories, a module to file location mapper to > > speed up file system based imports, > > I'm not sure what the former would do. distutils is still a little > nebulous to me right now. Basically it should scan a set of URLs providing access to package repositories which hold distutils installable package archives. In case it finds a suitable package it should then proceed to auto-install it and then continue the normal import process. > For a mapper, we can definitely have a custom Importer that knows where > certain modules are found. However, I suspect you're looking for some kind > of a cache, but there isn't a hook to say "I found at > location" (which would be used to build the mapping). Right. I would like to see some standard mechanism used throughout the ImportManager for this. One which all importers can use and rely on. E.g. it would be nice to have an option to load the cache from disk upon startup to reduce search times. All this should be left for the user to configure with the standard setting being no cache at all (to avoid confusion and reduce support costs ;-). -- Marc-Andre Lemburg ______________________________________________________________________ Y2000: Happy New Century ! Business: http://www.lemburg.com/ Python Pages: http://www.lemburg.com/python/ From bwarsaw at cnri.reston.va.us Tue Jan 4 22:04:48 2000 From: bwarsaw at cnri.reston.va.us (Barry A. Warsaw) Date: Tue, 4 Jan 2000 16:04:48 -0500 (EST) Subject: [Python-Dev] new imputil.py References: Message-ID: <14450.24688.492098.917284@anthem.cnri.reston.va.us> Happy New Year! >>>>> "GS" == Greg Stein writes: GS> I think Python 1.6 should drop the __import__ builtin and move GS> to something like sys.import_hook (to allow examination and GS> change). Wait! You can't remove builtin __import__ without breaking code. E.g. Mailman uses __import__ quite a bit in its CGI (and other) harnesses. Why does __import__ need to be removed? Why can't it just just the same mechanism the import statement uses? GS> I might be able to do something where the string methods are GS> used if available, and use the strop module if not. [ similar GS> to the 'os' bootstrapping that is done ] GS> Finn Bock emailed me to say that JPython does not have strop, GS> but does have string methods. Sorry Greg, I haven't had time to look at this stuff at all, so maybe I'm missing something essential, but if you just continue to use the string module, you'll be fine for JPython and CPython 1.5.2. In CPython 1.5.2, you /will/ actually be using the strop module under the covers. In CPython 1.6 and JPython 1.1 you'll be using string methods under the covers. Your penalty is one layer of Python function calls. Never use strop directly though. >>>>> "MA" == M writes: MA> There has been some moaning about the current Python startup MA> speed, so I guess people already find the existing strategy MA> too slow. Definitely. -Barry From gmcm at hypernet.com Wed Jan 5 04:49:08 2000 From: gmcm at hypernet.com (Gordon McMillan) Date: Tue, 4 Jan 2000 22:49:08 -0500 Subject: [Python-Dev] new imputil.py In-Reply-To: <14449.258.374018.919406@weyr.cnri.reston.va.us> References: <1265213088-25101227@hypernet.com> Message-ID: <1265079245-1617919@hypernet.com> Fred L. Drake, Jr.wrote: > Gordon McMillan writes: > > I'd also like to point out that archives *can* be used in a > > development situation. Obviously I wouldn't bother putting a > > module under current development into an archive. But if the > > source is still installed and you haven't mucked with the > > __file__ attribute when you put it in the archive, then > > tracebacks will show you what you need. IDLE doesn't know > the > difference. So for most developers, the standard library > can > be served from an archive with no effect (other than speed). > > I don't see why we can't just add the source to the archive as > well; > this would allow proper tracebacks even outside the development > of the library. Not including sources would cleanly result in > the same situation as we currently see when there's only a .pyc > file. > Am I missing something fundamental? Sure you could. Then you could patch IDLE, Pythonwin, etc. to open the proper archive and extract the source. Then you could patch them (and archive) to update on the fly. And while you're at it, I'd really like a jacuzzi jet that gets my neck and shoulders without having to scrunch into all kinds of strange positions. - Gordon Return-Path: Delivered-To: python-dev at dinsdale.python.org Received: from python.org (parrot.python.org [132.151.1.90]) by dinsdale.python.org (Postfix) with ESMTP id A76701CD65 for ; Fri, 14 Jan 2000 12:39:29 -0500 (EST) Received: from merlin.codesourcery.com (IDENT:qmailr@[206.168.99.1]) by python.org (8.9.1a/8.9.1) with SMTP id MAA17463 for ; Fri, 14 Jan 2000 12:39:29 -0500 (EST) Received: (qmail 2115 invoked by uid 513); 14 Jan 2000 17:44:23 -0000 Mailing-List: contact publicity-help at software-carpentry.com; run by ezmlm Delivered-To: mailing list publicity at software-carpentry.com Received: (qmail 2110 invoked from network); 14 Jan 2000 17:44:19 -0000 Date: Fri, 14 Jan 2000 12:40:13 -0500 (EST) From: gvwilson at nevex.com To: publicity at software-carpentry.com Message-ID: MIME-Version: 1.0 Content-Type: MULTIPART/MIXED; BOUNDARY="168427786-1646135556-947871613=:8785" Subject: [Python-Dev] ANNOUNCEMENT: Open Source Design Competition Sender: python-dev-admin at python.org Errors-To: python-dev-admin at python.org X-BeenThere: python-dev at python.org X-Mailman-Version: 1.2 (experimental) Precedence: bulk List-Id: Python core developers This message is in MIME format. The first part should be readable text, while the remaining parts are likely unreadable without MIME-aware tools. Send mail to mime at docserver.cac.washington.edu for more info. --168427786-1646135556-947871613=:8785 Content-Type: TEXT/PLAIN; charset=US-ASCII The Software Carpentry project is pleased to announce the launch of its first Open Source design competition. The project's logo is attached, and details of the competition are included below. This message is being sent to you because you have expressed an interest in covering this story, or publicizing this project. If you have any questions, or do not wish to receive future notices about Software Carpentry, please contact: Dr. Gregory V. Wilson Software Carpentry Project Coordinator (416) 593 2428 gvwilson at software-carpentry.com Thanks for your interest! Greg Wilson ---------------------------------------------------------------------- ---------------------------------------------------------------------- Los Alamos National Laboratory Code Sourcery, LLC Software Carpentry Open Source Design Competition $100,000 in Prizes! ---------------------------------------------------------------------- The Software Carpentry project is pleased to announce its first Open Source design competition, with prizes totaling $100,000. Students and professionals from any country, working individually or in teams, are invited to submit design outlines for: * a platform inspection tool to replace autoconf; * a dependency management tool to replace make; * an issue tracking system to replace gnats and Bugzilla; and * a unit and regression testing harness with the functionality of XUnit, Expect, and DejaGnu. Participants may submit separate entries in one or more categories by March 31, 2000. Entries must be in English, and no more than 5000 words long; examples are available at http://www.software-carpentry.com. The competition will be judged by a panel that includes the following noted software developers, authors, and computational scientists: Stephen Adler Brookhaven National Laboratory Frank Alexander Los Alamos National Laboratory Donnie Barnes Red Hat Chris DiBona VA Linux Paul Dubois Lawrence Livermore National Laboratory Andrew Hunt Pragmatic Programmers, LLC Stephen R. Lee Los Alamos National Laboratory Josh MacDonald University of California, Berkeley Brian Marick Reliable Software Technologies Doug Mewhort Queen's University Bruce Perens co-founder of the Open Source Initiative Dave Thomas Pragmatic Programmers, LLC Jon Udell author of Practical Internet Groupware Guido van Rossum inventor of Python Tom Van Vleck TransIlluminant Phil Wadler Bell Labs Scot Wingo AuctionRover The best four entries in each category will be awarded $2500, and invited to submit full designs by June 1, 2000. The best design in each category will then receive an additional $7500, while runners-up will each receive $2500. Once winning designs have been announced, $200,000 will be available through open bidding for implementation, testing, and documentation. All of the project's work will be Open Source; all tools will be written in, or scriptable with, Python, and will be required to run on both Linux and Microsoft Windows NT. ---------------------------------------------------------------------- The Software Carpentry project is sponsored by the Advanced Computing Laboratory at the U.S. Department of Energy's Los Alamos National Laboratory (http://www.acl.lanl.gov), and administered by Code Sourcery, LLC (http://www.codesourcery.com). The project's aim is to encourage adoption of better software development practices by making software tools easier to use, and by documenting design, testing, and related activities. For more information on the project, or to let us know that you intend to submit a proposal, see http://www.software-carpentry.com, or mail info at software-carpentry.com. --168427786-1646135556-947871613=:8785 Content-Type: IMAGE/GIF; name="software-carpentry-logo.gif" Content-Transfer-Encoding: BASE64 Content-ID: Content-Description: Content-Disposition: attachment; filename="software-carpentry-logo.gif" R0lGODlhLAGhANX/AIACFYU8R2RkZqWlp0pKS+np6tXV1snJyr+/wLW2u+Dh 5srM1Pf4/PT1+e7v877Ax4GDiZygq6Sos4yPl5aZobm7wNrc4aywuXF0efv8 /M7PzywtLJF8U0s4F6mTa76pgXBeQE0+LeDb2M7JxsfAvaCPi7yysJBxb7Ge nf////7+/v39/fv7+/n5+fj4+Pb29vPz8/Ly8u/v7+3t7ebm5uLi4t3d3dnZ 2dLS0sXFxa6urh4eHg8PDwgICAMDAwAAACwAAAAALAGhAEAG/8CUcEgsGo/I pHLJbDqf0Kh0Sq1ar9isdsvter/gsFipcjXLQ1aBhtDg3m/NLdN0rZotVpPV aq7MTH9OLipFOSgxRXZ4dEx5e3pMLJFLGYBLgkxld0yLjpRKj0ktM4VEMgk6 FRcQGBILCrELEwITCRe4uRgEBAICvLwYF6sJEjV9RC4yRjKJRCwzoCkxy0QZ BdIupUUzL0WkpkMyMEUrMnQ2HOoeHh/u7OocJi8uOiEgNUYzAhsbO/0EMPDb UKFQDG/WYtjYEKJfCF4gfIEgQCOGtBfOhqiYcUmINmYIh7SQEU4ItSIZohWB UW3IigLIRM7gJI7csxmNaip5QYNmEv8XNKRV2EBBxYAdDNSETLKChs0lNTRU OFIBgqkZBZrA6MmEp7QiKOJxaDcihQsDJFCUKAHhBIgOHULEKGmEBoF//XYE HDhhhYoCLZXIKKADAwQlJ1sgmNBKgEDHkIsy2ZozCQsaHZFcXpoEcJMCMwTb ALWiRlYiMGx0/BtBQtaiLWxkFDKjhk8WNgKnmGGDZoFYFiwUFPLiBgRftf7S UGTjqRAZo4mUPj1EYcwUKmhoEABiLAEIE2h15/BWQGsJEnANuFGkQA1QGWjY zbvBVz8KQqavVE0kO42SL9jAmXu35bYSCnB15wEJNYR2SnRE0FBDSS40196E RMSWAAUYTHD/zAET2BCOCqbtl5l8ShRwA2dHyHCDc0JQcEEBKsBmgIOh3EAd Ei48oMABQjQgwQY//CCMQAqkUIOITKh4HRIz3HDJDOCBF94EFGQZwZbopYfL A/iZpWMnNmQ1UH13IZCGDRgqUVpvS5AIYYqjIQBXBwpyI+USF0TgCwQX3HJB el12GcFxyGG5I3Y2LIcdBCOscINhBVAAgwpsKlEDDoG1YMANoBSAw464UeBa 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 d8M73tIIAgA7 --168427786-1646135556-947871613=:8785-- From jeremy at cnri.reston.va.us Mon Jan 17 21:35:37 2000 From: jeremy at cnri.reston.va.us (Jeremy Hylton) Date: Mon, 17 Jan 2000 15:35:37 -0500 (EST) Subject: [Python-Dev] developers day session on compilers Message-ID: <14467.32025.761662.841271@goon.cnri.reston.va.us> I am championing a Developers' Day session on a Python compiler. There is a short Web page describing the goals of the session at http://www.python.org/workshops/2000-01/compiler.html. I'd appreciate feedback on the content and format of the session. If you have ideas for what we should talk about or do, please followup to me or to the list. Jeremy From mal at lemburg.com Tue Jan 18 23:55:04 2000 From: mal at lemburg.com (M.-A. Lemburg) Date: Tue, 18 Jan 2000 23:55:04 +0100 Subject: [Python-Dev] Python Tools/ Message-ID: <3884EF48.A6107775@lemburg.com> I was just looking through the Tools dir of the CVS version (looking for a tool which autoexpands tabs in Python source files -- which I didn't find) and found some other useful scripts along the way. To my surprise these executable files did not have a .py extension even though were Python source files. Is this intended ? I find that scripts like "world" provide useful information which would be nice to have in the standard lib -- with .py extension... Other tidbits: I noted that at least in my CVS tree the Tools/ht2html dir does not include any executable: have I missed something ? The script Tools/scripts/parseentities.py is not executable for some reason. -- Marc-Andre Lemburg ______________________________________________________________________ Business: http://www.lemburg.com/ Python Pages: http://www.lemburg.com/python/ From guido at CNRI.Reston.VA.US Wed Jan 19 13:50:05 2000 From: guido at CNRI.Reston.VA.US (Guido van Rossum) Date: Wed, 19 Jan 2000 07:50:05 -0500 Subject: [Python-Dev] Python Tools/ In-Reply-To: Your message of "Tue, 18 Jan 2000 23:55:04 +0100." <3884EF48.A6107775@lemburg.com> References: <3884EF48.A6107775@lemburg.com> Message-ID: <200001191250.HAA18786@eric.cnri.reston.va.us> > I was just looking through the Tools dir of the CVS version > (looking for a tool which autoexpands tabs in Python source > files -- which I didn't find) and found some other useful scripts > along the way. > > To my surprise these executable files did not have a .py > extension even though were Python source files. Is this > intended ? I find that scripts like "world" provide useful > information which would be nice to have in the standard > lib -- with .py extension... I would agree, but that's Barry's creation, so I'll let him answer for himself. Any other scripts with the same problem? > Other tidbits: > > I noted that at least in my CVS tree the Tools/ht2html > dir does not include any executable: have I missed something ? Actually, that directory is a ghost and shouldn't have been exported at all. (Barry, can you erase it from sweetpea?) > The script Tools/scripts/parseentities.py is not executable > for some reason. Fixed now. --Guido van Rossum (home page: http://www.python.org/~guido/) From bwarsaw at cnri.reston.va.us Wed Jan 19 17:24:41 2000 From: bwarsaw at cnri.reston.va.us (Barry A. Warsaw) Date: Wed, 19 Jan 2000 11:24:41 -0500 (EST) Subject: [Python-Dev] Python Tools/ References: <3884EF48.A6107775@lemburg.com> Message-ID: <14469.58697.116588.501355@anthem.cnri.reston.va.us> >>>>> "M" == M writes: M> To my surprise these executable files did not have a .py M> extension even though were Python source files. Is this M> intended ? I find that scripts like "world" provide useful M> information which would be nice to have in the standard M> lib -- with .py extension... I hadn't thought about making world a module, but if others agree, I can play a little CVS magic to move the file to world.py. M> I noted that at least in my CVS tree the Tools/ht2html dir does M> not include any executable: have I missed something ? If you do a `cvs up -P' (-P for prune) you'll find that that directory goes away. At one point I started to add the ht2html scripts to the Python tools, but then we decided not to. Unfortunately, once a directory's been added to CVS it can never be removed (hence -P). If you're really interested in the ht2html scripts, which are used to build the Python.Org and JPython.Org sites (as well as my personal pages), please see http://www.python.org/~bwarsaw/software/pyware.html -Barry From bwarsaw at cnri.reston.va.us Wed Jan 19 18:32:50 2000 From: bwarsaw at cnri.reston.va.us (Barry A. Warsaw) Date: Wed, 19 Jan 2000 12:32:50 -0500 (EST) Subject: [Python-Dev] Python Tools/ References: <3884EF48.A6107775@lemburg.com> <14469.58697.116588.501355@anthem.cnri.reston.va.us> Message-ID: <14469.62786.178265.983781@anthem.cnri.reston.va.us> >>>>> "BAW" == Barry A Warsaw writes: BAW> If you do a `cvs up -P' (-P for prune) you'll find that that BAW> directory goes away. At one point I started to add the BAW> ht2html scripts to the Python tools, but then we decided not BAW> to. Unfortunately, once a directory's been added to CVS it BAW> can never be removed (hence -P). I just check this and there is no ht2html directory in Tools anymore. We probably did remove it after you (MAL) had checked it out. You can either ignore the directory, or delete it from your working dirs. If cvs complains after deleting it, you may have to manually edit the CVS/Entries file. Sorry about that -- we know better now. -Barry From gerrit.holl at pobox.com Wed Jan 19 21:14:27 2000 From: gerrit.holl at pobox.com (Gerrit Holl) Date: Wed, 19 Jan 2000 21:14:27 +0100 Subject: [Python-Dev] ''.join in 1.6 Message-ID: <20000119211427.A3755@stopcontact.palga.uucp> Hello, I have a question/suggestion about ''.join in Python 1.6. Suppose I have this list: l = ["This", "is", "a", "test"] Currently, I would join it this way into a tab-delimeted string: s = string.join(l, '\t') In 1.6, I should do it this way: '\t'.join(s) I think it would be better to have that method on the *list*: s.join('\t') That's more clear, isn't it? regards, Gerrit. -- Please correct any bad English you encounter in my email message! -----BEGIN GEEK CODE BLOCK----- http://www.geekcode.com Version: 3.12 GCS dpu s-:-- a14 C++++>$ UL++ P--- L+++ E--- W++ N o? K? w--- !O !M !V PS+ PE? Y? PGP-- t- 5? X? R- tv- b+(++) DI D+ G++ !e !r !y -----END GEEK CODE BLOCK----- From fredrik at pythonware.com Wed Jan 19 21:43:36 2000 From: fredrik at pythonware.com (Fredrik Lundh) Date: Wed, 19 Jan 2000 21:43:36 +0100 Subject: [Python-Dev] ''.join in 1.6 References: <20000119211427.A3755@stopcontact.palga.uucp> Message-ID: <005e01bf62bd$dc8073d0$f29b12c2@secret.pythonware.com> > In 1.6, I should do it this way: > '\t'.join(s) > > I think it would be better to have that method on the *list*: > s.join('\t') > > That's more clear, isn't it? what if "s" is a tuple? an array? a user-defined sequence type? From bwarsaw at cnri.reston.va.us Wed Jan 19 21:36:24 2000 From: bwarsaw at cnri.reston.va.us (Barry A. Warsaw) Date: Wed, 19 Jan 2000 15:36:24 -0500 (EST) Subject: [Python-Dev] ''.join in 1.6 References: <20000119211427.A3755@stopcontact.palga.uucp> Message-ID: <14470.8264.686274.888365@anthem.cnri.reston.va.us> >>>>> "GH" == Gerrit Holl writes: GH> I think it would be better to have that method on the *list*: GH> s.join('\t') GH> That's more clear, isn't it? Perhaps, but you want join to work on any sequence don't you? By making it a method on string objects, you sort of get that for free (as opposed to putting it on lists, sequences, and requiring all class authors to add it as well). -Barry From da at ski.org Wed Jan 19 21:54:03 2000 From: da at ski.org (David Ascher) Date: Wed, 19 Jan 2000 12:54:03 -0800 Subject: [Python-Dev] ''.join in 1.6 In-Reply-To: <20000119211427.A3755@stopcontact.palga.uucp> Message-ID: <003b01bf62bf$5191abc0$c355cfc0@ski.org> Gerrit Holl > Currently, I would join it this way into a tab-delimeted string: > s = string.join(l, '\t') > > In 1.6, I should do it this way: > '\t'.join(s) > > I think it would be better to have that method on the *list*: > s.join('\t') > > That's more clear, isn't it? As Tim pointed out when they were discussed, the clearest way to express it with the new methods is to do: tab = '\t' tab.join(s) Similarly space = ' ' space.join(s) etc. --david ascher From da at ski.org Wed Jan 19 23:41:47 2000 From: da at ski.org (David Ascher) Date: Wed, 19 Jan 2000 14:41:47 -0800 Subject: [Python-Dev] SOAP Message-ID: <000101bf62ce$5e509e70$c355cfc0@ski.org> Who if anyone is working on SOAP clients and servers for Python? --david ascher -------------- next part -------------- A non-text attachment was scrubbed... Name: David Ascher.vcf Type: text/x-vcard Size: 527 bytes Desc: not available URL: From amk1 at erols.com Thu Jan 20 05:19:33 2000 From: amk1 at erols.com (A.M. Kuchling) Date: Wed, 19 Jan 2000 23:19:33 -0500 Subject: [Python-Dev] Changing existing class instances Message-ID: <200001200419.XAA01969@mira.erols.com> Currently, when you replace a class definition with an updated version, it's really difficult to change existing class instances; you'd have to essentially sweep every Python object and check if it's an instance, starting at roots such as __main__ and sys.modules. This makes developing code in a long-running process difficult, Zope being the best example of this. When you modify a class definition used by Zope code, you can't update existing instances floating around in memory. Over dinner, a friend and I were discussing this, and we thought it probably isn't difficult to add an extra level of indirection to allow fixing this. The only other option we could think of is either the complete scan of all objects, or inserting a forwarding pointer into PyClassObjects that points to the replacing class if !NULL, and then chase pointers when accessing PyInstanceObject->in_class. A quick hack to implement the extra indirection took about half an hour. It does these things: * Defines a PyClassHandle type: struct _PyClassHandle { PyClassHandle *next; /* ptr to next PyClassHandle in linked list */ PyClassObject *klass; /* The class object */ } ; * The in_class attribute of PyInstanceObject becomes a PyClassHandle* instead of a PyClassObject*, and all code such as inst->in_class becomes inst->in_class->klass. * As a quick hack to allow changing the class object referenced by a handle, I added a .forward( ) method to class objects. This basically does self.handle->klass = . The end result is that obj.__class__.forward(newclass) changes obj to be an instance of newclass, and all other instances of obj.__class__ also mutate to become newclass instances. Making this purely automatic seems hard; you'd have to catch things like 'import ftplib; ftplib.FTP = myclass', which would require automatically calling ftplib.FTP.forward( myclass ) to make all existing FTP instances mutate. Would it be worthwhile to export some hook for doing this in 1.6? The cost is adding an extra pointer deref to all access to PyInstanceObject->in_class. (This could probably also be added to ExtensionClass, and probably doesn't need to be added to core Python to help out Zope. Just a thought...) -- A.M. Kuchling http://starship.python.net/crew/amk/ Here the skull of a consumptive child becomes part of a great machine for calculating the motions of the stars. Here, a yellow bird frets within the ribcage of an unjust man. -- Welcome to Orqwith, in DOOM PATROL #22 From guido at CNRI.Reston.VA.US Thu Jan 20 05:41:29 2000 From: guido at CNRI.Reston.VA.US (Guido van Rossum) Date: Wed, 19 Jan 2000 23:41:29 -0500 Subject: [Python-Dev] Changing existing class instances In-Reply-To: Your message of "Wed, 19 Jan 2000 23:19:33 EST." <200001200419.XAA01969@mira.erols.com> References: <200001200419.XAA01969@mira.erols.com> Message-ID: <200001200441.XAA20952@eric.cnri.reston.va.us> > Currently, when you replace a class definition with an updated > version, it's really difficult to change existing class instances; > you'd have to essentially sweep every Python object and check if it's > an instance, starting at roots such as __main__ and sys.modules. This > makes developing code in a long-running process difficult, Zope being > the best example of this. When you modify a class definition used by > Zope code, you can't update existing instances floating around in > memory. There might be another solution. When you reload a module, the module object and its dictionary are reused. Perhaps class and function objects could similarly be reused? It would mean that a class or def statement looks for an existing object with the same name and type, and overwrites that. Voila, all references are automatically updated. This is more work (e.g. for classes, a new bytecode may have to be invented because the class creation process must be done differently) but it's much less of a hack, and I think it would be more reliable. (Even though it alters borderline semantics a bit.) (Your extra indirection also slows things down, although I don't know by how much -- not just the extra memory reference but also less locality of reference so more cache hits.) --Guido van Rossum (home page: http://www.python.org/~guido/) From tim_one at email.msn.com Thu Jan 20 06:59:51 2000 From: tim_one at email.msn.com (Tim Peters) Date: Thu, 20 Jan 2000 00:59:51 -0500 Subject: [Python-Dev] Changing existing class instances In-Reply-To: <200001200441.XAA20952@eric.cnri.reston.va.us> Message-ID: <000b01bf630b$91a409a0$31a2143f@tim> [Guido, on Andrew's idea for automagically updating classes] > There might be another solution. When you reload a module, > the module object and its dictionary are reused. > > Perhaps class and function objects could similarly be > reused? It would mean that a class or def statement > looks for an existing object with the same name and type, > and overwrites that. Voila, all references are > automatically updated. Too dangerous, I think. While uncommon in general, I've certainly seen (even written) functions that e.g. return a contained def or class. The intent in such cases is very much to create distinct defs or classes (despite having the same names). In this case I assume "the same name" wouldn't *usually* be found, since the "contained def or class"'s name is local to the containing function. But if there ever happened to be a module-level function or class of the same name, brrrr. Modules differ because their namespace "search path" consists solely of the more-global-than-global sys.modules. > This is more work (e.g. for classes, a new bytecode may > have to be invented because the class creation process > must be done differently) but it's much less of a hack, > and I think it would be more reliable. (Even though it > alters borderline semantics a bit.) How about an explicit function in the "new" module, new.update(class_or_def_old, class_or_def_new) which overwrites old's guts with new's guts (in analogy with dict.update)? Then no semantics change and you don't need new bytecodes. In return, a user who wants to e.g. replace an existing class C would need to do oldC = C do whatever they do to get the new C new.update(oldC, C) Building on that, a short Python loop could do the magic for every class and function in a module; and building on *that*, a short "updating import" function could be written in Python. View it as providing mechanism instead of policy <0.9 wink>. > (Your extra indirection also slows things down, although > I don't know by how much -- not just the extra memory > reference but also less locality of reference so more > cache hits.) Across the universe of all Python programs on all platforms, weighted by importance, it was a slowdown of nearly 4.317%. if-i-had-used-only-one-digit-everyone-would-have- known-i-was-making-it-up-ly y'rs - tim From gstein at lyra.org Thu Jan 20 08:48:29 2000 From: gstein at lyra.org (Greg Stein) Date: Wed, 19 Jan 2000 23:48:29 -0800 (PST) Subject: [Python-Dev] Changing existing class instances In-Reply-To: <000b01bf630b$91a409a0$31a2143f@tim> Message-ID: Oh man, oh man... I think this is where I get to say something akin to "I told you so." :-) I already described Tim's proposal in my type proposal paper, as a way to deal with incomplete classes. Essentially, a class object is created "empty" and is later "updated" with the correct bits. The empty class allows two classes to refer to each other in the "recursive type" scenario. In other words, I definitely would support a new class object behavior that allows us to update a class' set of bases and dictionary on the fly. This could then be used to support my solution for the recursive type scenario (which, in turn, means that we don't have to introduce Yet Another Namespace into Python to hold type names). Note: I would agree with Guido, however, on the "look for a class object with the same name", but with the restriction that the name is only replaced in the *target* namespace. i.e. a "class Foo" in a function will only look for Foo in the function's local namespace; it would not overwrite a class in the global space, nor would it overwrite class objects returned by a prior invocation of the function. Cheers, -g On Thu, 20 Jan 2000, Tim Peters wrote: > [Guido, on Andrew's idea for automagically updating > classes] > > > There might be another solution. When you reload a module, > > the module object and its dictionary are reused. > > > > Perhaps class and function objects could similarly be > > reused? It would mean that a class or def statement > > looks for an existing object with the same name and type, > > and overwrites that. Voila, all references are > > automatically updated. > > Too dangerous, I think. While uncommon in general, I've certainly seen > (even written) functions that e.g. return a contained def or class. The > intent in such cases is very much to create distinct defs or classes > (despite having the same names). In this case I assume "the same name" > wouldn't *usually* be found, since the "contained def or class"'s name is > local to the containing function. But if there ever happened to be a > module-level function or class of the same name, brrrr. > > Modules differ because their namespace "search path" consists solely of the > more-global-than-global sys.modules. > > > This is more work (e.g. for classes, a new bytecode may > > have to be invented because the class creation process > > must be done differently) but it's much less of a hack, > > and I think it would be more reliable. (Even though it > > alters borderline semantics a bit.) > > How about an explicit function in the "new" module, > > new.update(class_or_def_old, class_or_def_new) > > which overwrites old's guts with new's guts (in analogy with dict.update)? > Then no semantics change and you don't need new bytecodes. In return, a > user who wants to e.g. replace an existing class C would need to do > > oldC = C > do whatever they do to get the new C > new.update(oldC, C) > > Building on that, a short Python loop could do the magic for every class and > function in a module; and building on *that*, a short "updating import" > function could be written in Python. View it as providing mechanism instead > of policy <0.9 wink>. > > > (Your extra indirection also slows things down, although > > I don't know by how much -- not just the extra memory > > reference but also less locality of reference so more > > cache hits.) > > Across the universe of all Python programs on all platforms, weighted by > importance, it was a slowdown of nearly 4.317%. > > if-i-had-used-only-one-digit-everyone-would-have- > known-i-was-making-it-up-ly y'rs - tim > > > > _______________________________________________ > Python-Dev maillist - Python-Dev at python.org > http://www.python.org/mailman/listinfo/python-dev > -- Greg Stein, http://www.lyra.org/ From fredrik at pythonware.com Thu Jan 20 09:06:32 2000 From: fredrik at pythonware.com (Fredrik Lundh) Date: Thu, 20 Jan 2000 09:06:32 +0100 Subject: [Python-Dev] SOAP References: <000101bf62ce$5e509e70$c355cfc0@ski.org> Message-ID: <006901bf631d$449eea50$f29b12c2@secret.pythonware.com> David Ascher wrote: > Who if anyone is working on SOAP clients and servers for Python? we are (or rather, we will). hope to have code available during (late) Q1. From gerrit.holl at pobox.com Thu Jan 20 09:08:01 2000 From: gerrit.holl at pobox.com (Gerrit Holl) Date: Thu, 20 Jan 2000 09:08:01 +0100 Subject: [Python-Dev] ''.join in 1.6 In-Reply-To: <005e01bf62bd$dc8073d0$f29b12c2@secret.pythonware.com>; from fredrik@pythonware.com on Wed, Jan 19, 2000 at 09:43:36PM +0100 References: <20000119211427.A3755@stopcontact.palga.uucp> <005e01bf62bd$dc8073d0$f29b12c2@secret.pythonware.com> Message-ID: <20000120090801.A903@stopcontact.palga.uucp> Fredrik Lundh wrote on 948314616: > > In 1.6, I should do it this way: > > '\t'.join(s) > > > > I think it would be better to have that method on the *list*: > > s.join('\t') > > > > That's more clear, isn't it? > > what if "s" is a tuple? an array? a user-defined > sequence type? I understand. Thanks for your answers. regards, Gerrit. -- Please correct any bad English you encounter in my email message! -----BEGIN GEEK CODE BLOCK----- http://www.geekcode.com Version: 3.12 GCS dpu s-:-- a14 C++++>$ UL++ P--- L+++ E--- W++ N o? K? w--- !O !M !V PS+ PE? Y? PGP-- t- 5? X? R- tv- b+(++) DI D+ G++ !e !r !y -----END GEEK CODE BLOCK----- From jim at digicool.com Thu Jan 20 15:06:29 2000 From: jim at digicool.com (Jim Fulton) Date: Thu, 20 Jan 2000 09:06:29 -0500 Subject: [Python-Dev] Changing existing class instances References: <200001200419.XAA01969@mira.erols.com> Message-ID: <38871665.C3B6FFEE@digicool.com> "A.M. Kuchling" wrote: > > Currently, when you replace a class definition with an updated > version, it's really difficult to change existing class instances; > you'd have to essentially sweep every Python object and check if it's > an instance, starting at roots such as __main__ and sys.modules. This > makes developing code in a long-running process difficult, Zope being > the best example of this. When you modify a class definition used by > Zope code, you can't update existing instances floating around in > memory. In the case of Zope, if the objects that you care about happen to be persistent objects, then it's relatively easy to arrange to get the objects flushed from memory and reloaded with the new classes. (There are some subtle issues to deal with, like worrying about multiple threads, but in a development environment, you can deal with these, for example, by limiting the server to one thread.) Note that this is really only a special case of a much larger problem. Reloading a module redefines the global variables in a module. It doesn't update any references to those global references from other places, such as instances or *other* modules. For example, imports like: from foo import spam are not updated when foo is reloaded. Maybe you are expecting too much from reload. Jim -- Jim Fulton mailto:jim at digicool.com Technical Director (888) 344-4332 Python Powered! Digital Creations http://www.digicool.com http://www.python.org Under US Code Title 47, Sec.227(b)(1)(C), Sec.227(a)(2)(B) This email address may not be added to any commercial mail list with out my permission. Violation of my privacy with advertising or SPAM will result in a suit for a MINIMUM of $500 damages/incident, $1500 for repeats. From jim at digicool.com Thu Jan 20 15:34:13 2000 From: jim at digicool.com (Jim Fulton) Date: Thu, 20 Jan 2000 09:34:13 -0500 Subject: Python 2 namespace change? (was Re: [Python-Dev] Changing existing class instances) References: <200001200419.XAA01969@mira.erols.com> <38871665.C3B6FFEE@digicool.com> Message-ID: <38871CE5.53FB9D68@digicool.com> Jim Fulton wrote: > > Reloading a module redefines the global variables in a module. > It doesn't update any references to those global references > from other places, such as instances or *other* modules. > > For example, imports like: > > from foo import spam > > are not updated when foo is reloaded. A change to the way that namespaces are handled could make this work and have a number of other benefits, like global name usage without namespace lookups. I've suggested this to Guido in the past. His reasonable response is that this would be too big a change for Python 1. Maybe this is something to consider for Python 2? The basic idea (borrowed from Smalltalk) is to have a kind of dictionary that is a collection of "association" objects. An association object is simply a pairing of a name with a value. Association objects can be shared among multiple namespaces. An import like: from foo import spam would copy the association between the name 'foo' and a value from module 'spam' into the current module. If foo is reloaded or if the name is reassigned in spam, the association is modified and the change is seen in any namespaces that imported foo. Similarly if a function uses a global variable: spam=1 def bar(): global spam return spam*2 the compiled function contains the association between spam and it's value. This means that: - When spam is used in the function, it doesn't have to be looked up, - The function object no longer needs to keep a reference to it's globals. This eliminates an annoying circular reference. (I would not replace existing dictionaries with this new kind. I'd have both kinds available.) I think that this would be a really nice change for Python 2. Jim -- Jim Fulton mailto:jim at digicool.com Technical Director (888) 344-4332 Python Powered! Digital Creations http://www.digicool.com http://www.python.org Under US Code Title 47, Sec.227(b)(1)(C), Sec.227(a)(2)(B) This email address may not be added to any commercial mail list with out my permission. Violation of my privacy with advertising or SPAM will result in a suit for a MINIMUM of $500 damages/incident, $1500 for repeats. From guido at CNRI.Reston.VA.US Thu Jan 20 16:20:45 2000 From: guido at CNRI.Reston.VA.US (Guido van Rossum) Date: Thu, 20 Jan 2000 10:20:45 -0500 Subject: [Python-Dev] Changing existing class instances In-Reply-To: Your message of "Thu, 20 Jan 2000 00:59:51 EST." <000b01bf630b$91a409a0$31a2143f@tim> References: <000b01bf630b$91a409a0$31a2143f@tim> Message-ID: <200001201520.KAA21137@eric.cnri.reston.va.us> > From: "Tim Peters" > > [Guido, on Andrew's idea for automagically updating > classes] > > > There might be another solution. When you reload a module, > > the module object and its dictionary are reused. > > > > Perhaps class and function objects could similarly be > > reused? It would mean that a class or def statement > > looks for an existing object with the same name and type, > > and overwrites that. Voila, all references are > > automatically updated. > > Too dangerous, I think. While uncommon in general, I've certainly seen > (even written) functions that e.g. return a contained def or class. The > intent in such cases is very much to create distinct defs or classes > (despite having the same names). In this case I assume "the same name" > wouldn't *usually* be found, since the "contained def or class"'s name is > local to the containing function. But if there ever happened to be a > module-level function or class of the same name, brrrr. Agreed that that would be bad. But I wouldn't search outer scopes -- I would only look for a class/def that I was about to stomp on. > Modules differ because their namespace "search path" consists solely of the > more-global-than-global sys.modules. "The search path doesn't enter into it." > > This is more work (e.g. for classes, a new bytecode may > > have to be invented because the class creation process > > must be done differently) but it's much less of a hack, > > and I think it would be more reliable. (Even though it > > alters borderline semantics a bit.) > > How about an explicit function in the "new" module, > > new.update(class_or_def_old, class_or_def_new) > > which overwrites old's guts with new's guts (in analogy with dict.update)? > Then no semantics change and you don't need new bytecodes. Only a slight semantics change (which my full proposal would require too): function objects would become mutable -- their func_code, func_defaults, func_doc and func_globals fields (and, why not, func_name too) should be changeable. If you make all these assignable, it doesn't even have to be a privileged function. > In return, a > user who wants to e.g. replace an existing class C would need to do > > oldC = C > do whatever they do to get the new C > new.update(oldC, C) > > Building on that, a short Python loop could do the magic for every class and > function in a module; and building on *that*, a short "updating import" > function could be written in Python. View it as providing mechanism instead > of policy <0.9 wink>. That's certainly a reasonable compromise. Note that the update on a class should imply an update on its methods, right? --Guido van Rossum (home page: http://www.python.org/~guido/) From guido at CNRI.Reston.VA.US Thu Jan 20 16:45:40 2000 From: guido at CNRI.Reston.VA.US (Guido van Rossum) Date: Thu, 20 Jan 2000 10:45:40 -0500 Subject: Python 2 namespace change? (was Re: [Python-Dev] Changing existing class instances) In-Reply-To: Your message of "Thu, 20 Jan 2000 09:34:13 EST." <38871CE5.53FB9D68@digicool.com> References: <200001200419.XAA01969@mira.erols.com> <38871665.C3B6FFEE@digicool.com> <38871CE5.53FB9D68@digicool.com> Message-ID: <200001201545.KAA21304@eric.cnri.reston.va.us> > I've suggested this to Guido in the past. His > reasonable response is that this would be too big a > change for Python 1. Maybe this is something to consider > for Python 2? Note: from now on the new name for Python 2 is Python 3000. :-) > The basic idea (borrowed from Smalltalk) is to have a kind > of dictionary that is a collection of "association" > objects. An association object is simply a pairing of a > name with a value. Association objects can be shared among > multiple namespaces. I've never liked this very much, mostly because it breaks simplicity: the idea that a namespace is a mapping from names to values (e.g. {"limit": 100, "doit": , ...}) is beautifully simple, while the idea of inserting an extra level of indirection, no matter how powerful, is much murkier. There's also the huge change in semantics, as you point out; currently, from foo import bar has the same effect (on bar anyway) as import foo bar = foo.bar # i.e. copying an object reference del foo while under your proposal it would be more akin to changing all references to bar to become references to foo.bar. Of course that's what the moral equivalent of "from ... import ..." does in most other languages anyway, so we might consider this for Python 3000; however it would break a considerable amount of old code, I think. (Not to mention brain and book breakage. :-) --Guido van Rossum (home page: http://www.python.org/~guido/) From guido at CNRI.Reston.VA.US Thu Jan 20 17:01:38 2000 From: guido at CNRI.Reston.VA.US (Guido van Rossum) Date: Thu, 20 Jan 2000 11:01:38 -0500 Subject: [Python-Dev] Python 1.6 timing Message-ID: <200001201601.LAA21359@eric.cnri.reston.va.us> Andrew let me repost this mail of his to this list. It's worth a discussion here (if not in a larger forum). My responses are at the bottom. ------- Forwarded Message Date: Wed, 19 Jan 2000 20:17:55 -0500 From: "A.M. Kuchling" To: guido at python.org Subject: Python 1.6 timing I thought a bit more about the release schedule for 1.6, and like the idea of delaying it less and less. Another bad effect of delaying it is that not having Unicode in the core handicaps developing XML tools; we can continue working with wstrop, or integrate MAL's code into the XML-SIG's CVS tree, but it might mean abandoning the XML processing field to Perl & Tcl because the tools can't be made fully standard compliant in time. Options I can think of: 1) Delegating some control to a pumpkin holder [...]. 2) Releasing the Unicode+sre modules as separate add-ons to 1.5. (But would that impose annoying backward-compatibility constraints when they get integrated into 1.6?) 3) Add Unicode, sre, Distutils, plus other minor things and call it 1.5.5, meaning it's not as big a revision as a 1.6 release, but it's bigger than just another patchlevel of bugfixes. I don't remember what other features were planned for 1.6; was there anything major, if static typing is left for 2.0? - -- A.M. Kuchling http://starship.python.net/crew/amk/ Life's too short for chess. -- H.J. Byron ------- End of Forwarded Message There are several other things I can think of now that were planned for 1.6: revamped import, rich comparisons, revised coercions, parallel for loop (for i in L; j in M: ...), extended slicing for all sequences. I've also been thinking about making classes be types (not as huge a change as you think, if you don't allow subclassing built-in types), and adding a built-in array type suitable for use by NumPy. I've also received a conservative GC patch that seems to be fairly easy to apply and has some of Tim Peters' blessing. For 1.5.5 (what happened to 1.5.3 and 1.5.4?), we can have a more conservative agenda, as suggested by Andrew: Unicode and distutils are probably the most important things to integrate. (The import utilities are not ready for prime time in my opinion; there are too many issues.) Anybody care to be the pumpkin? That would cut the discussion short; otherwise the problem remains that I can't spend too much time on the next release unless I get funded for it; what little money I've received for CP4E I had better spend on getting some CP4E-related results ASAP, because the next installment of this funding is very much at stake... --Guido van Rossum (home page: http://www.python.org/~guido/) Life's better without braces. -- Bruce Eckel From bwarsaw at cnri.reston.va.us Thu Jan 20 17:21:30 2000 From: bwarsaw at cnri.reston.va.us (Barry A. Warsaw) Date: Thu, 20 Jan 2000 11:21:30 -0500 (EST) Subject: [Python-Dev] Python 1.6 timing References: <200001201601.LAA21359@eric.cnri.reston.va.us> Message-ID: <14471.13834.480356.541389@anthem.cnri.reston.va.us> >>>>> "Guido" == Guido van Rossum writes: Guido> There are several other things I can think of now that were Guido> planned for 1.6: revamped import, rich comparisons, revised Guido> coercions, parallel for loop (for i in L; j in M: ...), Guido> extended slicing for all sequences. I've also been Guido> thinking about making classes be types (not as huge a Guido> change as you think, if you don't allow subclassing Guido> built-in types), and adding a built-in array type suitable Guido> for use by NumPy. I've also received a conservative GC Guido> patch that seems to be fairly easy to apply and has some of Guido> Tim Peters' blessing. All very cool things that could easily wait until 1.7. After all, what's in a number? If, as Andrew puts forth, getting a stable Python release with Unicode is very important for Python's future positioning, then I say let's go with his more modest list, mainly Unicode, sre, and Distutils. We've already got string meths, tons of library improvements, and sundry other things. That's a good enough laundry list for the next release. From jim at digicool.com Thu Jan 20 17:21:33 2000 From: jim at digicool.com (Jim Fulton) Date: Thu, 20 Jan 2000 11:21:33 -0500 Subject: Version numbering (was Re: [Python-Dev] Python 1.6 timing) References: <200001201601.LAA21359@eric.cnri.reston.va.us> Message-ID: <3887360D.C29A9836@digicool.com> Guido van Rossum wrote: > > Andrew let me repost this mail of his to this list. It's worth a > discussion here (if not in a larger forum). My responses are at the > bottom. > (snip) > > There are several other things I can think of now that were planned > for 1.6: revamped import, rich comparisons, revised coercions, > parallel for loop (for i in L; j in M: ...), extended slicing for all > sequences. I've also been thinking about making classes be types (not > as huge a change as you think, if you don't allow subclassing built-in > types), and adding a built-in array type suitable for use by NumPy. > I've also received a conservative GC patch that seems to be fairly > easy to apply and has some of Tim Peters' blessing. > > For 1.5.5 (what happened to 1.5.3 and 1.5.4?), we can have a more > conservative agenda, as suggested by Andrew: Unicode and distutils are > probably the most important things to integrate. (The import > utilities are not ready for prime time in my opinion; there are too > many issues.) (snip) What is the basis of the Python numbering scheme? I thought that there was a notion that: - The first part changed with huge, possibly backward incompatible, changes, - The second part was for new functionality - The third part was for bug fixes. I thought I saw this scheme referenced somewhere and possibly even attributed to Guido. (?) I think that this is a better scheme that what I've seen with the 1.5 releases. Jim -- Jim Fulton mailto:jim at digicool.com Technical Director (888) 344-4332 Python Powered! Digital Creations http://www.digicool.com http://www.python.org Under US Code Title 47, Sec.227(b)(1)(C), Sec.227(a)(2)(B) This email address may not be added to any commercial mail list with out my permission. Violation of my privacy with advertising or SPAM will result in a suit for a MINIMUM of $500 damages/incident, $1500 for repeats. From petrilli at amber.org Thu Jan 20 17:33:52 2000 From: petrilli at amber.org (Christopher Petrilli) Date: Thu, 20 Jan 2000 11:33:52 -0500 Subject: [Python-Dev] Python 1.6 timing In-Reply-To: <14471.13834.480356.541389@anthem.cnri.reston.va.us>; from bwarsaw@cnri.reston.va.us on Thu, Jan 20, 2000 at 11:21:30AM -0500 References: <200001201601.LAA21359@eric.cnri.reston.va.us> <14471.13834.480356.541389@anthem.cnri.reston.va.us> Message-ID: <20000120113352.A23763@trump.amber.org> Barry A. Warsaw [bwarsaw at cnri.reston.va.us] wrote: > All very cool things that could easily wait until 1.7. After all, > what's in a number? If, as Andrew puts forth, getting a stable Python > release with Unicode is very important for Python's future > positioning, then I say let's go with his more modest list, mainly > Unicode, sre, and Distutils. We've already got string meths, tons of > library improvements, and sundry other things. That's a good enough > laundry list for the next release. Heck, Python is infinately more conservative in its numbering than a lot of projects. All that was mentioned would normally be enough to call it 2.0 easily. :-) Modesty can be counter productive in PR business...also there is the issue of having two copies of 1.5.x installed at the same time, which with Unicode could be a manjor consideraton for some of us. For me, numbering has always been (and I try and keep it this way with Zope): X.Y.Z X = structural changes, backward incompaibility Y = new features Z = bug fixes only Chris -- | Christopher Petrilli | petrilli at amber.org From bwarsaw at cnri.reston.va.us Thu Jan 20 17:30:32 2000 From: bwarsaw at cnri.reston.va.us (Barry A. Warsaw) Date: Thu, 20 Jan 2000 11:30:32 -0500 (EST) Subject: [Python-Dev] Python 1.6 timing References: <200001201601.LAA21359@eric.cnri.reston.va.us> <14471.13834.480356.541389@anthem.cnri.reston.va.us> <20000120113352.A23763@trump.amber.org> Message-ID: <14471.14376.9881.702264@anthem.cnri.reston.va.us> >>>>> "CP" == Christopher Petrilli writes: CP> For me, numbering has always been (and I try and keep it this CP> way with Zope): CP> X.Y.Z | X = structural changes, backward incompaibility | Y = new features | Z = bug fixes only I agree. -Barry From petrilli at amber.org Thu Jan 20 17:41:24 2000 From: petrilli at amber.org (Christopher Petrilli) Date: Thu, 20 Jan 2000 11:41:24 -0500 Subject: [Python-Dev] SOAP In-Reply-To: <006901bf631d$449eea50$f29b12c2@secret.pythonware.com>; from fredrik@pythonware.com on Thu, Jan 20, 2000 at 09:06:32AM +0100 References: <000101bf62ce$5e509e70$c355cfc0@ski.org> <006901bf631d$449eea50$f29b12c2@secret.pythonware.com> Message-ID: <20000120114124.B23763@trump.amber.org> Fredrik Lundh [fredrik at pythonware.com] wrote: > David Ascher wrote: > > Who if anyone is working on SOAP clients and servers for Python? > > we are (or rather, we will). hope to have code > available during (late) Q1. > > For what it's worth, this is also Zope's strategy. We are commited to having full SOAP integration in the system soon (when soon is, is another queston for the marketing department). :-) I am pretty sure that it will be a bi-directional integration. Chris -- | Christopher Petrilli | petrilli at amber.org From akuchlin at mems-exchange.org Thu Jan 20 17:38:53 2000 From: akuchlin at mems-exchange.org (Andrew M. Kuchling) Date: Thu, 20 Jan 2000 11:38:53 -0500 (EST) Subject: [Python-Dev] Python 1.6 timing In-Reply-To: <14471.13834.480356.541389@anthem.cnri.reston.va.us> References: <200001201601.LAA21359@eric.cnri.reston.va.us> <14471.13834.480356.541389@anthem.cnri.reston.va.us> Message-ID: <14471.14877.434886.471929@amarok.cnri.reston.va.us> Barry A. Warsaw writes: > Guido> There are several other things I can think of now that were > Guido> planned for 1.6: revamped import, rich comparisons, revised > Guido> coercions, parallel for loop (for i in L; j in M: ...), > Guido> extended slicing for all sequences. I'm not clear on the status of these various things; how many of these changes are deep ones that need lots of design, or affect massive amounts of the code base? For example, revamped import is a tricky design problem (as we've seen on this list). Is the spec for rich comparisons clearly defined at this point? Something like the parallel for loop seems like a parser modification combined with a code-generator modification, with no subtle implications for the rest of the implementation, and so that seems a simple matter of programming -- a week or so of effort. (Maybe I've missed something?) > Guido> I've also been > Guido> thinking about making classes be types (not as huge a > Guido> change as you think, if you don't allow subclassing > Guido> built-in types), and adding a built-in array type suitable > Guido> for use by NumPy. I've also received a conservative GC > Guido> patch that seems to be fairly easy to apply and has some of > Guido> Tim Peters' blessing. Similarly, does the conservative GC patch splatter changes all over the place, or is it very localized? Is adding the NumPy array type straightforward? Remember, there would presumably be a couple of 1.6 alphas and betas to shake out bugs. >From a political standpoint, I'd call the next release 1.6 and not >bother with another installment in 1.5.x series. And I agree with Fair enough; forget about the 1.5.5 suggestion, and call it as 1.6. >tree. My free-time plate is pretty full with JPython and Mailman, but >I'm willing to help where possible. Ditto. -- A.M. Kuchling http://starship.python.net/crew/amk/ One trouble with being efficient is that it makes everybody hate you so. -- Bob Edwards, the Calgary Eyeopener, March 18, 1916 From jim at digicool.com Thu Jan 20 17:48:18 2000 From: jim at digicool.com (Jim Fulton) Date: Thu, 20 Jan 2000 11:48:18 -0500 Subject: Python 2 namespace change? (was Re: [Python-Dev] Changing existing class instances) References: <200001200419.XAA01969@mira.erols.com> <38871665.C3B6FFEE@digicool.com> <38871CE5.53FB9D68@digicool.com> <200001201545.KAA21304@eric.cnri.reston.va.us> Message-ID: <38873C52.29FEAC6D@digicool.com> Guido van Rossum wrote: > > > I've suggested this to Guido in the past. His > > reasonable response is that this would be too big a > > change for Python 1. Maybe this is something to consider > > for Python 2? > > Note: from now on the new name for Python 2 is Python 3000. :-) I like it. > > The basic idea (borrowed from Smalltalk) is to have a kind > > of dictionary that is a collection of "association" > > objects. An association object is simply a pairing of a > > name with a value. Association objects can be shared among > > multiple namespaces. > > I've never liked this very much, mostly because it breaks simplicity: > the idea that a namespace is a mapping from names to values > (e.g. {"limit": 100, "doit": , ...}) is beautifully > simple, while the idea of inserting an extra level of indirection, no > matter how powerful, is much murkier. How so? It doesn't change the mapping semantics. > There's also the huge change in semantics, as you point out; > currently, > > from foo import bar > > has the same effect (on bar anyway) as > > import foo > bar = foo.bar # i.e. copying an object reference > del foo > > while under your proposal it would be more akin to changing all > references to bar to become references to foo.bar. > > Of course that's what the moral equivalent of "from ... import ..." > does in most other languages anyway, so we might consider this for > Python 3000; Cool. Again, it would also make function global variable access faster and cleaner in some ways. > however it would break a considerable amount of old code, > I think. Really? I wonder. I bet it would break alot less old code that other recent changes. > (Not to mention brain It makes my brain feel much better. :) > and book breakage. :-) Hey, all of the books will have to be rewritten for Python 3000. Jim -- Jim Fulton mailto:jim at digicool.com Technical Director (888) 344-4332 Python Powered! Digital Creations http://www.digicool.com http://www.python.org Under US Code Title 47, Sec.227(b)(1)(C), Sec.227(a)(2)(B) This email address may not be added to any commercial mail list with out my permission. Violation of my privacy with advertising or SPAM will result in a suit for a MINIMUM of $500 damages/incident, $1500 for repeats. From gstein at lyra.org Thu Jan 20 18:22:40 2000 From: gstein at lyra.org (Greg Stein) Date: Thu, 20 Jan 2000 09:22:40 -0800 (PST) Subject: [Python-Dev] Python 1.6 timing In-Reply-To: <200001201601.LAA21359@eric.cnri.reston.va.us> Message-ID: On Thu, 20 Jan 2000, Guido van Rossum wrote: >... > Date: Wed, 19 Jan 2000 20:17:55 -0500 > From: "A.M. Kuchling" > To: guido at python.org > Subject: Python 1.6 timing > > I thought a bit more about the release schedule for 1.6, and like the > idea of delaying it less and less. Another bad effect of delaying it > is that not having Unicode in the core handicaps developing XML tools; > we can continue working with wstrop, or integrate MAL's code into the > XML-SIG's CVS tree, but it might mean abandoning the XML processing > field to Perl & Tcl because the tools can't be made fully standard > compliant in time. I agree with Andrew's basic premise. > Options I can think of: > > 1) Delegating some control to a pumpkin holder [...]. Seems fine. > 2) Releasing the Unicode+sre modules as separate add-ons to > 1.5. (But would that impose annoying > backward-compatibility constraints when they get integrated > into 1.6?) Icky. :-) > 3) Add Unicode, sre, Distutils, plus other minor things and > call it 1.5.5, meaning it's not as big a revision as a 1.6 > release, but it's bigger than just another patchlevel of > bugfixes. I don't remember what other features were > planned for 1.6; was there anything major, if static typing > is left for 2.0? Call it 1.6, per the rest of the thread. >... > For 1.5.5 (what happened to 1.5.3 and 1.5.4?), we can have a more > conservative agenda, as suggested by Andrew: Unicode and distutils are > probably the most important things to integrate. Unicode: definitely. distutils seems pretty early, but I bet that some key concepts could be added to 1.6, to make the transition and continued development easier. Note that if an announcement were made to the effect of "feature freeze on February 15; only bug fixes afterwards," that you would get a lot of people scrambling to submit their pet features. This would be a good way to light some fires, to see what kinds of things get completed (i.e. we may think some things aren't ready or are too far out, put that deadline in and those positions could change...) > (The import > utilities are not ready for prime time in my opinion; there are too > many issues.) I'm waiting for that review :-) If you raise issues, then I can knock them down. I don't see all that many at the moment. But I'm biased :-) > Anybody care to be the pumpkin? That would cut the discussion short; > otherwise the problem remains that I can't spend too much time on the > next release unless I get funded for it; what little money I've > received for CP4E I had better spend on getting some CP4E-related > results ASAP, because the next installment of this funding is very > much at stake... I would volunteer for the pumpkin... around April-ish. My plate is rather full with completing mod_dav and then integrating that into Apache 2.0. Once the Apache integration begins, then I'd have some more free time. But this begs the question of: what does the pumpkin-holder mean in the *Python* world? If it is collating fixes, producing snapshots, etc, then I'm comfy with it. If it also contains responsibility for specific kinds of work, then Fred would probably veto me :-), as I've got an outstanding doc that I owe him (for about six months now... sigh; maybe I'll bribe MAL to write it; he knows the interface :-)). But stll: what's it mean? How does the pumpkin reduce the Guido-load, yet still enable the Guido-control? [ I just had a talk about this with the guys at Inprise, re: InterBase, mentioning that the Dictator model works well for Python, but doesn't necessarily work well for new projects or commercially-started projects due to control/prejudice issues. Python people like it because of the resulting simplicity and cleanliness; I doubt we want a pumpkin approach that would allow that to go away! ] Cheers, -g -- Greg Stein, http://www.lyra.org/ From guido at CNRI.Reston.VA.US Thu Jan 20 18:20:33 2000 From: guido at CNRI.Reston.VA.US (Guido van Rossum) Date: Thu, 20 Jan 2000 12:20:33 -0500 Subject: Python 2 namespace change? (was Re: [Python-Dev] Changing existing class instances) In-Reply-To: Your message of "Thu, 20 Jan 2000 11:48:18 EST." <38873C52.29FEAC6D@digicool.com> References: <200001200419.XAA01969@mira.erols.com> <38871665.C3B6FFEE@digicool.com> <38871CE5.53FB9D68@digicool.com> <200001201545.KAA21304@eric.cnri.reston.va.us> <38873C52.29FEAC6D@digicool.com> Message-ID: <200001201720.MAA21534@eric.cnri.reston.va.us> [me] > > I've never liked this very much, mostly because it breaks simplicity: > > the idea that a namespace is a mapping from names to values > > (e.g. {"limit": 100, "doit": , ...}) is beautifully > > simple, while the idea of inserting an extra level of indirection, no > > matter how powerful, is much murkier. [Jim F] > How so? It doesn't change the mapping semantics. My assumption is that in your version, the dictionary would contain special objects which then would contain the referenced objects. E.g. {"limit": , "doit": >}. Thus, d["limit"] would be that object, while previously it would return 100. > Again, it would also make function global variable access > faster and cleaner in some ways. But I have other plans for that (if the optional static typing stuff ever gets implemented). > > however it would break a considerable amount of old code, > > I think. > > Really? I wonder. I bet it would break alot less old > code that other recent changes. Oh? Name some changes that broke a lot of code? --Guido van Rossum (home page: http://www.python.org/~guido/) From jeremy at cnri.reston.va.us Thu Jan 20 18:36:32 2000 From: jeremy at cnri.reston.va.us (Jeremy Hylton) Date: Thu, 20 Jan 2000 12:36:32 -0500 (EST) Subject: [Python-Dev] Python 1.6 timing In-Reply-To: <14471.13834.480356.541389@anthem.cnri.reston.va.us> References: <200001201601.LAA21359@eric.cnri.reston.va.us> <14471.13834.480356.541389@anthem.cnri.reston.va.us> Message-ID: <14471.18336.257653.730100@bitdiddle.cnri.reston.va.us> >>>>> "BAW" == Barry A Warsaw writes: >>>>> "Guido" == Guido van Rossum writes: Guido> There are several other things I can think of now that were Guido> planned for 1.6: revamped import, rich comparisons, revised Guido> coercions, parallel for loop (for i in L; j in M: ...), Guido> extended slicing for all sequences. I've also been thinking Guido> about making classes be types (not as huge a change as you Guido> think, if you don't allow subclassing built-in types), and Guido> adding a built-in array type suitable for use by NumPy. I've Guido> also received a conservative GC patch that seems to be fairly Guido> easy to apply and has some of Tim Peters' blessing. BAW> All very cool things that could easily wait until 1.7. After BAW> all, what's in a number? If, as Andrew puts forth, getting a BAW> stable Python release with Unicode is very important for BAW> Python's future positioning, then I say let's go with his more BAW> modest list, mainly Unicode, sre, and Distutils. We've already BAW> got string meths, tons of library improvements, and sundry BAW> other things. That's a good enough laundry list for the next BAW> release. We've had this conversation before, so it'll comes as no surprise that I agree with you. Question: If we go with the feature set you've described, when will those features be ready? What kind of schedule could we set for releasing the first alpha? Jeremy From guido at CNRI.Reston.VA.US Thu Jan 20 18:40:51 2000 From: guido at CNRI.Reston.VA.US (Guido van Rossum) Date: Thu, 20 Jan 2000 12:40:51 -0500 Subject: [Python-Dev] Python 1.6 timing In-Reply-To: Your message of "Thu, 20 Jan 2000 09:22:40 PST." References: Message-ID: <200001201740.MAA21608@eric.cnri.reston.va.us> > Call it 1.6, per the rest of the thread. OK. I expect I'll get some complaints from some people who asked when 1.6 would be out (I've generally told them end of 2000); but it sounds like a 1.7 would be necessary to fulfill the other promises, so it shouldn't really matter -- it's all a case of relabeling for PR purposes. > Unicode: definitely. distutils seems pretty early, but I bet that some key > concepts could be added to 1.6, to make the transition and continued > development easier. The point of adding distutils is that it will allow distribution of packages without including distutils with each distribution. Since distutils was about 200K itself last time I looked, this is important. I don't believe it would be good to have to say "My FooBar package is really easy to install. All you need to do is download and install distutils, (which by the way is a 200K package that you have to manually install), and then run "python setup.py" in the FooBar root directory..." This would be enough for the average person to run away screaming. I think I saw a distribution by AMK that had a setup.py that tried to use distutils but had a crude fallback if distutils didn't exist; however that defeats much of the purpose since the package author has to figure out how to do the fallback. Large distributions (e.g. NumPy) can afford to squeeze distutils in a corner of their distribution, but for the average package it wouldn't be of much use. In other words, I'm for putting distutils in the next release, essentially feature-freezing it. Greg Ward, what do you think of that? > Note that if an announcement were made to the effect of "feature freeze on > February 15; only bug fixes afterwards," that you would get a lot of > people scrambling to submit their pet features. This would be a good way > to light some fires, to see what kinds of things get completed (i.e. we > may think some things aren't ready or are too far out, put that deadline > in and those positions could change...) I bet you we couldn't complete the import hooks by that date; I consider imputil.py as a nice prototype, but the integration with the C code is still missing. Also the 50% slowdown is a problem I worry about for inclusion a production version. (Plus breakage of everybody else's code who uses or hacks __import__; e.g. have you tested it with rexec?) > > (The import > > utilities are not ready for prime time in my opinion; there are too > > many issues.) > > I'm waiting for that review :-) It was kept up by the need to get the types documents out. > If you raise issues, then I can knock them down. I don't see all that many > at the moment. But I'm biased :-) > > > Anybody care to be the pumpkin? That would cut the discussion short; > > otherwise the problem remains that I can't spend too much time on the > > next release unless I get funded for it; what little money I've > > received for CP4E I had better spend on getting some CP4E-related > > results ASAP, because the next installment of this funding is very > > much at stake... > > I would volunteer for the pumpkin... around April-ish. My plate is rather > full with completing mod_dav and then integrating that into Apache 2.0. > Once the Apache integration begins, then I'd have some more free time. > > But this begs the question of: what does the pumpkin-holder mean in the > *Python* world? > > If it is collating fixes, producing snapshots, etc, then I'm comfy with > it. If it also contains responsibility for specific kinds of work, then > Fred would probably veto me :-), as I've got an outstanding doc that I owe > him (for about six months now... sigh; maybe I'll bribe MAL to write it; > he knows the interface :-)). > > But stll: what's it mean? How does the pumpkin reduce the Guido-load, yet > still enable the Guido-control? Good questions. I have to say that I feel reluctant to release any kind of control -- yet at the same time I desperately need help getting trivial stuff checked in. One of the most important time-consuming tasks is quality control: collecting fixes is all well and good, but I routinely reject fixes that superficially look fine, because they are subtly broken, or interfere with other plans, or just because the code looks poorly written. I also spend a lot of testing before I check things in; running the standard test suite is a good safeguard against general breakage, but you really have to play with the code affected by the change before you can know that it works as advertised. My work attitude here means that what gets checked in is generally rock solid, and that helps Python's reputation; but it is very costly... > [ I just had a talk about this with the guys at Inprise, re: InterBase, > mentioning that the Dictator model works well for Python, but doesn't > necessarily work well for new projects or commercially-started projects > due to control/prejudice issues. Python people like it because of the > resulting simplicity and cleanliness; I doubt we want a pumpkin approach > that would allow that to go away! ] Agreed, of course. --Guido van Rossum (home page: http://www.python.org/~guido/) From da at ski.org Thu Jan 20 18:57:51 2000 From: da at ski.org (David Ascher) Date: Thu, 20 Jan 2000 09:57:51 -0800 Subject: [Python-Dev] Python 1.6 timing In-Reply-To: <14471.13834.480356.541389@anthem.cnri.reston.va.us> Message-ID: <000701bf636f$de37c5e0$c355cfc0@ski.org> [I just got GvR's post on the topic, but I'll send this anyway] BAW: > All very cool things that could easily wait until 1.7. After all, > what's in a number? Guido has promised some of those features as being in 1.6 at conferences in the past, but I agree that string methods for example are a more major change than I'd expect to see in a 0.0.3-delta version change. Maybe with a deadline (as Greg suggests) we can integrate some of the pending patches (I agree with Greg that I at least would have found the time for a revised patch for rich comparisons if I'd had a deadline -- call me human =). Coercion and extended slicing also seem like relatively minor changes, compared with changing everything to be a class or adding GC! Regardless, just like Greg, I'd like to know what a pumpkin-holder would mean in the Python world. I propose that it be called the Oracle instead. As in, whoever is Oracle would get some training with Tim Peters and learn how to channel G__do. As a Python user, I'd be most comfortable with such a change if the Oracle just took over the technical stuff (reviewing patches, CVS checkins, running tests, corralling help for doc & code, maintaining release notes, building installers, etc.), but that the important decisions (e.g. whether to add a feature to the core language) would be checked with G__do first. We could call the position "Administrative Assistant", but somehow that doesn't have the prestige. A progressive schedule where Guido watches over the Oracle periodically would probably help build trust in the new mechanism. The Oracle would be expected to ask Guido for his opinion with everything at the beginning, and as a trust builds between Guido and the Oracle and the community and the mechanism, progressively less. --david ascher From gstein at lyra.org Thu Jan 20 19:30:52 2000 From: gstein at lyra.org (Greg Stein) Date: Thu, 20 Jan 2000 10:30:52 -0800 (PST) Subject: [Python-Dev] Python 1.6 timing In-Reply-To: <200001201740.MAA21608@eric.cnri.reston.va.us> Message-ID: On Thu, 20 Jan 2000, Guido van Rossum wrote: >... > In other words, I'm for putting distutils in the next release, > essentially feature-freezing it. Greg Ward, what do you think of > that? Oh, don't get me wrong. I'd like to see it in there for at least all the reasons you cite. But it seems (to me) that it is still pretty alpha. But hey: I'm shooting from the peanut gallery; we need GregW's comments. > > Note that if an announcement were made to the effect of "feature freeze on > > February 15; only bug fixes afterwards," that you would get a lot of > > people scrambling to submit their pet features. This would be a good way > > to light some fires, to see what kinds of things get completed (i.e. we > > may think some things aren't ready or are too far out, put that deadline > > in and those positions could change...) > > I bet you we couldn't complete the import hooks by that date; I > consider imputil.py as a nice prototype, but the integration with the > C code is still missing. Also the 50% slowdown is a problem I worry > about for inclusion a production version. (Plus breakage of everybody > else's code who uses or hacks __import__; e.g. have you tested it with > rexec?) hehe... if the static typing is to be deferred, then I'll take that bet! [discussion omitted; too tangental to this thread right now...] >... > Good questions. I have to say that I feel reluctant to release any > kind of control -- yet at the same time I desperately need help > getting trivial stuff checked in. Reading your comments below, we may be able to help. First, presume that at least one (best would be several) people man the "front lines" for any/all patches and bug reports. The front line can deal with the bug reports, mostly by responding with "go away; enter it into Jitterbug." Patches fall under several catagories, detailed below: > One of the most important > time-consuming tasks is quality control: collecting fixes is all well > and good, but I routinely reject fixes that superficially look fine, Conversely, your "lieutenants" (LTs) would filter all ugly-looking patches. > because they are subtly broken, If the LTs didn't catch these, then you could catch them from the checkin diff email. However, the LTs would reduce the number of broken ones that you would review. > or interfere with other plans, The LTs may know of this, but if not: you'd catch it at checkin time. The patches would then be backed out, altered, or whatever. > or just > because the code looks poorly written. The LTs would definitely catch this. If the style was *still* not up to snuff, I'd have to believe it would only be in minor ways that you could then touch up at your leisure. > I also spend a lot of testing > before I check things in; Done by the LTs. > running the standard test suite is a good > safeguard against general breakage, Ditto. > but you really have to play with > the code affected by the change before you can know that it works as > advertised. Ditto. > My work attitude here means that what gets checked in is > generally rock solid, and that helps Python's reputation; but it is > very costly... Based on my responses, I would venture to state that a group of LTs would manage to keep the Python core rock solid, except for: 1) subtle breakages that require your broader knowledge of Python 2) changes that "go against the plan" (and the LTs were ignorant of it) 3) minor format issues You would still review checkins, but the number of reviews would drop since the (obvious) crap has been eliminated. #1 is based on your *broad* knowledge of Python; I presume the LTs would be your match on various subsets of Python. By keeping the LTs well-informed, #2 could be nearly eliminated. #3 isn't that big of a deal, as I think your desired style is relatively well-known and the LTs would simply endeavor to match existing style. You could avoid a lot of testing; you would probably be inclined to do testing of items that you find dubious, but still this would be a reduction. ===== That may be an answer to the checkin problem. How about actual snapshots, alphas, betas, releases, and accompanying notes/news/readme files? I presume your LTs could run the alpha and beta aspects, but you would still issue final releases. Does your mail volume need to be reduced? (I think this has been asked before) Specifically, would patches at python.org (and similar targets) need to be established? (I would think so, as a matter of course, with the expectation that some patches would still end up with you and need to be bounced to patches@) Cheers, -g -- Greg Stein, http://www.lyra.org/ From klm at digicool.com Thu Jan 20 19:31:52 2000 From: klm at digicool.com (Ken Manheimer) Date: Thu, 20 Jan 2000 13:31:52 -0500 (EST) Subject: [Python-Dev] Python 1.6 timing In-Reply-To: <000701bf636f$de37c5e0$c355cfc0@ski.org> Message-ID: I must have missed the historic landmark where "pumpkin" was coined, but i think i get the gist. How about "Python Marshall" or "Python Activity Marshall" (a la the PS_A_)? Ken David Ascher wrote: > [...] > Regardless, just like Greg, I'd like to know what a pumpkin-holder would > mean in the Python world. > > I propose that it be called the Oracle instead. As in, whoever is Oracle > would get some training with Tim Peters and learn how to channel G__do. As > a Python user, I'd be most comfortable with such a change if the Oracle just > took over the technical stuff (reviewing patches, CVS checkins, running > tests, corralling help for doc & code, maintaining release notes, building > installers, etc.), but that the important decisions (e.g. whether to add a > feature to the core language) would be checked with G__do first. We could > call the position "Administrative Assistant", but somehow that doesn't have > the prestige. > > A progressive schedule where Guido watches over the Oracle periodically > would probably help build trust in the new mechanism. The Oracle would be > expected to ask Guido for his opinion with everything at the beginning, and > as a trust builds between Guido and the Oracle and the community and the > mechanism, progressively less. From gstein at lyra.org Thu Jan 20 19:42:43 2000 From: gstein at lyra.org (Greg Stein) Date: Thu, 20 Jan 2000 10:42:43 -0800 (PST) Subject: [Python-Dev] Python 1.6 timing In-Reply-To: Message-ID: On Thu, 20 Jan 2000, Ken Manheimer wrote: > I must have missed the historic landmark where "pumpkin" was coined, but i > think i get the gist. How about "Python Marshall" or "Python Activity > Marshall" (a la the PS_A_)? The "pumpkin" term comes from Perl-land... I'm not super clear on the pumpkin-holders's entire job, but I think it is basically the guy who sees that the version for which he "holds the pumpkin" is completed and shipped. Not necessarily by himself :-), but as the overseer (or "release manager" if you will). The current Perl pumpkin-holder is a guy at ActiveState. I think it changes for each version. Cheers, -g -- Greg Stein, http://www.lyra.org/ From gvwilson at nevex.com Thu Jan 20 19:51:17 2000 From: gvwilson at nevex.com (gvwilson at nevex.com) Date: Thu, 20 Jan 2000 13:51:17 -0500 (EST) Subject: [Python-Dev] Python 1.6 timing (fwd) Message-ID: Guido> There are several other things I can think of now that were Guido> planned for 1.6: revamped import, rich comparisons, revised Guido> coercions, parallel for loop (for i in L; j in M: ...), Guido> extended slicing for all sequences. I've also been thinking Guido> about making classes be types (not as huge a change as you Guido> think, if you don't allow subclassing built-in types), and Guido> adding a built-in array type suitable for use by NumPy. I've Guido> also received a conservative GC patch that seems to be fairly Guido> easy to apply and has some of Tim Peters' blessing. BAW> All very cool things that could easily wait until 1.7. After BAW> all, what's in a number? GVW writes: I agree on all counts except garbage collection --- I'm half-way through the second day of the Python class I teach at Los Alamos (the people who are funding the Python tool design competition), and it's come up a couple of times. People want to be able to prototype meshes, throw callbacks around without worrying about circularity, and some other things that I don't really understand yet. There's also a couple of smart guys in the class who are wondering about CPython vs. JPython ("So this'll be safe in one version of the language, but not in the other?"), and about marketing ("Help me win a feature comparison against Java in my group..."). There's also been questions about tighter integration of NumPy (e.g. overloading operators rather than calling 'greater()' to do comparison), but I think that's a separate discussion... My $0.02, Greg From tismer at tismer.com Thu Jan 20 20:11:13 2000 From: tismer at tismer.com (Christian Tismer) Date: Thu, 20 Jan 2000 20:11:13 +0100 Subject: [Python-Dev] Python 1.6 timing (fwd) References: Message-ID: <38875DD1.B6596@tismer.com> [garbage collection] gvwilson at nevex.com wrote: > I agree on all counts except garbage collection --- I'm half-way through > the second day of the Python class I teach at Los Alamos (the people who > are funding the Python tool design competition), and it's come up a couple > of times. People want to be able to prototype meshes, throw callbacks > around without worrying about circularity, and some other things that I > don't really understand yet. There's also a couple of smart guys in the > class who are wondering about CPython vs. JPython ("So this'll be safe in > one version of the language, but not in the other?"), and about marketing > ("Help me win a feature comparison against Java in my group..."). Guido once posted some proposal of a hybrid system *with* refcounts and some additional garbage collection scheme to match circular things. I believe this is a much better approach than what Java and therefor also JPython does at the moment. Although people might argue differently, I'm pretty sure that reference counting is the stronger concept. By reference counting, the idea of object ownership can be made explicit. This plays a central role in the Corba specification for instance, and I made the same observation when implementing continuations for Stackless Python. Refcounts are no burden but a virtue. Even better: Refcounting can lead to many new optimizations if we pay the cost to make INCREF/DECREF into methods. It has its cost (about 10 percent less pystones), but massive long-term benefits. I'm currently in charge to develop a custom version of Python's builtin types where this concept is used. Everything is refcounted, but without storing the refcounts in the objects. This is possible (proven) and will be shown in my next paper. Conclusion: I vote for a kind of GC that does just what refcounts cannot do, but please keep with the refcounts. cheers - chris -- Christian Tismer :^) Virtual Photonics GmbH : Have a break! Take a ride on Python's Carnotstr. 6 : *Starship* http://starship.python.net 10587 Berlin : PGP key -> http://wwwkeys.pgp.net PGP Fingerprint E182 71C7 1A9D 66E9 9D15 D3CC D4D7 93E2 1FAE F6DF we're tired of banana software - shipped green, ripens at home From tim_one at email.msn.com Thu Jan 20 20:47:01 2000 From: tim_one at email.msn.com (Tim Peters) Date: Thu, 20 Jan 2000 14:47:01 -0500 Subject: [Python-Dev] Changing existing class instances In-Reply-To: <200001201520.KAA21137@eric.cnri.reston.va.us> Message-ID: <000301bf637f$1f1c2d80$b72d153f@tim> [Tim worries about stomping on unintended classes/defs] [Guido] > Agreed that that would be bad. But I wouldn't search outer > scopes -- I would only look for a class/def that I was about > to stomp on. Maybe I just don't grasp what that means, exactly. Fair enough, since I'm not expressing myself clearly either! Suppose someone does from Tkinter import * in my.py, and later in my.py just *happens* to define, at module level, class Misc: blah blah blah Now Misc was already in my.py's global namespace because Tkinter.py just happens to export a class of that name too (more by accident than design -- but accidents are what I'm most worried about here). At the time my.py defines Misc, does Misc count as a class we're "about to stomp on"? If so-- & I've assumed so --it would wreak havoc. But if not, I don't see how this case can be reliably distinguished "by magic" from the cases where update is desired (if people are doing dynamic updates to a long-running program, a new version of a class can come from anywhere, so nothing like original file name or line number can distinguish correctly either). >> Modules differ because their namespace "search path" >> consists solely of the more-global-than-global >> sys.modules. > "The search path doesn't enter into it." I agree, but am at a loss to describe what's happening in the case above using other terminology . In a sense, you need a system-wide "unique handle" to support bulletproof updating, and while sys.modules has supplied that all along for module objects (in the form of the module name), I don't believe there's anything analogous to key off of for function or class objects. >> [suggesting] >> new.update(class_or_def_old, class_or_def_new) > Only a slight semantics change (which my full proposal > would require too): function objects would become mutable > -- their func_code, func_defaults, func_doc and func_globals > fields (and, why not, func_name too) should be changeable. Of course I meant "no new semantics" in the sense of "won't cause current exception-free code to alter behavior in any way". > If you make all these assignable, it doesn't even have to > be a privileged function. I'm all for that! > [sketching a Python approach to "updating import/reload" > building on the hypothetical new.update] > That's certainly a reasonable compromise. Note that the > update on a class should imply an update on its methods, > right? Hadn't considered that! Of course you're right. So make it a pair of nested loops . so-long-as-it-can-be-written-in-python-it's-easy-ly y'rs - tim From guido at CNRI.Reston.VA.US Thu Jan 20 21:02:20 2000 From: guido at CNRI.Reston.VA.US (Guido van Rossum) Date: Thu, 20 Jan 2000 15:02:20 -0500 Subject: [Python-Dev] Changing existing class instances In-Reply-To: Your message of "Thu, 20 Jan 2000 14:47:01 EST." <000301bf637f$1f1c2d80$b72d153f@tim> References: <000301bf637f$1f1c2d80$b72d153f@tim> Message-ID: <200001202002.PAA22435@eric.cnri.reston.va.us> > [Tim worries about stomping on unintended classes/defs] > > [Guido] > > Agreed that that would be bad. But I wouldn't search outer > > scopes -- I would only look for a class/def that I was about > > to stomp on. > > Maybe I just don't grasp what that means, exactly. Fair enough, since I'm > not expressing myself clearly either! > > Suppose someone does > > from Tkinter import * > > in my.py, and later in my.py just *happens* to define, at module level, > > class Misc: > blah blah blah > > Now Misc was already in my.py's global namespace because Tkinter.py just > happens to export a class of that name too (more by accident than design -- > but accidents are what I'm most worried about here). For a second I thought you got me there! > At the time my.py defines Misc, does Misc count as a class we're "about to > stomp on"? If so-- & I've assumed so --it would wreak havoc. > > But if not, I don't see how this case can be reliably distinguished "by > magic" from the cases where update is desired (if people are doing dynamic > updates to a long-running program, a new version of a class can come from > anywhere, so nothing like original file name or line number can distinguish > correctly either). Fortunately, there's magic available: recently, all classes have a __module__ attribute that is set to the full name of the module that defined it (its key in __sys__.modules). For functions, we would have to invent something similar. > >> Modules differ because their namespace "search path" > >> consists solely of the more-global-than-global > >> sys.modules. > > > "The search path doesn't enter into it." > > I agree, but am at a loss to describe what's happening in the case above > using other terminology . In a sense, you need a system-wide "unique > handle" to support bulletproof updating, and while sys.modules has supplied > that all along for module objects (in the form of the module name), I don't > believe there's anything analogous to key off of for function or class > objects. > > >> [suggesting] > >> new.update(class_or_def_old, class_or_def_new) > > > Only a slight semantics change (which my full proposal > > would require too): function objects would become mutable > > -- their func_code, func_defaults, func_doc and func_globals > > fields (and, why not, func_name too) should be changeable. > > Of course I meant "no new semantics" in the sense of "won't cause current > exception-free code to alter behavior in any way". > > > If you make all these assignable, it doesn't even have to > > be a privileged function. > > I'm all for that! > > > [sketching a Python approach to "updating import/reload" > > building on the hypothetical new.update] > > > That's certainly a reasonable compromise. Note that the > > update on a class should imply an update on its methods, > > right? > > Hadn't considered that! Of course you're right. So make it a pair of > nested loops . > > so-long-as-it-can-be-written-in-python-it's-easy-ly > y'rs - tim --Guido van Rossum (home page: http://www.python.org/~guido/) From guido at CNRI.Reston.VA.US Thu Jan 20 21:12:58 2000 From: guido at CNRI.Reston.VA.US (Guido van Rossum) Date: Thu, 20 Jan 2000 15:12:58 -0500 Subject: [Python-Dev] Python 1.6 timing (fwd) In-Reply-To: Your message of "Thu, 20 Jan 2000 20:11:13 +0100." <38875DD1.B6596@tismer.com> References: <38875DD1.B6596@tismer.com> Message-ID: <200001202012.PAA22501@eric.cnri.reston.va.us> > Conclusion: I vote for a kind of GC that does just what refcounts > cannot do, but please keep with the refcounts. The patch that I received and that has Tim's <0.5 blessing> does just that. I haven't had the time to understand why it doesn't have his <1.0 blessing>. --Guido van Rossum (home page: http://www.python.org/~guido/) From tim_one at email.msn.com Thu Jan 20 21:35:44 2000 From: tim_one at email.msn.com (Tim Peters) Date: Thu, 20 Jan 2000 15:35:44 -0500 Subject: [Python-Dev] Python 1.6 timing (fwd) In-Reply-To: <200001202012.PAA22501@eric.cnri.reston.va.us> Message-ID: <000901bf6385$eccfba20$b72d153f@tim> [Christian] > Conclusion: I vote for a kind of GC that does just > what refcounts cannot do, but please keep with the > refcounts. [Guido] > The patch that I received and that has Tim's <0.5 > blessing> does just that. I haven't had the time to > understand why it doesn't have his <1.0 blessing>. Primarily because it doesn't reclaim the most common cycles; e.g., cycles among class instances aren't touched. This seems easily repairable, but at an unknown cost (it needs to do the "reachability" transitive closure business from the set of all "suspicious" objects, and instances are never considered suspicious now; adding them will certainly cause a lot more pointer chasing). Apart from that, the code appears unreasonably expensive as written today, using e.g. splay trees instead of hash tables to keep track of objects. The author hasn't said anything more in a bit over two weeks, so I suspect he's off on other things now. The technical approach is sound, but even its inventor (Rafael Lins; Toby Kelsey may have reinvented it on his own, though) stresses that getting it to run fast is difficult. needs-work!-ly y'rs - tim, who hasn't the time to do it From tismer at tismer.com Thu Jan 20 21:35:27 2000 From: tismer at tismer.com (Christian Tismer) Date: Thu, 20 Jan 2000 21:35:27 +0100 Subject: [Python-Dev] Stackless Python 1.0 + Continuations 0.6 Message-ID: <3887718F.82E1B327@tismer.com> ANNOUNCING: Stackless Python 1.0 A Python Implementation That Does Not Use The C Stack * plus the real toy * Continuation Module 0.6 Continuations as First Class Objects What is it? A plugin-replacement for core Python. It should run any program which runs under Python 1.5.2 . But it does not need space on the C stack. Why did I write it? Stackless Python was never written before (afaik), since it was said to be impossible without major rewrites of core Python. I have proven the controverse: It is easy to write, just hard to think. About 3 times harder was finally the continuation module. The whole project took about 6 man months where 80 percent of the time was thinking and trying. The rest was coding and to become a reference counting champion :-) Recent changes: Version 1.0 has been optimized like hell and is now 3-5 percent faster than Standard Python. Continuation module is in version 0.6, very stable, and it allows to save a program's "future" at any time, in a portable way. Continuations are callable Python objects with a very small footprint. Who needs it? Since the continuations are done, this is no more only useful for C programmers who want to try certain new ideas. Everybody who is interested to develop his own generators, coroutines and tiny threads is invited to check it out. Status of the final 1.0: Pystone works correctly and is 5% faster than standard Python. Version 0.3 was 10 percent slower. Continuations work with PythonWin and Idle. The overall result is now better than expected, and I'm happy to call this *FINAL* (until the next version of course:) Downloadable files can be found at http://www.tismer.com/research/stackless/ Some older documentation: http://www.tismer.com/research/stackless/stackless.htm Some better documentation can be found in my IPC8 paper: http://www.tismer.com/research/stackless/spc_final.zip or be read directly as HTML http://www.tismer.com/research/stackless/spcpaper.htm Source code and a VC++6.0 build for Windows (340K): http://www.tismer.com/research/stackless/spc_win32.zip cheers - chris == Christian Tismer :^) Applied Biometrics GmbH : Have a break! Take a ride on Python's Kaiserin-Augusta-Allee 101 : *Starship* http://starship.python.net 10553 Berlin : PGP key -> http://wwwkeys.pgp.net PGP Fingerprint E182 71C7 1A9D 66E9 9D15 D3CC D4D7 93E2 1FAE F6DF we're tired of banana software - shipped green, ripens at home

Stackless Python 1.0 - a version of Python 1.5.2 that does not need space on the C stack. (20-Jan-00) From bwarsaw at cnri.reston.va.us Thu Jan 20 22:12:37 2000 From: bwarsaw at cnri.reston.va.us (Barry A. Warsaw) Date: Thu, 20 Jan 2000 16:12:37 -0500 (EST) Subject: [Python-Dev] Python 1.6 timing References: Message-ID: <14471.31301.504670.201702@anthem.cnri.reston.va.us> We'd have to rework the CVS arrangement in order to give non-CNRI employees write access to the tree. I think I know how I'd go about this, and it wouldn't be too hard, just a bit time-consuming. If that's the way we're going to go, I can start making plans. -Barry From guido at CNRI.Reston.VA.US Thu Jan 20 22:16:39 2000 From: guido at CNRI.Reston.VA.US (Guido van Rossum) Date: Thu, 20 Jan 2000 16:16:39 -0500 Subject: [Python-Dev] Python 1.6 timing In-Reply-To: Your message of "Thu, 20 Jan 2000 16:12:37 EST." <14471.31301.504670.201702@anthem.cnri.reston.va.us> References: <14471.31301.504670.201702@anthem.cnri.reston.va.us> Message-ID: <200001202116.QAA22943@eric.cnri.reston.va.us> [Barry] > We'd have to rework the CVS arrangement in order to give non-CNRI > employees write access to the tree. I think I know how I'd go about > this, and it wouldn't be too hard, just a bit time-consuming. If > that's the way we're going to go, I can start making plans. I think before you make such changes you'd have to talk to Bob (good luck). I don't mind applying patches and doing the checkins -- it's the decision-making that's time-consuming. --Guido van Rossum (home page: http://www.python.org/~guido/) From da at ski.org Thu Jan 20 22:28:24 2000 From: da at ski.org (David Ascher) Date: Thu, 20 Jan 2000 13:28:24 -0800 Subject: [Python-Dev] Python 1.6 timing (fwd) In-Reply-To: Message-ID: <001401bf638d$486488f0$c355cfc0@ski.org> Daddy Warbucks (uh, Greg Wilson =): > There's also been questions about tighter integration of NumPy (e.g. > overloading operators rather than calling 'greater()' to do comparison), > but I think that's a separate discussion... That's the rich comparison proposal which Guido mentioned. --david From bwarsaw at cnri.reston.va.us Thu Jan 20 22:30:24 2000 From: bwarsaw at cnri.reston.va.us (Barry A. Warsaw) Date: Thu, 20 Jan 2000 16:30:24 -0500 (EST) Subject: [Python-Dev] Python 1.6 timing References: <14471.31301.504670.201702@anthem.cnri.reston.va.us> <200001202116.QAA22943@eric.cnri.reston.va.us> Message-ID: <14471.32368.730988.252872@anthem.cnri.reston.va.us> >>>>> "Guido" == Guido van Rossum writes: Guido> I think before you make such changes you'd have to talk to Guido> Bob (good luck). Heh. Guido> I don't mind applying patches and doing the checkins -- Guido> it's the decision-making that's time-consuming. Then maybe the current CVS arrangement is fine (cool with me). -Barry From klm at digicool.com Thu Jan 20 23:08:28 2000 From: klm at digicool.com (Ken Manheimer) Date: Thu, 20 Jan 2000 17:08:28 -0500 (EST) Subject: [Python-Dev] Python 1.6 timing In-Reply-To: <14471.31301.504670.201702@anthem.cnri.reston.va.us> Message-ID: On Thu, 20 Jan 2000, Barry A. Warsaw wrote: > We'd have to rework the CVS arrangement in order to give non-CNRI > employees write access to the tree. I think I know how I'd go about > this, and it wouldn't be too hard, just a bit time-consuming. If > that's the way we're going to go, I can start making plans. Though it may be moot if guido's going to continue mediating the checkins, maybe this would be interesting (if only for barry, to compare procedures). We basically use a captive cvs-":ext:"-over-ssh method, where the captive .ssh/authorized_keys command is quite succinct: command="set $SSH_ORIGINAL_COMMAND; shift; exec cvs $@" 1024 35 ... The shellisms (set/shift/exec cvs $@) lock the user of the qualifying key into executing a cvs command, and only a cvs command. Also, for us the checkins are to a public mirror of our CVS repository, so penetration of the security there doesn't jepordize the master repository base. We don't currently have any outsiders checking into our master repository, and it doesn't seem to me that CVS provides sufficiently managable discretion for doing that. Oh, and a disappointment - the account under which cvs conducts the checkins is the account on the CVS server host, not that of the host where the checkins are being done. This means that you can't use a single account to serve multiple remote users (preventing masquerading quite reliably by using a separate authorized_key public-key entry for each remote user). Therefore we have to have distinct (nailed-down) accounts for each checkin-privileged person - more management burden. Ken From tim_one at email.msn.com Fri Jan 21 00:53:18 2000 From: tim_one at email.msn.com (Tim Peters) Date: Thu, 20 Jan 2000 18:53:18 -0500 Subject: [Python-Dev] Python 1.6 timing (fwd) In-Reply-To: <001401bf638d$486488f0$c355cfc0@ski.org> Message-ID: <000201bf63a1$8641b1c0$6ea0143f@tim> [Greg Wilson] > There's also been questions about tighter integration > of NumPy (e.g. overloading operators rather than > calling 'greater()' to do comparison), but I think ? that's a separate discussion... [David Ascher] > That's the rich comparison proposal which Guido mentioned. But there's also been talk about moving (at least) the basic NumPy array type into the core. This would be a Good Thing. Speaking for my employer, however, only Unicode is an Important Thing . As a developer, I have railed against schedule-driven release cycles. Python tends toward the opposite end of that spectrum, driven by features no matter how bloody long they take. Add Unicode to what's already waiting to go, and that's *good enough* reason for a major release; heck, it's been 9 months & we haven't even had a 1.5.2 bugfix patch. BTW, do the Perl-Porters have real jobs? pay-me-to-do-python-releases-and-you'll-get-a-major-new- release-every-three-days-ly y'rs - tim From da at ski.org Fri Jan 21 01:01:45 2000 From: da at ski.org (David Ascher) Date: Thu, 20 Jan 2000 16:01:45 -0800 Subject: [Python-Dev] Python 1.6 timing (fwd) In-Reply-To: <000201bf63a1$8641b1c0$6ea0143f@tim> Message-ID: <002601bf63a2$b4acf9b0$c355cfc0@ski.org> Tim Peters > But there's also been talk about moving (at least) the basic NumPy array > type into the core. This would be a Good Thing. IMNSHO, moving the current NumPy array into the core would be a Bad Thing. Moving a new similar object with cleaned up semantics and better implementation in would be a Good Thing. But it won't happen until 1.7 at the earliest, as the semantics haven't even been agreed on, let alone the code written. --david From da at ski.org Fri Jan 21 01:07:16 2000 From: da at ski.org (David Ascher) Date: Thu, 20 Jan 2000 16:07:16 -0800 Subject: [Python-Dev] Conference Schedules Message-ID: <002701bf63a3$79a15ae0$c355cfc0@ski.org> Given the rush of interesting discussions and progress which occurs in the two weeks before Python conferences, I propose that we have a bi-weekly conference. We'll just have to remember to cancel them at the last minute except a couple of times a year. --david ascher -------------- next part -------------- A non-text attachment was scrubbed... Name: David Ascher.vcf Type: text/x-vcard Size: 527 bytes Desc: not available URL: From gstein at lyra.org Fri Jan 21 01:53:59 2000 From: gstein at lyra.org (Greg Stein) Date: Thu, 20 Jan 2000 16:53:59 -0800 (PST) Subject: [Python-Dev] Python 1.6 timing In-Reply-To: <14471.31301.504670.201702@anthem.cnri.reston.va.us> Message-ID: On Thu, 20 Jan 2000, Barry A. Warsaw wrote: > We'd have to rework the CVS arrangement in order to give non-CNRI > employees write access to the tree. I think I know how I'd go about > this, and it wouldn't be too hard, just a bit time-consuming. If > that's the way we're going to go, I can start making plans. Or move the CVS tree off-site. Cheers, -g -- Greg Stein, http://www.lyra.org/ From guido at CNRI.Reston.VA.US Fri Jan 21 02:29:30 2000 From: guido at CNRI.Reston.VA.US (Guido van Rossum) Date: Thu, 20 Jan 2000 20:29:30 -0500 Subject: [Python-Dev] Python 1.6 timing In-Reply-To: Your message of "Thu, 20 Jan 2000 10:30:52 PST." References: Message-ID: <200001210129.UAA28292@eric.cnri.reston.va.us> (I accidentally mailed this only to Greg; here's a repost of the relevant parts to the list:) [me] > > Good questions. I have to say that I feel reluctant to release any > > kind of control -- yet at the same time I desperately need help > > getting trivial stuff checked in. [Greg Stein] > Reading your comments below, we may be able to help. [...Proposal of lieutenants condensed...] > Based on my responses, I would venture to state that a group of LTs would > manage to keep the Python core rock solid, except for: > > 1) subtle breakages that require your broader knowledge of Python > 2) changes that "go against the plan" (and the LTs were ignorant of it) > 3) minor format issues > > You would still review checkins, but the number of reviews would drop > since the (obvious) crap has been eliminated. #1 is based on your *broad* > knowledge of Python; I presume the LTs would be your match on various > subsets of Python. By keeping the LTs well-informed, #2 could be nearly > eliminated. #3 isn't that big of a deal, as I think your desired style is > relatively well-known and the LTs would simply endeavor to match existing > style. > > You could avoid a lot of testing; you would probably be inclined to do > testing of items that you find dubious, but still this would be a > reduction. > > ===== > > That may be an answer to the checkin problem. How about actual snapshots, > alphas, betas, releases, and accompanying notes/news/readme files? I > presume your LTs could run the alpha and beta aspects, but you would still > issue final releases. There's a lot of work in these (you may have noticed that the release notes got sloppier as 1.5.2 neared its completion). I would be happy to have the responsibility to decide to release without the burden of having to do all the work. > Does your mail volume need to be reduced? (I think this has been asked > before) Specifically, would patches at python.org (and similar targets) need > to be established? (I would think so, as a matter of course, with the > expectation that some patches would still end up with you and need to be > bounced to patches@) It's not the mail volume that bothers me -- I can ignore 100s of messages a day very quickly. It's the time it takes to respond to all of them. As an experiment, I've collected about 40 messages with suggested patches in them that I found in my inbox; the oldest are nearly two years old. You can access these from this address: http://www.python.org/~guido/patch/ I would love any help I could get in responding with these, and taking action in the form of patches. I propose that if you decide that a particular patch is worth checking in, you ask the author for the bugrelease or wetsign disclaimer and let me know that I can check it in; if changes to the patch are needed, I propose that you negotiate these with the author first. (I often ask them to test my version of a patch when I have style suggestions but don't have access the target platform or problem it solves.) --Guido van Rossum (home page: http://www.python.org/~guido/) From tim_one at email.msn.com Fri Jan 21 10:38:21 2000 From: tim_one at email.msn.com (Tim Peters) Date: Fri, 21 Jan 2000 04:38:21 -0500 Subject: [Python-Dev] Changing existing class instances In-Reply-To: Message-ID: <001801bf63f3$414e0c60$ec2d153f@tim> [Greg Stein] > ... > In other words, I definitely would support a new class > object behavior that allows us to update a class' set of > bases and dictionary on the fly. This could then be used > to support my solution for the recursive type scenario (which, > in turn, means that we don't have to introduce Yet Another > Namespace into Python to hold type names). Parenthetically, I never grasped the appeal of the parenthetical comment. Yet Another Namespace for Yet Another Entirely New Purpose seems highly *desirable* to me! Trying to overload the current namespace set makes it so much harder to see that these are compile-time gimmicks, and users need to be acutely aware of that if they're to use it effectively. Note that I understand (& wholly agree with) the need for runtime introspection. different-things-different-rules-ly y'rs - tim From tim_one at email.msn.com Fri Jan 21 10:38:24 2000 From: tim_one at email.msn.com (Tim Peters) Date: Fri, 21 Jan 2000 04:38:24 -0500 Subject: [Python-Dev] Python 1.6 timing In-Reply-To: <20000120113352.A23763@trump.amber.org> Message-ID: <001901bf63f3$432404e0$ec2d153f@tim> [Christopher Petrilli] > Heck, Python is infinately more conservative in its > numbering than a lot of projects. All that was mentioned > would normally be enough to call it 2.0 easily. :-) Modesty > can be counter productive in PR business... Indeed, where I work a number of managers met the suggestion to use Python 1.5.x with "what?! we don't want to use software that's barely out of alpha release -- besides, Perl is already on release 5". I hear that Guido got normal American glasses -- time to do normal American hyperinflated version numbering too. heck-ms-windows-will-soon-be-at-version-2000-ly y'rs - tim From tim_one at email.msn.com Fri Jan 21 10:38:26 2000 From: tim_one at email.msn.com (Tim Peters) Date: Fri, 21 Jan 2000 04:38:26 -0500 Subject: [Python-Dev] Python 1.6 timing In-Reply-To: <14471.14877.434886.471929@amarok.cnri.reston.va.us> Message-ID: <001a01bf63f3$4473b660$ec2d153f@tim> [Andrew M. Kuchling] > ... > Similarly, does the conservative GC patch splatter changes > all over the place, or is it very localized? Part of its problem is that it's *too* localized (which was, paradoxically, I suspect part of its initial quick-eyeball appeal to Guido -- it "looks like" an amazingly self-contained patch). For example, all the code to chase pointers in various types of objects is hiding in a single function, which does a string of "if type is list then this else if type is tuple then that ..." tests. This stuff clearly needs to be distributed across the object implementations and dispatched to via a new slot in type objects; there's no code for that now. I expect it would take a minimum of two weeks (full-time work) to make this code ready for prime time (but mostly to slash the space and time use -- and with no certainty of "good enough" in the end). BTW, "conservative" is a misleading adjective for this approach -- it never guesses ("guessing on the safe side" whether or not some bit pattern is a pointer is what "conservative" customarily means in the GC world). > Is adding the NumPy array type straightforward? DavidA nixed that one in no uncertain terms! maybe-hp-will-give-up-unicode-and-we-can-release-tomorrow-ly y'rs - tim From tim_one at email.msn.com Fri Jan 21 10:52:13 2000 From: tim_one at email.msn.com (Tim Peters) Date: Fri, 21 Jan 2000 04:52:13 -0500 Subject: [Python-Dev] Python 1.6 timing (fwd) In-Reply-To: Message-ID: <001d01bf63f5$318e2600$ec2d153f@tim> [Greg Wilson] > ... > There's also a couple of smart guys in the class who are > wondering about CPython vs. JPython ("So this'll be safe in > one version of the language, but not in the other?"), Greg, people who have been exposed to Fortran (this is LANL, right ?) can't possibly have a problem with the concept of "not defined by the standard". Don't sell these as different *versions* of the language, but as different implementations. That's what they are. The Python *language* doesn't define anything about the lifetime of objects. Even when CPython grows "real GC", thanks to refcounting too you'll still be able to *rely* on behaviors in CPython you'll see only accidentally in JPython. You do so at your own risk, same as e.g. you rely on floating point Fortran x+y+z getting evaluated "left to right" at your own risk (BTW, x+y+z *is* "left to right" in Python -- maybe they'll trade that for the lack of GC promises ). From tim_one at email.msn.com Fri Jan 21 11:22:51 2000 From: tim_one at email.msn.com (Tim Peters) Date: Fri, 21 Jan 2000 05:22:51 -0500 Subject: [Python-Dev] Changing existing class instances In-Reply-To: <200001202002.PAA22435@eric.cnri.reston.va.us> Message-ID: <001e01bf63f9$79660980$ec2d153f@tim> [Tim, still worried about stomping on unintended classes/defs] [example abusing Tkinter.Misc] > For a second I thought you got me there! That's twice as long as I thought you'd think that, so I win after all . > Fortunately, there's magic available: recently, all classes > have a __module__ attribute that is set to the full name > of the module that defined it (its key in __sys__.modules). > > For functions, we would have to invent something similar. OK! I didn't know about class.__module__ -- I hope you realize that relying on your time machine is making you lazy . I remain uncomfortable with automagic updating, but not as much so. Both kinds of errors still seem possible to me: 1. Automagically updating when it wasn't wanted. Examples of this are getting harder to come by . Off the top of my head I'm reduced to stuff like this: >>> adders = [] >>> for i in range(10): def adder(y, x=i): return y+x adders.append(adder) >>> adders[2](40) 42 >>> adders[9](33) 42 >>> "That kind of thing" has got to be rare, but can't be non-existent either (well, isn't -- I've done it). 2. Failing to automagically update when it was wanted. Implicit in the discussion so far is that long-running systems want to update code at a granularity no finer than module level. Is that realistic? I'm unsure. It's certainly easy to *imagine* the app running an updater server thread, accepting new source for functions and classes, and offering to compile and install the objects. Under the explicit new.update scheme, such a service needn't bother clients with communicating the full name of the original module; heck, in a *truly* long-running app, over time the source tree will change, and classes and functions will migrate across modules. That will be a problem for the explicit scheme too (how does it know *which* "class Misc" to update) -- but at least it's an explicit problem then, and not a "mysterous failure" of hidden magic. I could live with both of those (#1 is more worrisome); but think it easier all around to give the users some tools and tell them to solve the problems however they see fit. or-maybe-we-already-agreed-about-that-ly y'rs - tim From gstein at lyra.org Fri Jan 21 12:08:19 2000 From: gstein at lyra.org (Greg Stein) Date: Fri, 21 Jan 2000 03:08:19 -0800 (PST) Subject: [Python-Dev] namespaces (was: Changing existing class instances) In-Reply-To: <001801bf63f3$414e0c60$ec2d153f@tim> Message-ID: On Fri, 21 Jan 2000, Tim Peters wrote: > [Greg Stein] > > ... > > In other words, I definitely would support a new class > > object behavior that allows us to update a class' set of > > bases and dictionary on the fly. This could then be used > > to support my solution for the recursive type scenario (which, > > in turn, means that we don't have to introduce Yet Another > > Namespace into Python to hold type names). > > Parenthetically, I never grasped the appeal of the parenthetical comment. > Yet Another Namespace for Yet Another Entirely New Purpose seems highly > *desirable* to me! Trying to overload the current namespace set makes it so > much harder to see that these are compile-time gimmicks, and users need to > be acutely aware of that if they're to use it effectively. Note that I > understand (& wholly agree with) the need for runtime introspection. And that is the crux of the issue: I think the names that are assigned to these classes, interfaces, typedefs, or whatever, can follow the standard Python semantics and be plopped into the appropriate namespace. There is no overloading. The compile-time behavior certainly understands what names have what types; in this case, if a name is a "typedecl", then it can remember the *value*, too. When the name is used later, it knows the corresponding value to use. For instance: IntOrString = typedef int|str def foo(x: IntOrString): ... In this example, the type-checker knows that IntOrString is a typedecl. It also knows the *value* of "int|str" so the name IntOrString now has two items associated with it at type-check time: # not "real" syntax, but you get the idea... namespace["IntOrString"] = (TypeDeclarator, int|str) With the above information in hand, the type-checker knows what IntOrString means in the declaration for foo(). The cool benefit is that the runtime semantics are exactly as you would expect: a typedecl object is created and assigned to IntOrString. That object is also associated with the "x" argument in the function object referred to by the name "foo". There is no "overloading" of namespaces. We are using Python namespaces just like they should be, and the type-checker doesn't even have to be all the smart to track this stuff. To get back to the recursive class problem, consider the following code: decl incomplete class Foo decl incomplete class Bar class Foo: decl a: Bar class Bar: decl b: Foo The "decl" statements would create an empty class object and store that into the "current" namespace. There is no need to shove that off into another namespace. When the "class Foo" comes along, the class object is updated with the class definition for Foo. It is conceivable to remove the need for "decl" if you allow "class" and "def" to omit the ": suite" portion of their grammar: class Foo class Bar class Foo: decl a: Bar ... def some_function(x: some_type, y: another_type) -> third_type ... lots o' code ... def some_function(x, y): ... Guido suggested that it may be possible to omit "decl" altogether. Certainly, it can work for member declarations such as: class Foo: a: Bar Anyhow... my point is that a new namespace is not needed. Assuming we want objects for reflection at runtime, then the above proposal states *how* those objects are realized at runtime. Further, the type-checker can easily follow that information and perform the appropriate compile-time checks. No New Namespaces! (lather, rinse, repeat) Cheers, -g -- Greg Stein, http://www.lyra.org/ From gstein at lyra.org Fri Jan 21 12:12:57 2000 From: gstein at lyra.org (Greg Stein) Date: Fri, 21 Jan 2000 03:12:57 -0800 (PST) Subject: [Python-Dev] Changing existing class instances In-Reply-To: <200001202002.PAA22435@eric.cnri.reston.va.us> Message-ID: On Thu, 20 Jan 2000, Guido van Rossum wrote: > Tim Peters: >... > > At the time my.py defines Misc, does Misc count as a class we're "about to > > stomp on"? If so-- & I've assumed so --it would wreak havoc. > > > > But if not, I don't see how this case can be reliably distinguished "by > > magic" from the cases where update is desired (if people are doing dynamic > > updates to a long-running program, a new version of a class can come from > > anywhere, so nothing like original file name or line number can distinguish > > correctly either). > > Fortunately, there's magic available: recently, all classes have a > __module__ attribute that is set to the full name of the module that > defined it (its key in __sys__.modules). > > For functions, we would have to invent something similar. func.func_globals __module__ and func_globals can prevent *other* modules from redefining something accidentally, but it doesn't prevent Badness from within the module. [ Tim just posted an example of this: his "def adder()" example... ] Cheers, -g -- Greg Stein, http://www.lyra.org/ From bwarsaw at cnri.reston.va.us Fri Jan 21 15:38:52 2000 From: bwarsaw at cnri.reston.va.us (Barry A. Warsaw) Date: Fri, 21 Jan 2000 09:38:52 -0500 (EST) Subject: [Python-Dev] Changing existing class instances References: <200001202002.PAA22435@eric.cnri.reston.va.us> <001e01bf63f9$79660980$ec2d153f@tim> Message-ID: <14472.28540.765858.16133@anthem.cnri.reston.va.us> >>>>> "TP" == Tim Peters writes: TP> Under the explicit new.update scheme, such a service needn't TP> bother clients with communicating the full name of the TP> original module; heck, in a *truly* long-running app, over TP> time the source tree will change, and classes and functions TP> will migrate across modules. That will be a problem for the TP> explicit scheme too (how does it know *which* "class Misc" to TP> update) -- but at least it's an explicit problem then, and not TP> a "mysterous failure" of hidden magic. I completely agree. I think in general, such long running apps are rare, and in those cases you probably want to be explicit about when and how the updates occur anyway. The one place where automatic updates would be convenient would be at the interactive prompt, so it might be nice to add a module that could be imported by PYTHONSTARTUP, and play hook games to enable automatic updates. -Barry From bwarsaw at cnri.reston.va.us Fri Jan 21 15:39:32 2000 From: bwarsaw at cnri.reston.va.us (Barry A. Warsaw) Date: Fri, 21 Jan 2000 09:39:32 -0500 (EST) Subject: [Python-Dev] Python 1.6 timing References: <14471.31301.504670.201702@anthem.cnri.reston.va.us> Message-ID: <14472.28580.945266.658533@anthem.cnri.reston.va.us> >>>>> "GS" == Greg Stein writes: GS> Or move the CVS tree off-site. I don't see what this buys us. -Barry From gstein at lyra.org Fri Jan 21 15:48:40 2000 From: gstein at lyra.org (Greg Stein) Date: Fri, 21 Jan 2000 06:48:40 -0800 (PST) Subject: [Python-Dev] Python 1.6 timing In-Reply-To: <14472.28580.945266.658533@anthem.cnri.reston.va.us> Message-ID: On Fri, 21 Jan 2000, Barry A. Warsaw wrote: > >>>>> "GS" == Greg Stein writes: > > GS> Or move the CVS tree off-site. > > I don't see what this buys us. I was under the impression that CVS access restrictions are based on CNRI security policy. If the CVS repository moves elsewhere, then many people can access it without impact on CNRI's network and security policies. However, if the external access issue is based on legal reasons (for example, only CNRI people should alter Python code), then yes: moving the repository will buy nothing. Cheers, -g -- Greg Stein, http://www.lyra.org/ From bwarsaw at python.org Fri Jan 21 17:08:11 2000 From: bwarsaw at python.org (bwarsaw at python.org) Date: Fri, 21 Jan 2000 11:08:11 -0500 (EST) Subject: [Python-Dev] Python 1.6 timing References: <14472.28580.945266.658533@anthem.cnri.reston.va.us> Message-ID: <14472.33899.20409.602096@anthem.cnri.reston.va.us> >>>>> "GS" == Greg Stein writes: GS> I was under the impression that CVS access restrictions are GS> based on CNRI security policy. If the CVS repository moves GS> elsewhere, then many people can access it without impact on GS> CNRI's network and security policies. Well, access to our /internal/ network is of course restricted. CNRI employees have write access to the tree by virtue of access to the filesystem (i.e. by NFS). My current arrangement for external ssh mediated access to a writable cvs server on an internal machine is a hack and not something that I want to perpetuate if more users were added. GS> However, if the external access issue is based on legal GS> reasons (for example, only CNRI people should alter Python GS> code), then yes: moving the repository will buy nothing. I'll let Guido comment on policy concerning write access to the Python CVS tree. From a technical standpoint, if this is something Guido wanted to extend to non-CNRI employees, the way to do it would be to host the primary repository on a CNRI machine outside our firewall, e.g cvs.python.org. At that point, we'd be accessing the tree the same as anybody else. -Barry From gstein at lyra.org Fri Jan 21 17:19:33 2000 From: gstein at lyra.org (Greg Stein) Date: Fri, 21 Jan 2000 08:19:33 -0800 (PST) Subject: [Python-Dev] Python 1.6 timing In-Reply-To: <14472.33899.20409.602096@anthem.cnri.reston.va.us> Message-ID: On Fri, 21 Jan 2000 bwarsaw at python.org wrote: > >>>>> "GS" == Greg Stein writes: >... > From a technical standpoint, if this is something Guido > wanted to extend to non-CNRI employees, the way to do it would be to > host the primary repository on a CNRI machine outside our firewall, > e.g cvs.python.org. At that point, we'd be accessing the tree the > same as anybody else. Gotcha. Sounds great! I'm not sure yet that Guido is looking for external people to do checkins (as opposed to delivering refined patches to him)... So we probably don't need an assessment from the legal department :-), but if Guido already knows, then I'd be curious. thx! -g -- Greg Stein, http://www.lyra.org/ From paul at prescod.net Fri Jan 21 17:51:24 2000 From: paul at prescod.net (Paul Prescod) Date: Fri, 21 Jan 2000 08:51:24 -0800 Subject: [Python-Dev] Re: [Types-sig] namespaces (was: Changing existing class instances) References: Message-ID: <38888E8C.FE369A86@prescod.net> Greg Stein wrote: > Tim Peters: > > Trying to overload the current namespace set makes it so > > much harder to see that these are compile-time gimmicks, and users need to > > be acutely aware of that if they're to use it effectively. Note that I > > understand (& wholly agree with) the need for runtime introspection. > > And that is the crux of the issue: I think the names that are assigned to > these classes, interfaces, typedefs, or whatever, can follow the standard > Python semantics and be plopped into the appropriate namespace. There is > no overloading. This is indeed the crux of the issue. For those that missed it last time, it became very clear to me that we are working with radically different design aesthetics when we discussed the idea of having an optional keyword that said: "this thing is usually handled at compile time but I want to handle it at runtime. I know what I am doing." Greg complained that that would require the programmer to understand too much what was being done at compile time and what at runtime and what. >From my point of view this is *exactly* what a programmer *needs* to know and if we make it too hard for them to know it then we have failed. > There is no "overloading" of namespaces. We are using Python namespaces > just like they should be, and the type-checker doesn't even have to be all > the smart to track this stuff. There is an overloading of namespaces because we will separately specify the *compile time semantics* of these names. We need to separately specify these semantics because we need all compile time type checkers to behave identically. Yes, it seems elegant to make type objects seem as if they are "just like" Python objects. Unfortunately they aren't. Type objects are evaluated -- and accepted or rejected -- at compile time. Every programmer needs to understand that and it should be blatantly obvious in the syntax, just as everything else in Python syntax is blatantly obvious. -- Paul Prescod - ISOGEN Consulting Engineer speaking for himself Earth will soon support only survivor species -- dandelions, roaches, lizards, thistles, crows, rats. Not to mention 10 billion humans. - Planet of the Weeds, Harper's Magazine, October 1998 From skaller at maxtal.com.au Fri Jan 21 22:01:03 2000 From: skaller at maxtal.com.au (skaller) Date: Sat, 22 Jan 2000 08:01:03 +1100 Subject: [Python-Dev] Re: [Types-sig] namespaces (was: Changing existing class instances) References: <38888E8C.FE369A86@prescod.net> Message-ID: <3888C90F.BECA3FF6@maxtal.com.au> Paul Prescod wrote: > Yes, it seems elegant to make type objects seem as if they are "just > like" Python objects. Unfortunately they aren't. Yes they are. They even have a type, TypeType. -- John (Max) Skaller, mailto:skaller at maxtal.com.au 10/1 Toxteth Rd Glebe NSW 2037 Australia voice: 61-2-9660-0850 homepage: http://www.maxtal.com.au/~skaller download: ftp://ftp.cs.usyd.edu/au/jskaller From tim_one at email.msn.com Sun Jan 23 00:18:14 2000 From: tim_one at email.msn.com (Tim Peters) Date: Sat, 22 Jan 2000 18:18:14 -0500 Subject: [Python-Dev] Python 1.6 timing In-Reply-To: <000701bf636f$de37c5e0$c355cfc0@ski.org> Message-ID: <000401bf652e$f5266b60$132d153f@tim> [David Ascher] > ... > Regardless, just like Greg, I'd like to know what a > pumpkin-holder would mean in the Python world. > > I propose that it be called the Oracle instead. As in, > whoever is Oracle would get some training with Tim Peters > and learn how to channel G__do. I'm afraid that wouldn't work. The whole secret to channeling Guido in the *past* was to have been an ABC user: all you had to do is notice the things about ABC that you loved and the ones that would drive any sane *experienced* programmer mad with frustration. Voila! Guido's mind is your mind . But the more Python sails into uncharted waters, the less reliable my Guido-channeling pseudo-skills get. He is, in Essence, Unfathomable. Also indispensable. > As a Python user, I'd be most comfortable with such a change > if the Oracle just took over the technical stuff (reviewing > patches, CVS checkins, running tests, corralling help for > doc & code, maintaining release notes, building installers, > etc.), but that the important decisions (e.g. whether to add > a feature to the core language) would be checked with G__do > first. Definitely. But where do you find someone like that? It's (or at least *should* be) several full-time jobs. Languages like Icon & Scheme do it via university association (scads of grad student slave labor); REBOL did it by floating a trendy Internet business plan that actually attracted enough venture capital to hire about 30 people; Python, unfortunately , seems to attract people who already have demanding jobs. So I see it as an issue of finding warm bodies more than anything else. In the absence of funding "real jobs", I really don't see much hope. Bits & pieces can be farmed out (e.g., I doubt Guido has had to do any work on the regular expression code since Andrew arrived), but that's it -- I expect the past predicts the future quite accurately here. Certainly much more *could* be "farmed out", but no single volunteer of the kind Python has attracted so far is going to do a lot on their own month after month after month. Even with the best of intentions, their "real life" will interfere severely more often than not (voice of experience, there -- and I'd guess it's the same for *all* of us). if-something-doesn't-change-nothing-will-change-ly y'rs - tim From tim_one at email.msn.com Sun Jan 23 00:18:11 2000 From: tim_one at email.msn.com (Tim Peters) Date: Sat, 22 Jan 2000 18:18:11 -0500 Subject: Python 2 namespace change? (was Re: [Python-Dev] Changing existing class instances) In-Reply-To: <38871CE5.53FB9D68@digicool.com> Message-ID: <000301bf652e$f348d1c0$132d153f@tim> [Jim Fulton] > ... > A change to the way that namespaces are handled > could make this work and have a number of other benefits, > like global name usage without namespace lookups. > > I've suggested this to Guido in the past. His > reasonable response is that this would be too big a > change for Python 1. Maybe this is something to consider > for Python 2? > > The basic idea (borrowed from Smalltalk) is to have a kind > of dictionary that is a collection of "association" > objects. An association object is simply a pairing of a > name with a value. Association objects can be shared among > multiple namespaces. Jim, I've been intrigued by this idea for all the years you've been suggesting it , but I've never understood what it is you're proposing! This is the Python-Dev list, so feel encouraged to present it in concrete implementation terms instead of ambiguous English. Or maybe an interface? interface a_kind_of_dictionary_that_is_a_collection_of_\ association_objects: # ??? beats me ... Or maybe as a C struct? For example, is "an association object" a (char*, PyObject*) pair? Does this kind of dictionary have keys? If so, of what type? What type are the values? Best I can make sense of the above, the values are "association objects", each of which contains a name and a value, and a key is maybe a duplicate of the name in the association object to which it maps. "A name" may or may not be a string -- I can't tell. Or maybe by "dictionary" you didn't intend Python's current meaning for that word at all. I assume "a value" is a PyObject*. The whole thrust *appears* to be to get names to map to a PyObject** instead of PyObject*, but if that's the ticket I don't know what association objeects have to do with it. > An import like: > > from foo import spam > > would copy the association between the name 'foo' and a > value from module 'spam' into the current module. Where does the idea that 'spam' is a *module* here come from? It doesn't make sense to me, and I'm so lost I'll spare everyone my further confusions . suspecting-the-last-actually-doesn't-make-any-sense-ly y'rs - tim From tim_one at email.msn.com Sun Jan 23 00:29:45 2000 From: tim_one at email.msn.com (Tim Peters) Date: Sat, 22 Jan 2000 18:29:45 -0500 Subject: [Python-Dev] Python 1.6 timing (fwd) In-Reply-To: <38875DD1.B6596@tismer.com> Message-ID: <000701bf6530$90cc31c0$132d153f@tim> [hristian Tismer] > ... > Even better: Refcounting can lead to many new optimizations > if we pay the cost to make INCREF/DECREF into methods. It > has its cost (about 10 percent less pystones), but massive > long-term benefits. The GC patch Guido forced me to look at is based on the observation that it's impossible to create cyclic trash unless a decref leaves a nonzero refcount. So the patch adds a function call to the DECREF macro (if the new refcount is > 0, the object must be added to the set of "suspicious" objects; else the object must be removed from that set). So it roughly adds the cost of a method call to each decref anyway. You would think it adds less , but "the set" now is represented as a splay tree, so *gobs* of hairy code get executed in either case (splay trees do mutating rotations even on a lookup). > ... > Conclusion: I vote for a kind of GC that does just what > refcounts cannot do, but please keep with the refcounts. I like 'em too! BTW, Toby posted (at least an earlier version of) the patch to c.l.py, if anyone else wants to dig into it (I may have mentioned before that I'm short on time ). From tim_one at email.msn.com Sun Jan 23 05:59:38 2000 From: tim_one at email.msn.com (Tim Peters) Date: Sat, 22 Jan 2000 23:59:38 -0500 Subject: [Python-Dev] Changing existing class instances In-Reply-To: <14472.28540.765858.16133@anthem.cnri.reston.va.us> Message-ID: <000201bf655e$a6a49b80$732d153f@tim> [Barry A. Warsaw] > I completely agree. That's no fun . > I think in general, such long running apps are rare, By definition, they're non-existent under Windows <0.7 wink>. But it depends on which field you're working in. The closer you get to being part of a business or consumer service, the more important it gets; e.g., I've seen serious RFQs for software systems guaranteed to suffer no more than 5 minutes of downtime per *year* (& stiff penalties for failure to meet that). I've never been on the winning end of such an RFQ, so am not sure what it takes to meet it. It's interesting to ponder. Psion has published a little about the software techniques they use in their PDAs (my Psion 3a's remarkably capable "Agenda" app has been running non-stop for a bit over 3 years!). > and in those cases you probably want to be explicit about when > and how the updates occur anyway. My guess is you'd want to be *paranoidly* explicit, leaving nothing to chance. > The one place where automatic updates would be convenient would > be at the interactive prompt, so it might be nice to add a > module that could be imported by PYTHONSTARTUP, and play hook > games to enable automatic updates. Returning the favor, I completely agree. The single thing people at work gripe most about is how to do development under IDLE in such a way that their package-laden systems exhibit the hoped-for changes in response to editing a module deep in the bowels of the system. I don't have a *good* answer to that now; reduced to stuff like writing custom scripts to selectively clear out sys.modules. non-stop-ly y'rs - tim From bwarsaw at cnri.reston.va.us Sun Jan 23 16:07:26 2000 From: bwarsaw at cnri.reston.va.us (Barry A. Warsaw) Date: Sun, 23 Jan 2000 10:07:26 -0500 (EST) Subject: [Python-Dev] Python 1.6 timing References: <000701bf636f$de37c5e0$c355cfc0@ski.org> <000401bf652e$f5266b60$132d153f@tim> Message-ID: <14475.6446.336166.192186@anthem.cnri.reston.va.us> >>>>> "TP" == Tim Peters writes: TP> REBOL did it by floating a trendy Internet business plan that TP> actually attracted enough venture capital to hire about 30 TP> people; Python, unfortunately , seems to attract people TP> who already have demanding jobs. I think all we have to do is change the name for 1.6 to LinuxPython 2.0, then split off and go IPO. The more money we lose, the higher our stock will go and we can use our market cap to hire all those warm bodies. -Barry From jeremy at cnri.reston.va.us Sun Jan 23 19:54:40 2000 From: jeremy at cnri.reston.va.us (Jeremy Hylton) Date: Sun, 23 Jan 2000 13:54:40 -0500 (EST) Subject: [Python-Dev] Python 1.6 timing In-Reply-To: <000401bf652e$f5266b60$132d153f@tim> References: <000701bf636f$de37c5e0$c355cfc0@ski.org> <000401bf652e$f5266b60$132d153f@tim> Message-ID: <14475.20080.508651.261991@bitdiddle.cnri.reston.va.us> >>>>> "TP" == Tim Peters writes: TP> [David Ascher] >> I propose that it be called the Oracle instead. As in, whoever >> is Oracle would get some training with Tim Peters and learn how >> to channel G__do. TP> I'm afraid that wouldn't work. The whole secret to channeling TP> Guido in the *past* was to have been an ABC user: all you had to TP> do is notice the things about ABC that you loved and the ones TP> that would drive any sane *experienced* programmer mad with TP> frustration. Voila! Guido's mind is your mind . I have discovered another approach. CNRI put in a cleam room on the second floor last year. I recently discovered a little door behind some metrology device in a corner of the clean room. The door opens onto a tunnel that leads directly into Guido's mind. Unfortunately, it won't be of much use for a pumpkin-holder or channeler, because after about 15 minutes you are deposited on the shoulder of the Dulles Toll Road. who-wants-to-be-John-Malkovich-when-they-could-be-Guido-ly y'rs, Jeremy From skip at mojam.com Wed Jan 26 04:42:06 2000 From: skip at mojam.com (Skip Montanaro) Date: Tue, 25 Jan 2000 21:42:06 -0600 Subject: [Python-Dev] Multiple dicts for string interpolation? Message-ID: <200001260342.VAA10627@beluga.mojam.com> Every once in awhile I want to perform string interpolation using more than one dictionary. One way is to build a dictionary that's a union of multiple dictionaries: dict = {} dict.update(d1) dict.update(d2) ... s = format % dict Another way is the MultiDict approach that Digital Creations (used to?) use in their DocumentTemplate module (I can't remember the exact usage any more): dict = MultiDict() dict.append(d1) dict.append(d2) ... s = format % dict A MultiDict object maintains a list of the dicts it's been fed and searches them in order when __getitem__ is called. I'd like to propose a third alternative. How about if the string interpolation function accepted a tuple of dictionaries directly: s = format % (d1, d2) It would only be used when named interpolation was expected. I don't think there would be any conflict with current % operator semantics. Skip Montanaro | http://www.mojam.com/ skip at mojam.com | http://www.musi-cal.com/ 847-971-7098 From guido at CNRI.Reston.VA.US Wed Jan 26 05:13:28 2000 From: guido at CNRI.Reston.VA.US (Guido van Rossum) Date: Tue, 25 Jan 2000 23:13:28 -0500 Subject: [Python-Dev] Multiple dicts for string interpolation? In-Reply-To: Your message of "Tue, 25 Jan 2000 21:42:06 CST." <200001260342.VAA10627@beluga.mojam.com> References: <200001260342.VAA10627@beluga.mojam.com> Message-ID: <200001260413.XAA02813@eric.cnri.reston.va.us> > I'd like to propose a third alternative. How about if the string > interpolation function accepted a tuple of dictionaries directly: > > s = format % (d1, d2) > > It would only be used when named interpolation was expected. I don't think > there would be any conflict with current % operator semantics. Gut feeling: it's dangerous to fill up every possible dark corner with specific semantics that are occasionally useful, because if you go too far you lose useful redundancy, and you end up with Perl. Not sure whether this particular suggestion is "going too far." I think it depends on to what extent this is a common, useful idiom. Do you have evidence of that? Examples? --Guido van Rossum (home page: http://www.python.org/~guido/) From skip at mojam.com Wed Jan 26 05:38:53 2000 From: skip at mojam.com (Skip Montanaro) Date: Tue, 25 Jan 2000 22:38:53 -0600 (CST) Subject: [Python-Dev] Multiple dicts for string interpolation? In-Reply-To: <200001260413.XAA02813@eric.cnri.reston.va.us> References: <200001260342.VAA10627@beluga.mojam.com> <200001260413.XAA02813@eric.cnri.reston.va.us> Message-ID: <14478.31325.891846.701373@beluga.mojam.com> >> I'd like to propose a third alternative. How about if the string >> interpolation function accepted a tuple of dictionaries directly: >> >> s = format % (d1, d2) Guido> Gut feeling: it's dangerous to fill up every possible dark corner Guido> with specific semantics that are occasionally useful, because if Guido> you go too far you lose useful redundancy, and you end up with Guido> Perl. Yeah, I am kind of taking advantage of the fact that the format operator doesn't happen to use tuples of dicts already, though this seems like a natural extension of the current semantics. Currently, you can have Style of Simple form Complex form Interpolation ------- ----------- ------------ sprintf string tuple of strings named dict tuple of dicts It does complicate the decision making process in the string format routine a bit. Guido> I think it depends on to what extent this is a common, useful Guido> idiom. Do you have evidence of that? Examples? Well, the first place I ran into it was in DocumentTemplates a few years ago. They used an idiom heavily which may have now been replaced by acquisition where you'd effectively push and pop value dicts onto a stack as you entered and exited nested blocks of DTML code. Their solution was a special dict-like object. The example that made the light click for me this evening was having an object whose class dict stores constants and whose instant dict stores varying values. It seemed cleaner to me to do obj = Class() ... s = format % (Class.__dict__, obj.__dict__) than go through the intermediate step of building a separate dict which would just get discarded as soon as this bit of string building was complete. (I will perform this once for each of several thousand instances.) It's not a big deal. If it seems too obscure the other obvious solutions are not gruesome. Skip From skip at mojam.com Wed Jan 26 05:40:20 2000 From: skip at mojam.com (Skip Montanaro) Date: Tue, 25 Jan 2000 22:40:20 -0600 (CST) Subject: [Python-Dev] Multiple dicts for string interpolation? In-Reply-To: <14478.31325.891846.701373@beluga.mojam.com> References: <200001260342.VAA10627@beluga.mojam.com> <200001260413.XAA02813@eric.cnri.reston.va.us> <14478.31325.891846.701373@beluga.mojam.com> Message-ID: <14478.31412.36960.440988@beluga.mojam.com> Oh crap... Of course, the table should have been Style of Simple form Complex form Interpolation ------- ----------- ------------ sprintf string tuple of strings named dict (empty fourth cell...) Skip From klm at digicool.com Wed Jan 26 06:01:36 2000 From: klm at digicool.com (Ken Manheimer) Date: Wed, 26 Jan 2000 00:01:36 -0500 (EST) Subject: [Python-Dev] Multiple dicts for string interpolation? In-Reply-To: <14478.31325.891846.701373@beluga.mojam.com> Message-ID: On Tue, 25 Jan 2000, Skip Montanaro wrote: > Guido> Skip: > >> I'd like to propose a third alternative. How about if the string > >> interpolation function accepted a tuple of dictionaries directly: > >> > >> s = format % (d1, d2) > [...] > Guido> I think it depends on to what extent this is a common, useful > Guido> idiom. Do you have evidence of that? Examples? > > Well, the first place I ran into it was in DocumentTemplates a few years > ago. They used an idiom heavily which may have now been replaced by > acquisition where you'd effectively push and pop value dicts onto a stack as > you entered and exited nested blocks of DTML code. Their solution was a > special dict-like object. Implementation of acquisition basically uses a MultiDict underneath. Consider acquisition as a cumulative context composed from the containers of the target of a web request. (Actually, a distinction is made between the object containment hierarchy of the target and the successive components of the path along which the target is reached by the request, with the containment contexts taking precedence - but that's probably not important here:-) Add in incidental things like the server environment (from which you can get HTTP_REFERER and cookies and so forth). Each of the components can be a dictionary or a MultiDict (or a sequence of pairs, i think), and they're ultimately composed in a MultiDict. I think another place in zope where multidicts play prominently is in the security mechanism, where any object can have local roles, and the ultimate role of a user within a context is composed from the union across the containment hierarchy. There probably are lots of other places where multidicts are used. Suffice to say that there's a lot of composing of contexts that goes on in Zope in general, acquistion being a prime example but not the only one, and multidicts play heavily in many. I would be surprised if this need to combine contexts is peculiar to web server, or general server applications. > [...] > It's not a big deal. If it seems too obscure the other obvious solutions > are not gruesome. I suppose we'd be pretty happy to have something like MultiDict as part of python... Ken klm at digicool.com (Who's the only one left in fredericksburg to speak up, at the moment:-) From tim_one at email.msn.com Wed Jan 26 06:39:19 2000 From: tim_one at email.msn.com (Tim Peters) Date: Wed, 26 Jan 2000 00:39:19 -0500 Subject: [Python-Dev] Multiple dicts for string interpolation? In-Reply-To: <200001260413.XAA02813@eric.cnri.reston.va.us> Message-ID: <000101bf67bf$b103e460$592d153f@tim> [Skip, wants to interpolate multiple dicts via "%", suggests passing a tuple of dicts: format % (d1, d2, ...)] [Guido] > ... > I think it depends on to what extent this is a common, useful > idiom. Do you have evidence of that? Examples? You yourself raised one last century : simply wanting to interpolate from both locals() and globals(). At the time, the idea of a new dict-like mapping object (capturing Python's lookup rules) appealed to you. I still like that, and note that the apparent need becomes more acute if "deep nesting" is ever added. I wasn't aware of the MultiDict approach Skip mentioned, but thought it looked spot on for the general case! Skip, is the long-windedness of dict = MultiDict() dict.append(d1) dict.append(d2) ... s = format % dict the part you didn't like about that? If so, how about changing the constructor to def __init__(self, *dicts): ... instead so you could use it as a one-liner format % MultiDict(d1, d2, ...) ? That's exactly the same as the tuple idea, except there's a nice descriptive word in the middle of it . From jack at oratrix.nl Wed Jan 26 10:56:18 2000 From: jack at oratrix.nl (Jack Jansen) Date: Wed, 26 Jan 2000 10:56:18 +0100 Subject: [Python-Dev] Multiple dicts for string interpolation? In-Reply-To: Message by "Tim Peters" , Wed, 26 Jan 2000 00:39:19 -0500 , <000101bf67bf$b103e460$592d153f@tim> Message-ID: <20000126095619.DC67D36E440@snelboot.oratrix.nl> > the part you didn't like about that? If so, how about changing the > constructor to > > def __init__(self, *dicts): > ... > > instead so you could use it as a one-liner > > format % MultiDict(d1, d2, ...) > > ? That's exactly the same as the tuple idea, except there's a nice > descriptive word in the middle of it . I've always wonderer why dict+dict isn't supported (or possibly dict|dict, if the key-collision semantics of + on dict are seen as a problem). Is there a good reason for this, or is it just that there are other more important things to implement? This wouldn't be a replacement for all uses of MultiDict, as it would probably have to create a new dict to keep semantics in line with those of list+list -- Jack Jansen | ++++ stop the execution of Mumia Abu-Jamal ++++ Jack.Jansen at oratrix.com | ++++ if you agree copy these lines to your sig ++++ www.oratrix.nl/~jack | see http://www.xs4all.nl/~tank/spg-l/sigaction.htm From guido at CNRI.Reston.VA.US Wed Jan 26 13:41:45 2000 From: guido at CNRI.Reston.VA.US (Guido van Rossum) Date: Wed, 26 Jan 2000 07:41:45 -0500 Subject: [Python-Dev] Multiple dicts for string interpolation? In-Reply-To: Your message of "Wed, 26 Jan 2000 10:56:18 +0100." <20000126095619.DC67D36E440@snelboot.oratrix.nl> References: <20000126095619.DC67D36E440@snelboot.oratrix.nl> Message-ID: <200001261241.HAA03001@eric.cnri.reston.va.us> [Tim] > > format % MultiDict(d1, d2, ...) > > > > ? That's exactly the same as the tuple idea, except there's a nice > > descriptive word in the middle of it . Nice. [Jack] > I've always wonderer why dict+dict isn't supported (or possibly > dict|dict, if the key-collision semantics of + on dict are seen as a > problem). Is there a good reason for this, or is it just that there > are other more important things to implement? The reason is that + (or |) looks symmetrical, but for the key collisions, one of them has to lose. We now have dict1.update(dict2), which is a bit more cumbersome, but makes it much clearer who is the loser. --Guido van Rossum (home page: http://www.python.org/~guido/) From skip at mojam.com Wed Jan 26 15:30:09 2000 From: skip at mojam.com (Skip Montanaro) Date: Wed, 26 Jan 2000 08:30:09 -0600 (CST) Subject: [Python-Dev] Multiple dicts for string interpolation? In-Reply-To: <000101bf67bf$b103e460$592d153f@tim> References: <200001260413.XAA02813@eric.cnri.reston.va.us> <000101bf67bf$b103e460$592d153f@tim> Message-ID: <14479.1265.213769.810138@beluga.mojam.com> Tim> Skip, is the long-windedness of Tim> dict = MultiDict() Tim> dict.append(d1) Tim> dict.append(d2) Tim> ... Tim> s = format % dict Tim> the part you didn't like about that? If so, how about changing the Tim> constructor to Tim> def __init__(self, *dicts): Tim> ... Tim> instead so you could use it as a one-liner Tim> format % MultiDict(d1, d2, ...) Tim> ? That's exactly the same as the tuple idea, except there's a nice Tim> descriptive word in the middle of it . The long-windedness was part of it. The performance hit of composing dictionaries thousands of times to perform a single format operation was also a consideration. Okay, side excursion into the Zope source tree... What I was calling MultiDict is actually MultiMapping (written in C, BTW). As a side effect of my Zope install here, I even already have it in sys.path (go figure!). And it turns out to work just as Tim surmised: >>> d1 = {"a": 1} >>> d2 = {"b": 2} >>> d = MultiMapping.MultiMapping(d1, d2) >>> d["b"] 2 >>> d["a"] 1 Dang! Turns out Jim Fulton has a time machine also. I guess the next question is to extend Ken's comment about getting it into the Python core. Would that be something possible for 1.6? I used a Python version of MultiMapping in an ancient version of DocumentTemplate. I'm sure the C version has been around for at least two or three years and would appear pretty darn stable, since it seems to be at the core of a lot of Zope's coolness. Skip From ping at lfw.org Thu Jan 27 08:06:01 2000 From: ping at lfw.org (Ka-Ping Yee) Date: Wed, 26 Jan 2000 23:06:01 -0800 (PST) Subject: [Python-Dev] Multiple dicts for string interpolation? In-Reply-To: <14478.31325.891846.701373@beluga.mojam.com> Message-ID: On Tue, 25 Jan 2000, Skip Montanaro wrote: > > Guido> I think it depends on to what extent this is a common, useful > Guido> idiom. Do you have evidence of that? Examples? > > Well, the first place I ran into it was in DocumentTemplates a few years > ago. They used an idiom heavily which may have now been replaced by > acquisition where you'd effectively push and pop value dicts onto a stack as > you entered and exited nested blocks of DTML code. Their solution was a > special dict-like object. That's really interesting. I wrote a bunch of Python wrappers for a UI toolkit a little while ago, and there were two main pieces of machinery i built to make the toolkit pleasant to use: 1. a reasonably nice C++ extension class kit (this is where i tried overloading operator new for the first time, so it would allocate memory that could be freed by PyMem_DEL -- i don't know if CXX uses the same approach) 2. a second layer of Python wrapper classes for the extension classes that implements extra methods in Python, and maintains a hierarchy of default keyword argument values along the inheritance hierarchy of widgets The second of these things involved implementing exactly the kind of dictionary stack that you mentioned. The programming idiom for building widgets goes something like: defaultstack = {} # maps class object to list of defaults dictionaries class Label(Component): defaults = _dict(text="Label", align=LEFT) class Button(Label): defaults = _dict(text="Button", align=CENTER, shadow=2) ... w = Window(...) Button.push(fg="white", bg="red", font="-*-courier-bold-r-normal--14-*-*-*-*-*-*-*") a = Button(w, text="one") b = Button(w, text="two") c = Button(w, text="three") Button.pop() This way you can install some options for a while and make a bunch of widgets with your defaults, then pop the options and go back to the previous state. The layers of dictionaries that get composed in every widget's __init__ function are (in order of priority): 1. any non-None keyword arguments to __init__ 2. any non-None values in class.defaults 3. any non-None values in class.__bases__[0].defaults 4. any non-None values in class.__bases__[0].__bases__[0].defaults etc. When a new set of defaults is push()ed, the class's current defaults are saved on the defaultstack for the class, and restored when pop() gets called. I don't *know* if this is really the best way to do things, but it has seemed to work out pretty well in practice. It makes it more convenient to deal with all the options you have to throw around especially when doing UI stuff. Anyway, i noticed the same sort of thing today while wondering about using keyword arguments for HTML tag attributes. (Perhaps HTMLgen does this sort of thing already -- sorry i haven't looked at it.) Anyway, the following sort of helper might be useful in general: class Default: def __init__(self, cl, **defaults): self.cl = cl self.defaults = defaults def __call__(self, *args, **kw): for key, value in self.defaults: if not kw.has_key(key): kw[key] = value return apply(self.cl, args, kw) Then you could do the same thing as above with: MyButton = Default(Button, fg="white", bg="red", font="-*-courier-bold-r-normal--14-*-*-*-*-*-*-*") a = MyButton(w, text="one") b = MyButton(w, text="two") c = MyButton(w, text="three") This is probably a cleaner way to do things. I haven't tried it, but it might be a nice thing to have in Tkinter. -- ?!ng From ping at lfw.org Fri Jan 28 05:36:49 2000 From: ping at lfw.org (Ka-Ping Yee) Date: Thu, 27 Jan 2000 20:36:49 -0800 (PST) Subject: [Python-Dev] Python 1.6 timing In-Reply-To: <14475.20080.508651.261991@bitdiddle.cnri.reston.va.us> Message-ID: On Sun, 23 Jan 2000, Jeremy Hylton wrote: > > I have discovered another approach. CNRI put in a cleam room on the > second floor last year. I recently discovered a little door behind > some metrology device in a corner of the clean room. The door opens > onto a tunnel that leads directly into Guido's mind. Unfortunately, > it won't be of much use for a pumpkin-holder or channeler, because > after about 15 minutes you are deposited on the shoulder of the Dulles > Toll Road. I almost fell out of my chair laughing when i read this. What do you think would happen if Guido went into the tunnel? Perhaps http://www.lfw.org/jminc/Guido/http://www.python.org/ (What you get is a generalization of some earlier silliness... the description of the original is at http://www.lfw.org/jminc/.) -- ?!ng From jim at digicool.com Fri Jan 28 16:02:12 2000 From: jim at digicool.com (Jim Fulton) Date: Fri, 28 Jan 2000 10:02:12 -0500 Subject: [Python-Dev] Multiple dicts for string interpolation? References: <200001260342.VAA10627@beluga.mojam.com> Message-ID: <3891AF74.1E81D7F8@digicool.com> Skip Montanaro wrote: > > Every once in awhile I want to perform string interpolation using more than > one dictionary. One way is to build a dictionary that's a union of multiple > dictionaries: > > dict = {} > dict.update(d1) > dict.update(d2) > ... > s = format % dict > > Another way is the MultiDict approach that Digital Creations (used to?) use > in their DocumentTemplate module (I can't remember the exact usage any > more): > > dict = MultiDict() > dict.append(d1) > dict.append(d2) Actually, push (and pop). The namspaces are managed as a stack. > ... > s = format % dict > > A MultiDict object maintains a list of the dicts it's been fed and searches > them in order when __getitem__ is called. > > I'd like to propose a third alternative. How about if the string > interpolation function accepted a tuple of dictionaries directly: > > s = format % (d1, d2) > > It would only be used when named interpolation was expected. I don't think > there would be any conflict with current % operator semantics. Yes. In the current semantics, you output the two dictionaries. Try: '%s %s' % ({'hello':'skip'},{}) Jim -- Jim Fulton mailto:jim at digicool.com Python Powered! Technical Director (888) 344-4332 http://www.python.org Digital Creations http://www.digicool.com http://www.zope.org Under US Code Title 47, Sec.227(b)(1)(C), Sec.227(a)(2)(B) This email address may not be added to any commercial mail list with out my permission. Violation of my privacy with advertising or SPAM will result in a suit for a MINIMUM of $500 damages/incident, $1500 for repeats. From jim at digicool.com Fri Jan 28 16:07:24 2000 From: jim at digicool.com (Jim Fulton) Date: Fri, 28 Jan 2000 10:07:24 -0500 Subject: [Python-Dev] Multiple dicts for string interpolation? References: Message-ID: <3891B0AC.D39275DF@digicool.com> Ken Manheimer wrote: > > On Tue, 25 Jan 2000, Skip Montanaro wrote: > > > Guido> Skip: > > >> I'd like to propose a third alternative. How about if the string > > >> interpolation function accepted a tuple of dictionaries directly: > > >> > > >> s = format % (d1, d2) > > [...] > > Guido> I think it depends on to what extent this is a common, useful > > Guido> idiom. Do you have evidence of that? Examples? > > > > Well, the first place I ran into it was in DocumentTemplates a few years > > ago. They used an idiom heavily which may have now been replaced by > > acquisition where you'd effectively push and pop value dicts onto a stack as > > you entered and exited nested blocks of DTML code. Their solution was a > > special dict-like object. > > Implementation of acquisition basically uses a MultiDict underneath. No it doesn't. Acquisition achieves combination of multiple namespaces in much the same way that inheritence does (through delagation). > Consider acquisition as a cumulative context composed from the containers > of the target of a web request. (Actually, a distinction is made between > the object containment hierarchy of the target and the successive > components of the path along which the target is reached by the request, > with the containment contexts taking precedence - but that's probably not > important here:-) Add in incidental things like the server environment > (from which you can get HTTP_REFERER and cookies and so forth). Each of > the components can be a dictionary or a MultiDict (or a sequence of pairs, > i think), and they're ultimately composed in a MultiDict. > > I think another place in zope where multidicts play prominently is in the > security mechanism, where any object can have local roles, and the > ultimate role of a user within a context is composed from the union across > the containment hierarchy. There probably are lots of other places where > multidicts are used. Acquisition plays a role in security, but MultiDicts-like things are not used. > Suffice to say that there's a lot of composing of contexts that goes on in > Zope in general, acquistion being a prime example but not the only one, > and multidicts play heavily in many. I would be surprised if this need to > combine contexts is peculiar to web server, or general server > applications. > > > [...] > > It's not a big deal. If it seems too obscure the other obvious solutions > > are not gruesome. > > I suppose we'd be pretty happy to have something like MultiDict as part of > python... Note that Zope actually uses two separate flavors. The one used most in Zope (in DocumentTemplate) has very specific hooks to work with Zope's security machinery. Jim -- Jim Fulton mailto:jim at digicool.com Python Powered! Technical Director (888) 344-4332 http://www.python.org Digital Creations http://www.digicool.com http://www.zope.org Under US Code Title 47, Sec.227(b)(1)(C), Sec.227(a)(2)(B) This email address may not be added to any commercial mail list with out my permission. Violation of my privacy with advertising or SPAM will result in a suit for a MINIMUM of $500 damages/incident, $1500 for repeats. From jim at digicool.com Fri Jan 28 16:10:26 2000 From: jim at digicool.com (Jim Fulton) Date: Fri, 28 Jan 2000 10:10:26 -0500 Subject: [Python-Dev] Multiple dicts for string interpolation? References: <000101bf67bf$b103e460$592d153f@tim> Message-ID: <3891B162.554622E2@digicool.com> Tim Peters wrote: > (snip) > I wasn't aware of the MultiDict approach Skip mentioned, See the MultiMapping module in ExtensionClass. You can get the latest flavor of this in the latest Zope release. > but thought it > looked spot on for the general case! Skip, is the long-windedness of > > dict = MultiDict() > dict.append(d1) > dict.append(d2) > ... > s = format % dict Note the rather important *stack* sematics of MultiMappings. We often push and pop namespaces on and off of MultiMappings in use. > the part you didn't like about that? If so, how about changing the > constructor to > > def __init__(self, *dicts): > ... > > instead so you could use it as a one-liner > > format % MultiDict(d1, d2, ...) > > ? That's exactly the same as the tuple idea, except there's a nice > descriptive word in the middle of it . This is exactly what the current MultiMapping "class" does. Jim -- Jim Fulton mailto:jim at digicool.com Python Powered! Technical Director (888) 344-4332 http://www.python.org Digital Creations http://www.digicool.com http://www.zope.org Under US Code Title 47, Sec.227(b)(1)(C), Sec.227(a)(2)(B) This email address may not be added to any commercial mail list with out my permission. Violation of my privacy with advertising or SPAM will result in a suit for a MINIMUM of $500 damages/incident, $1500 for repeats. From gward at cnri.reston.va.us Fri Jan 28 17:39:54 2000 From: gward at cnri.reston.va.us (Greg Ward) Date: Fri, 28 Jan 2000 11:39:54 -0500 Subject: [Python-Dev] To-do for Distutils 0.2 (and beyond) Message-ID: <20000128113954.A12965@cnri.reston.va.us> Hi all -- [oops: I *said* that I was cc'ing this to python-dev when I posted it to distutils-sig, but I just plain forgot to. So here it is again, still presumed relevant to python-dev'ers because it directly affects the planned Python 1.6 feature set. Please reply either to me directly or to distutils-sig, because that's where the implementation will be done.] recent developments in the planned release schedule for Python 1.6 (Guido doesn't want to wait for everything planned, but get something out the door in the next couple of months) are lighting a fire under me to get a seriously usable version of Distutils ready *really* soon now. This will be Distutils 0.2; I anticipate that 0.2.x will be included in Python 1.6, where x is the number of attempts it takes me to get something reasonably bug-free out the door. Those if you who were at the Python Conference this past week will have seen bits and pieces of my "laundry list" of desired features that should be added to the Distutils at some point in the future. Given the shortened schedule, it looks like it's necessary to do some pruning and concentrate on the essentials to get something in Python 1.6. So, here is my current laundry list, sorted into a couple of categories: essential for 0.2 (Python 1.6) ----------------- * fix the "dist" command (two-phase manifest, better feedback) (steal ideas and hopefully code from Gordon Macmillan's installer) * fix the "install" command (have the right interface and do the right thing for installating to non-standard or personal directories) * fix some bad nomenclature in the command classes (most likely 'options' -> 'user_options', 'set_default_options()' -> 'initialize_options()', and 'set_final_options()' -> ??? (maybe 'finalize_options()'?)) * build C libraries (for PIL, and other similar distributions) * documentation (two small manuals that should become standard Python manuals: "Installing Python Modules" and "Developing and Distributing Python Modules") * add a bdist command; should at least be able to generate dumb archives of built distributions (eg. a tarball that you unpack from /usr/local, or maybe /usr/local/lib/python1.5/site-packages) desirable for 0.2 ----------------- * "what's installed" database * dependency checking ("is version 1.3 of foo installed?") * don't automatically clobber an existing installation -- confirm, or require a "force" option, or something * command to install C headers (assuming more extensions than NumPy need to do this) put off to 0.3 (Python 1.7?) ---------------------------- * JPython support (most importantly, know where to install .py modules when run from JPython and be able to build Java extensions for JPython) * build static Python binary (for shared-library-challenged OSs) * SWIG support (mainly, know how to run it before building the C extension it generates) * PyFort support (ditto) * Mac support * allow overlapping multi-architecture installations (Michel Sanner's pet peeve and Guido's nightmare ;-) (this would *not* be the default; it would have to be explicitly chosen by brave/cheap/foolhardy installers) * support for archive sites (Parnassus) to pull out meta-info Anyone feel strongly about moving any of these items around, or discarding any entirely, or adding anything? Please let me know by email; I'll summarize to the list. Thanks -- Greg From jeremy at cnri.reston.va.us Sat Jan 29 00:52:53 2000 From: jeremy at cnri.reston.va.us (Jeremy Hylton) Date: Fri, 28 Jan 2000 18:52:53 -0500 (EST) Subject: [Python-Dev] To-do for Distutils 0.2 (and beyond) In-Reply-To: <20000128113954.A12965@cnri.reston.va.us> References: <20000128113954.A12965@cnri.reston.va.us> Message-ID: <14482.11221.451866.695357@bitdiddle.cnri.reston.va.us> >>>>> "GW" == Greg Ward writes: GW> desirable for 0.2 GW> ----------------- GW> * "what's installed" database GW> * dependency checking ("is version 1.3 of foo installed?") These are *not* desirable for version 0.2. Paul Dubois expressed some concern about the complexity of these tasks. I agree completely. I think the chances of getting this done correctly in the next month are slim to none. Don't waste your time adding the kitchen sink to distutils :-); just bang on the simple stuff until it's rock solid. Jeremy From jim at digicool.com Sat Jan 29 02:40:22 2000 From: jim at digicool.com (Jim Fulton) Date: Fri, 28 Jan 2000 20:40:22 -0500 Subject: [Python-Dev] Multiple dicts for string interpolation? References: <200001260413.XAA02813@eric.cnri.reston.va.us> <000101bf67bf$b103e460$592d153f@tim> <14479.1265.213769.810138@beluga.mojam.com> Message-ID: <38924506.808D34F5@digicool.com> Skip Montanaro wrote: > (snip) > I guess the next question is to extend Ken's comment about getting it into > the Python core. Would that be something possible for 1.6? I used a Python > version of MultiMapping in an ancient version of DocumentTemplate. I'm sure > the C version has been around for at least two or three years and would > appear pretty darn stable, Yes. I'm sure you'd have to de-ExtensionClass-ify it to get it into the core. :) > since it seems to be at the core of a lot of > Zope's coolness. Actually, it isn't, as there is a separate similar thing (TemplateDict) used in DocumentTemplate. Jim -- Jim Fulton mailto:jim at digicool.com Python Powered! Technical Director (888) 344-4332 http://www.python.org Digital Creations http://www.digicool.com http://www.zope.org Under US Code Title 47, Sec.227(b)(1)(C), Sec.227(a)(2)(B) This email address may not be added to any commercial mail list with out my permission. Violation of my privacy with advertising or SPAM will result in a suit for a MINIMUM of $500 damages/incident, $1500 for repeats. From guido at CNRI.Reston.VA.US Sun Jan 30 14:32:18 2000 From: guido at CNRI.Reston.VA.US (Guido van Rossum) Date: Sun, 30 Jan 2000 08:32:18 -0500 Subject: [Python-Dev] Adding C ternary select (a?b:c) to Python? Message-ID: <200001301332.IAA12252@eric.cnri.reston.va.us> Dear developers, Eric Raymond has sent me the following patch, which adds conditional expressions to Python. I'd like to hear opinions on whether this is a good thing to add to Python, and whether this is the right syntax. I am a bit skeptical about whether this is sufficiently Pythonic, but on the other hand there have always been requests for such a feature, and the existing solutions are ugly: a and b or c only works when you know for sure that b will never be false, and (a and [b] or [c])[0] is dead ugly... --Guido van Rossum (home page: http://www.python.org/~guido/) Subject: Ternary select -- here it is. From: "Eric S. Raymond" To: Guido Van Rossum Date: Sat, 29 Jan 2000 17:40:31 -0500 X-Eric-Conspiracy: There is no conspiracy Dang, Guido, this was *fun*! This patch extends the Python interpreter to support the C ternary operator, and documents the extension in the Reference Manual. The implementation is dead simple and robust: it's adapted from the existing code for if statements, and adds or changes less than 70 lines of code all told. Diffs between last version checked in and current workfile(s): --- Grammar/Grammar 2000/01/28 17:10:18 1.1 +++ Grammar/Grammar 2000/01/29 22:14:05 @@ -61,7 +61,8 @@ except_clause: 'except' [test [',' test]] suite: simple_stmt | NEWLINE INDENT stmt+ DEDENT -test: and_test ('or' and_test)* | lambdef +test: bool_test ['?' bool_test ':' bool_test] +bool_test: and_test ('or' and_test)* | lambdef and_test: not_test ('and' not_test)* not_test: 'not' not_test | comparison comparison: expr (comp_op expr)* --- Include/token.h 2000/01/28 17:38:55 1.1 +++ Include/token.h 2000/01/29 01:27:00 @@ -74,10 +74,11 @@ #define LEFTSHIFT 34 #define RIGHTSHIFT 35 #define DOUBLESTAR 36 +#define QUERY 37 /* Don't forget to update the table _PyParser_TokenNames in tokenizer.c! */ -#define OP 37 -#define ERRORTOKEN 38 -#define N_TOKENS 39 +#define OP 38 +#define ERRORTOKEN 39 +#define N_TOKENS 34 /* Special definitions for cooperation with parser */ --- Modules/parsermodule.c 2000/01/28 18:03:27 1.1 +++ Modules/parsermodule.c 2000/01/29 22:13:45 @@ -945,6 +945,7 @@ #define validate_star(ch) validate_terminal(ch, STAR, "*") #define validate_vbar(ch) validate_terminal(ch, VBAR, "|") #define validate_doublestar(ch) validate_terminal(ch, DOUBLESTAR, "**") +#define validate_query(ch) validate_terminal(ch, QUERY, "?") #define validate_dot(ch) validate_terminal(ch, DOT, ".") #define validate_name(ch, str) validate_terminal(ch, NAME, str) @@ -963,7 +964,8 @@ VALIDATER(exec_stmt); VALIDATER(compound_stmt); VALIDATER(while); VALIDATER(for); VALIDATER(try); VALIDATER(except_clause); -VALIDATER(test); VALIDATER(and_test); +VALIDATER(test); +VALIDATER(bool_test); VALIDATER(and_test); VALIDATER(not_test); VALIDATER(comparison); VALIDATER(comp_op); VALIDATER(expr); VALIDATER(xor_expr); VALIDATER(and_expr); @@ -1829,12 +1831,34 @@ } /* validate_except_clause() */ +/* bool_test ( | bool_test ? bool_test ) + * + */ static int validate_test(tree) node *tree; { + if (!validate_ntype(tree, test)) + return 0; + else if (NCH(tree) == 1) + return(validate_bool_test(CHILD(tree, 0))); + else if (validate_numnodes(tree, 5, "expr")) + { + return validate_bool_test(CHILD(tree, 0)) + && validate_query(CHILD(tree, 1)) + && validate_bool_test(CHILD(tree, 2)) + && validate_colon(CHILD(tree, 3)) + && validate_bool_test(CHILD(tree, 4)); + } +} /* validate_test() */ + + +static int +validate_bool_test(tree) + node *tree; +{ int nch = NCH(tree); - int res = validate_ntype(tree, test) && is_odd(nch); + int res = validate_ntype(tree, bool_test) && is_odd(nch); if (res && (TYPE(CHILD(tree, 0)) == lambdef)) res = ((nch == 1) @@ -1848,7 +1872,7 @@ } return (res); -} /* validate_test() */ +} /* validate_bool_test() */ static int --- Parser/tokenizer.c 2000/01/28 17:37:48 1.1 +++ Parser/tokenizer.c 2000/01/29 01:27:26 @@ -99,6 +99,7 @@ "LEFTSHIFT", "RIGHTSHIFT", "DOUBLESTAR", + "QUERY", /* This table must match the #defines in token.h! */ "OP", "", @@ -384,6 +385,7 @@ case '}': return RBRACE; case '^': return CIRCUMFLEX; case '~': return TILDE; + case '?': return QUERY; default: return OP; } } --- Python/compile.c 2000/01/28 23:17:19 1.1 +++ Python/compile.c 2000/01/29 22:19:29 @@ -1698,11 +1698,11 @@ } static void -com_test(c, n) +com_bool_test(c, n) struct compiling *c; node *n; { - REQ(n, test); /* and_test ('or' and_test)* | lambdef */ + REQ(n, bool_test); /* and_test ('or' and_test)* | lambdef */ if (NCH(n) == 1 && TYPE(CHILD(n, 0)) == lambdef) { PyObject *v; int i; @@ -1738,6 +1738,32 @@ } static void +com_test(c, n) + struct compiling *c; + node *n; +{ + int op; + REQ(n, test); + com_bool_test(c, CHILD(n, 0)); + + /* is there a following ternary operator? */ + /* XXX optimize the compilation when the guard is a constant */ + if (NCH(n) == 5) + { + int anchor1 = 0, anchor2 = 0; + com_addfwref(c, JUMP_IF_FALSE, &anchor2); + com_addbyte(c, POP_TOP); + com_pop(c, 1); + com_node(c, CHILD(n, 2)); + com_addfwref(c, JUMP_FORWARD, &anchor1); + com_backpatch(c, anchor2); + com_addbyte(c, POP_TOP); + com_node(c, CHILD(n, 4)); + com_backpatch(c, anchor1); + } +} + +static void com_list(c, n, toplevel) struct compiling *c; node *n; @@ -2931,6 +2957,9 @@ break; case test: com_test(c, n); + break; + case bool_test: + com_bool_test(c, n); break; case and_test: com_and_test(c, n); --- Doc/ref/ref5.tex 2000/01/29 21:28:13 1.1 +++ Doc/ref/ref5.tex 2000/01/29 22:00:02 @@ -764,7 +764,7 @@ \section{Boolean operations\label{Booleans}} \indexii{Boolean}{operation} -Boolean operations have the lowest priority of all Python operations: +Boolean operations have the lowest priority of all Python binary operations: \begin{verbatim} expression: or_test | lambda_form @@ -832,6 +832,24 @@ def make_incrementor(increment): return lambda x, n=increment: x+n \end{verbatim} + +\section{Select\label{select}} +\index{select} + +The select operator is a ternary operator with lower priority than +boolean operations (and thus lower priority than all other binary and +unary operators). + +\begin{verbatim} +select_expr: xor_expr | xor_expr "?" xor_expr ":" xor_expr +\end{verbatim} + +If its first operand is nonempty, the value of a select operation is +its second operand; otherwise the value is the third operand. + +(The semantics and precedence level of select are intended to be +unsurprising to programmers familiar with \C's ternary select +operator.) \section{Expression lists\label{exprlists}} \indexii{expression}{list} End of diffs. -- Eric S. Raymond You know why there's a Second Amendment? In case the government fails to follow the first one. -- Rush Limbaugh, in a moment of unaccustomed profundity 17 Aug 1993 From jim at digicool.com Sun Jan 30 14:52:32 2000 From: jim at digicool.com (Jim Fulton) Date: Sun, 30 Jan 2000 08:52:32 -0500 Subject: [Python-Dev] Adding C ternary select (a?b:c) to Python? References: <200001301332.IAA12252@eric.cnri.reston.va.us> Message-ID: <38944220.3177B402@digicool.com> Guido van Rossum wrote: > > Dear developers, > > Eric Raymond has sent me the following patch, which adds conditional > expressions to Python. I'd like to hear opinions on whether this is a > good thing to add to Python, and whether this is the right syntax. Yee ha! I think that this is a great idea. I'm surprised that using the colon doesn't cause problems. I'm not a grammer lawyer, and don't care that much. I very much would like to see a conditional expression. I wouldn't object if it was spelled differently than C's. > I am a bit skeptical about whether this is sufficiently Pythonic, but > on the other hand there have always been requests for such a feature, > and the existing solutions are ugly: > > a and b or c > > only works when you know for sure that b will never be false, and > > (a and [b] or [c])[0] > > is dead ugly... Yup. (a and (b,) or (c,))[0] is even worse. ;) Jim -- Jim Fulton mailto:jim at digicool.com Technical Director (888) 344-4332 Python Powered! Digital Creations http://www.digicool.com http://www.python.org Under US Code Title 47, Sec.227(b)(1)(C), Sec.227(a)(2)(B) This email address may not be added to any commercial mail list with out my permission. Violation of my privacy with advertising or SPAM will result in a suit for a MINIMUM of $500 damages/incident, $1500 for repeats. From esr at thyrsus.com Sun Jan 30 16:59:42 2000 From: esr at thyrsus.com (Eric S. Raymond) Date: Sun, 30 Jan 2000 10:59:42 -0500 Subject: [Python-Dev] Adding C ternary select (a?b:c) to Python? In-Reply-To: <38944220.3177B402@digicool.com>; from Jim Fulton on Sun, Jan 30, 2000 at 08:52:32AM -0500 References: <200001301332.IAA12252@eric.cnri.reston.va.us> <38944220.3177B402@digicool.com> Message-ID: <20000130105941.A10861@thyrsus.com> Jim Fulton : > I'm surprised that using the colon doesn't cause problems. Pgen doesn't tag this ambiguous. The LL(1) traversal actually helps here; by the time you see a colon, you already know whether or not you're parsing a ternary telect. -- Eric S. Raymond Don't think of it as `gun control', think of it as `victim disarmament'. If we make enough laws, we can all be criminals. From guido at CNRI.Reston.VA.US Sun Jan 30 17:40:32 2000 From: guido at CNRI.Reston.VA.US (Guido van Rossum) Date: Sun, 30 Jan 2000 11:40:32 -0500 Subject: [Python-Dev] Adding C ternary select (a?b:c) to Python? In-Reply-To: Your message of "Sun, 30 Jan 2000 10:59:42 EST." <20000130105941.A10861@thyrsus.com> References: <200001301332.IAA12252@eric.cnri.reston.va.us> <38944220.3177B402@digicool.com> <20000130105941.A10861@thyrsus.com> Message-ID: <200001301640.LAA12598@eric.cnri.reston.va.us> > Jim Fulton : > > I'm surprised that using the colon doesn't cause problems. [ESR] > Pgen doesn't tag this ambiguous. The LL(1) traversal actually helps > here; by the time you see a colon, you already know whether or not you're > parsing a ternary telect. Interestingly, the very ad-hoc parsing that I described in the compiling/parsing session on devday would be hit by this... I was looking for a colon at nesting level zero. Serves me right for not using a real parse :-) --Guido van Rossum (home page: http://www.python.org/~guido/) From da at ski.org Sun Jan 30 19:07:51 2000 From: da at ski.org (David Ascher) Date: Sun, 30 Jan 2000 10:07:51 -0800 Subject: [Python-Dev] Adding C ternary select (a?b:c) to Python? References: <200001301332.IAA12252@eric.cnri.reston.va.us> <38944220.3177B402@digicool.com> <20000130105941.A10861@thyrsus.com> <200001301640.LAA12598@eric.cnri.reston.va.us> Message-ID: <004101bf6b4c$ed2ab9b0$0100000a@ski.org> FWIW, the lack of a ternary select is one of the frequently asked questions in my Python courses. It would make TomC happier as well. I'm not sure the latter is a feature. =) On the topic of aesthetics, the C syntax doesn't strike me as the ultimate in pythonicity but it's not too bad either. I can't think of an alternative that doesn't involve a new reserved word. --david From gvwilson at nevex.com Sun Jan 30 21:22:21 2000 From: gvwilson at nevex.com (gvwilson at nevex.com) Date: Sun, 30 Jan 2000 15:22:21 -0500 (EST) Subject: [Python-Dev] Eight suggestions for Python books Message-ID: I realize this is a bit off-topic, but based on discussions with various publishers over the last couple of years, and on conversations at the conference last week, I wrote up some notes on books that I think would help Python succeed, and posted them to comp.lang.python under the heading "Eight suggestions for Python books". Some of the books are specificially about Python, while others try to use Python to fill holes in the curriculum, and thereby get Python into colleges through the side door (in the same way that networking and computer graphics texts helped C become more popular). Hope it's useful... Greg From mal at lemburg.com Sun Jan 30 22:34:51 2000 From: mal at lemburg.com (M.-A. Lemburg) Date: Sun, 30 Jan 2000 22:34:51 +0100 Subject: [Python-Dev] Adding C ternary select (a?b:c) to Python? References: <200001301332.IAA12252@eric.cnri.reston.va.us> Message-ID: <3894AE7A.BE89D9B4@lemburg.com> > --- Include/token.h 2000/01/28 17:38:55 1.1 > +++ Include/token.h 2000/01/29 01:27:00 > @@ -74,10 +74,11 @@ > #define LEFTSHIFT 34 > #define RIGHTSHIFT 35 > #define DOUBLESTAR 36 > +#define QUERY 37 > /* Don't forget to update the table _PyParser_TokenNames in tokenizer.c! */ > -#define OP 37 > -#define ERRORTOKEN 38 > -#define N_TOKENS 39 > +#define OP 38 > +#define ERRORTOKEN 39 > +#define N_TOKENS 34 Shouldn't this read #define N_TOKENS 40 ?! Apart from that I wouldn't mind having this patch in the core :-) -- Marc-Andre Lemburg ______________________________________________________________________ Business: http://www.lemburg.com/ Python Pages: http://www.lemburg.com/python/ From tim_one at email.msn.com Mon Jan 31 00:25:30 2000 From: tim_one at email.msn.com (Tim Peters) Date: Sun, 30 Jan 2000 18:25:30 -0500 Subject: [Python-Dev] Adding C ternary select (a?b:c) to Python? In-Reply-To: <200001301332.IAA12252@eric.cnri.reston.va.us> Message-ID: <000301bf6b79$4f0c8a60$482d153f@tim> [Guido van Rossum] > Eric Raymond has sent me the following patch, which adds conditional > expressions to Python. I'd like to hear opinions on whether this > is a good thing to add to Python, Marginal; not evil, but of minor utility. > and whether this is the right syntax. If and only if you were a C programmer first. BTW, insert s where needed throughout . > I am a bit skeptical about whether this is sufficiently Pythonic, > but on the other hand there have always been requests for such a > feature, There have always been requests for the union of all features from all other languages. > and the existing solutions are ugly: > > a and b or c > > only works when you know for sure that b will never be false, Too error prone. > and > > (a and [b] or [c])[0] > > is dead ugly... Well, I'm the guy who invented that one! The thread that spawned it was just playfully wondering whether it was *possible* -- and if I didn't solve it, Majewski would have using even uglier __xxx__ trickery. I've never used it in a real program, and shoot people who do. So there is no reasonable way to spell ?: as a one-liner today, period. The question is whether that's "a lack" worth doing something about. I can live without it. Surprised that Jim (Fulton) seems so keen on it: his cPickle.c uses ?: exactly once in 4400 lines of C, and in a line that would have been clearer if C had a max function (or is it min? it can take a while to reverse-engineer the intent of a ?:! ... not good when it happens; and I recall one of the contributed patches that went into 1.5.2 longobject.c, that had Guido & I both cracking a C manual just to figure out how C would *parse* a particularly nutso blob of nested ?: thingies). If this goes in (I'm not deadly opposed, just more opposed than in favor), I'd like to see "else" used instead of the colon (cond "?" true "else" false). The question mark is reasonably mnemonic, but a colon makes no sense here. Now let's see whether people really want the functionality or are just addicted to C syntax . BTW, a number of other changes would be needed to the Lang Ref manual (e.g., section 2.6 (Delimeters) explicitly says that "?" isn't used in Python today, and that its appeareance outside a string literal or comment is "an unconditional error"; etc). crabby-old-man-ly y'rs - tim From esr at thyrsus.com Mon Jan 31 00:43:17 2000 From: esr at thyrsus.com (Eric S. Raymond) Date: Sun, 30 Jan 2000 18:43:17 -0500 Subject: [Python-Dev] Adding C ternary select (a?b:c) to Python? In-Reply-To: <000301bf6b79$4f0c8a60$482d153f@tim>; from Tim Peters on Sun, Jan 30, 2000 at 06:25:30PM -0500 References: <200001301332.IAA12252@eric.cnri.reston.va.us> <000301bf6b79$4f0c8a60$482d153f@tim> Message-ID: <20000130184317.A12833@thyrsus.com> Tim Peters : > If this goes in (I'm not deadly opposed, just more opposed than in favor), > I'd like to see "else" used instead of the colon (cond "?" true "else" > false). The question mark is reasonably mnemonic, but a colon makes no > sense here. I have to say that I think any ternary syntax that mixes a single-character operator with a keyword would be intolerably ugly. > Now let's see whether people really want the functionality or are just > addicted to C syntax . It's not that simple. People clearly want the functionality; we've seen ample evidence of that. Given that, I think the presumption has to be in favor of using the familiar C syntax rather than an invention that would necessarily be more obscure. > BTW, a number of other changes would be needed to the Lang Ref manual (e.g., > section 2.6 (Delimeters) explicitly says that "?" isn't used in Python > today, and that its appeareance outside a string literal or comment is "an > unconditional error"; etc). I'm certainly willing to fix that. -- Eric S. Raymond [The disarming of citizens] has a double effect, it palsies the hand and brutalizes the mind: a habitual disuse of physical forces totally destroys the moral [force]; and men lose at once the power of protecting themselves, and of discerning the cause of their oppression. -- Joel Barlow, "Advice to the Privileged Orders", 1792-93 From dascher at mindspring.com Mon Jan 31 01:09:39 2000 From: dascher at mindspring.com (David Ascher) Date: Sun, 30 Jan 2000 16:09:39 -0800 Subject: [Python-Dev] Adding C ternary select (a?b:c) to Python? References: <200001301332.IAA12252@eric.cnri.reston.va.us> <000301bf6b79$4f0c8a60$482d153f@tim> <20000130184317.A12833@thyrsus.com> Message-ID: <005c01bf6b7f$7a3a8f60$0100000a@ski.org> > > Now let's see whether people really want the functionality or are just > > addicted to C syntax . > > It's not that simple. People clearly want the functionality; we've > seen ample evidence of that. I personally haven't been stunned by the ample evidence you mention. While folks do ask about the ternary select periodically in classes and on the net, none of my students at least are especially upset when I point out the readability of: if a: b = c else: b = d > Given that, I think the presumption has > to be in favor of using the familiar C syntax rather than an invention > that would necessarily be more obscure. The presumption from the language design point of view is to do what's right regardless of language background, not what's in C -- when Guido remembered that, he chose 'and' and 'or' over '&&' and '||'. When Guido forgot that, he chose integer division =). While all of the folks on this list are comfortable with C, I can point out that a (possibly surprisingly) large proportion of the Python programmers I have taught have never used C or never felt comfortable with it. If CP4E succeeds, that proportion will grow, not shrink. I do think that taking a page from Randy Pausch would be a good idea in this case. My guess is that english words would emerge from trying to teach non-programmers the concept, but I of course don't have data on the topic. I wonder how high-school teachers teach the hook-colon in C intro classes, specifically what _words_ they use. Those words might lead to alternative syntaxes. Finally, something at the edge of my brain is trying to combine the logic of the ternary select (which is clearly related to control flow) and a more generalized switch statement. But I'm not seeing anything syntactically appealing at present. That said, the hook-colon syntax is appealing from a release management perspective because it fits within the current set of reserved words and clearly isn't the hardest concept to teach. --david From petrilli at amber.org Mon Jan 31 01:54:06 2000 From: petrilli at amber.org (Christopher Petrilli) Date: Sun, 30 Jan 2000 19:54:06 -0500 Subject: [Python-Dev] Adding C ternary select (a?b:c) to Python? In-Reply-To: <005c01bf6b7f$7a3a8f60$0100000a@ski.org>; from dascher@mindspring.com on Sun, Jan 30, 2000 at 04:09:39PM -0800 References: <200001301332.IAA12252@eric.cnri.reston.va.us> <000301bf6b79$4f0c8a60$482d153f@tim> <20000130184317.A12833@thyrsus.com> <005c01bf6b7f$7a3a8f60$0100000a@ski.org> Message-ID: <20000130195406.A25682@trump.amber.org> The question comes from what "problem" you're trying to solve. The ?: syntax does not introduce any new "functionality" to the language, nor does it make it capable of solving problems or requirements that it can not do at the current time. The second qustion I'd ask is, who is this aimed at? It's certainly not aimed at first-time programmers, as I know from experience that the ?: is one of the hardest things to teach people in C (after pointers), and often I leave it out of training when I did it. It's simply a "shorthand" not a new functionality. If its aimed at experienced programmers, I'd argue that it's at best "non-pythonic" and at worst a hack, taken from a language in which it exposes the "macro assembler" approach. Python is not a language that has been optimized for "minimal typing", it's much more verbose than most languages, and so that argument shouldn' be applied. Perhaps it's for optimization? That was I believe the original argument made for it in K&R, in that optimizers in that day were rather antiquated, wheras today, I believe that any C compiler would get it right if it were expressed in its full form. (Timbot?) So, it comes down to a few questions for me: Does it solve a new problem? No Is it pythonic? No Does it make it faster? No Given Pyton's CP4E goals, and its general place as an easy to use language, I'd argue this patch would be counter to all of those goals. Sorry if I pushed someone's buton, but... I saw a lot of hints at making Python MUCH more complex, which is counter to why I changed and dropped many other languags. Chris -- | Christopher Petrilli | petrilli at amber.org From tim_one at email.msn.com Mon Jan 31 01:44:34 2000 From: tim_one at email.msn.com (Tim Peters) Date: Sun, 30 Jan 2000 19:44:34 -0500 Subject: [Python-Dev] Adding C ternary select (a?b:c) to Python? In-Reply-To: <20000130184317.A12833@thyrsus.com> Message-ID: <000801bf6b84$588c2d60$482d153f@tim> [Tim, tosses off cond "?" true "else" false in apparent hatred of colons] [Eric S. Raymond] > I have to say that I think any ternary syntax that mixes a > single-character operator with a keyword would be intolerably ugly. It's certainly not attractive . Guido is the Master of Syntax; if he decides the functionality is Pythonic, he'll dream up a good Pythonic syntax. I'll refrain from suggesting "if" cond "lambda" true "else" false . >> Now let's see whether people really want the functionality or are just >> addicted to C syntax . > It's not that simple. People clearly want the functionality; we've > seen ample evidence of that. I have not. Really! This has been debated for nearly a decade, with no consensus (the invention of the (a and [b] or [c])[0] atrocity predates c.l.py!). *Some* people certainly want ?: (or equivalent) a lot; but others are equally opposed. Note that lack of ?: didn't have enough of a constituency in Andrew Kuchling's eyes either to make his original "Python Warts" paper, or its revisions: http://starship.python.net/crew/amk/python/writing/warts.html No change ever proposed has failed to attract vocal & persistent supporters, so it's not as simple as *that* either <0.5 wink>. > Given that, I think the presumption has to be in favor of using the > familiar C syntax rather than an invention that would necessarily be > more obscure. By count, I'm sure many more languages (from virtually all functional languages to Icon) use "if cond then true else false" for this purpose; obscurity is relative to your background. At least "if x then y else z" is clear on the face of it (which may betray my background ). "then" has no chance of getting into Python1, though. My core objection is that ?: doesn't "look pretty": it's not at all suggestive of what it means, and the effects on precedence and associativity are unattractive ("see C, copy C" is the only sense there is to it, and rules for ?: are-- as I noted last time --obscure). Good syntax counts for a lot in Python -- which is why it doesn't look like C now. Get a good syntax, and most of my objections vanish; I don't have a good syntax to suggest, though. passing-the-ball-back-to-guido-where-he-always-knew-it- would-land-ly y'rs - tim From esr at thyrsus.com Mon Jan 31 02:07:11 2000 From: esr at thyrsus.com (Eric S. Raymond) Date: Sun, 30 Jan 2000 20:07:11 -0500 Subject: [Python-Dev] Adding C ternary select (a?b:c) to Python? In-Reply-To: <20000130195406.A25682@trump.amber.org>; from Christopher Petrilli on Sun, Jan 30, 2000 at 07:54:06PM -0500 References: <200001301332.IAA12252@eric.cnri.reston.va.us> <000301bf6b79$4f0c8a60$482d153f@tim> <20000130184317.A12833@thyrsus.com> <005c01bf6b7f$7a3a8f60$0100000a@ski.org> <20000130195406.A25682@trump.amber.org> Message-ID: <20000130200711.A13063@thyrsus.com> Christopher Petrilli : > The question comes from what "problem" you're trying to solve. The ?: syntax > does not introduce any new "functionality" to the language, nor does it > make it capable of solving problems or requirements that it can not do > at the current time. Well, in a theoretical sense, you're right. But then, even troff macros and INTERCAL are Turing-complete . One of the lessons of Python to this old LISPer is that *notation matters*. Theoretically, Python is a subset of Scheme-with-objects using a vaguely C-like surface notation. But even I would rather write a for-loop than the equivalent recursion. That's why I code in Python now instead of trying to rescue LISP from its desuetitude. So while it is *theoretically* true that ?: adds nothing, it is *practically* true that it enables a large class of idioms that can't otherwise be comfortably expressed. That matters. Now, you can argue that the complexity ?: adds to language is not paid for by the additional convenience; I disagree, but that's at least a defensible argument. But simply saying it "adds nothing to the language" is a red herring -- neither do many of the other base language features. Why, for example, do we have more than one kind of loop construct? Unecessary. Wasteful. Clearly either "for" or "while" must go. As an exercise, try editing your complaint so that it refers to "for" everywhere it now refers to ?:. Contemplate the edited version until you achieve enlightenment ;-). -- Eric S. Raymond The same applies for other kinds of long-lasting low-level pain. [...] The body's response to being jabbed, pierced, and cut is to produce endorphins. [...] So here's my programme for breaking that cycle of dependency on Windows: get left arm tattooed with dragon motif, buy a crate of Jamaican Hot! Pepper Sauce, get nipples pierced. With any luck that will produce enough endorphins to make Windows completely redundant, and I can then upgrade to Linux and get on with things. -- Pieter Hintjens From ping at lfw.org Mon Jan 31 02:29:43 2000 From: ping at lfw.org (Ka-Ping Yee) Date: Sun, 30 Jan 2000 19:29:43 -0600 (EST) Subject: [Python-Dev] Adding C ternary select (a?b:c) to Python? In-Reply-To: <000301bf6b79$4f0c8a60$482d153f@tim> Message-ID: On Sun, 30 Jan 2000, Tim Peters wrote: > If this goes in (I'm not deadly opposed, just more opposed than in favor), > I'd like to see "else" used instead of the colon (cond "?" true "else" > false). The question mark is reasonably mnemonic, but a colon makes no > sense here. I agree with that sentiment (along the lines of the philosophy that chose "and" over "&&"), and it seems to me that it makes the most sense to use words for both: a = x > 0 then x else -x I don't have the time to do it right this second, but i suggest that a scan through a decent chunk of Python would be useful to find out how often this construct (in its "and"/"or" incarnation) actually gets used. I promise to give it a try as soon as i get my notebook battery charged up again. -- ?!ng From tim_one at email.msn.com Mon Jan 31 03:41:59 2000 From: tim_one at email.msn.com (Tim Peters) Date: Sun, 30 Jan 2000 21:41:59 -0500 Subject: [Python-Dev] Adding C ternary select (a?b:c) to Python? In-Reply-To: <20000130195406.A25682@trump.amber.org> Message-ID: <000201bf6b94$bfabc360$ee2d153f@tim> [Christopher Petrilli] > ... > Python is not a language that has been optimized for "minimal > typing", it's much more verbose than most languages, and so that > argument shouldn't be applied. Concise expression of common concepts is a Good Thing, though, and there's nothing inherently evil about wanting one of two outcomes . My impression is that the people historically most in favor of ?: ("or something like it") are also the ones most strongly in favor of embedded assignment ("or something like it"), and I can't *dismiss* either gripe. The Python while 1: x = something_or_other() if not x: break consume(x) idiom is truly grating at first -- more so than the multi-line ?: alternatives, in my eyes. > Perhaps it's for optimization? That was I believe the original > argument made for it in K&R, in that optimizers in that day were rather > antiquated, wheras today, I believe that any C compiler would get it > right if it were expressed in its full form. (Timbot?) Indeed, a couple weeks ago we tracked down a "mysterious slowdown" of our core speech recognizer to a particular compiler failing to optimize *unless* we changed a ?: into a long winded if/else! There's really nothing you can say about "any C compiler" -- optimization is much more a black art than anyone in that business will admit to in public <0.9 wink>. C was definitely designed with "by hand" optimization in mind, and, ironically, it's those features (particularly pointer aliasing) that make it harder for compilers to optimize than is, say, Fortran. But regardless of origin, ?: stands or falls on its other merits now. Python's own implementation uses it often enough, and to good effect. So it can't be that Guido hates the idea . It's just hard to love the syntax. > So, it comes down to a few questions for me: > > Does it solve a new problem? No > Is it pythonic? No > Does it make it faster? No Would a nice syntax allow clearer expression of some common computations? Probably yes. That's the same basis on which, e.g., list.pop and list.extend and dict.get and 3-argument getattr and ... were adopted. "Faster" applied to those too, but nobody pushed for 'em on that basis. Clearer! That's what really matters. It's the same argument for list comprehensions too. > ... > Sorry if I pushed someone's buton, but... I saw a lot of hints at making > Python MUCH more complex, which is counter to why I changed and dropped > many other languags. A good antitode to feature panic is reviewing Misc/HISTORY: Guido's willingness to entertain suggestions far exceeds his willingness to adopt them . it-would-be-different-if-features-were-just-as-easy-to- take-out-ly y'rs - tim From tismer at tismer.com Mon Jan 31 12:46:50 2000 From: tismer at tismer.com (Christian Tismer) Date: Mon, 31 Jan 2000 12:46:50 +0100 Subject: [Python-Dev] Adding C ternary select (a?b:c) to Python? References: Message-ID: <3895762A.C1706E8@tismer.com> Ka-Ping Yee wrote: > > On Sun, 30 Jan 2000, Tim Peters wrote: > > If this goes in (I'm not deadly opposed, just more opposed than in favor), > > I'd like to see "else" used instead of the colon (cond "?" true "else" > > false). The question mark is reasonably mnemonic, but a colon makes no > > sense here. > > I agree with that sentiment (along the lines of the philosophy that > chose "and" over "&&"), and it seems to me that it makes the most sense > to use words for both: > > a = x > 0 then x else -x I would favorise this as well instead of using ?: . Maybe it would make sense to be even more verbose and use an "if" as well? a = if x > 0 then x else -x sign = lambda x: if x > 0 then 1 elif x then -1 else 0 ciao - chris -- Christian Tismer :^) Applied Biometrics GmbH : Have a break! Take a ride on Python's D?ppelstr. 31 : *Starship* http://starship.python.net 12163 Berlin : PGP key -> http://wwwkeys.pgp.net PGP Fingerprint E182 71C7 1A9D 66E9 9D15 D3CC D4D7 93E2 1FAE F6DF we're tired of banana software - shipped green, ripens at home From gward at cnri.reston.va.us Mon Jan 31 15:15:08 2000 From: gward at cnri.reston.va.us (Greg Ward) Date: Mon, 31 Jan 2000 09:15:08 -0500 Subject: [Python-Dev] Adding C ternary select (a?b:c) to Python? In-Reply-To: ; from ping@lfw.org on Sun, Jan 30, 2000 at 07:29:43PM -0600 References: <000301bf6b79$4f0c8a60$482d153f@tim> Message-ID: <20000131091507.A17073@cnri.reston.va.us> On 30 January 2000, Ka-Ping Yee said: > On Sun, 30 Jan 2000, Tim Peters wrote: > > If this goes in (I'm not deadly opposed, just more opposed than in favor), > > I'd like to see "else" used instead of the colon (cond "?" true "else" > > false). The question mark is reasonably mnemonic, but a colon makes no > > sense here. > > I agree with that sentiment (along the lines of the philosophy that > chose "and" over "&&"), and it seems to me that it makes the most sense > to use words for both: > > a = x > 0 then x else -x Yeah, I agree with Tim: it's a handy feature and I frequently wish I could do simple conditional assignment without resorting to a full-blown if/else. (I think I stumbled across "a and b or c" myself -- either that or it was suggested by *Learning Python*, but lay dormant in my subconscious for several months -- which means that I missed the "b must always be true" subtlety until it bit me. Ouch. I avoid that idiom now.) BUT the C line-noise syntax is not appropriate. It's fine in C, and it's eminently appropriate in Perl -- both languages designed to minimise wear-and-tear of programmers' keyboards. But keyboards are cheap nowadays, so perhaps we can be a bit more profligate with them. I find Ping's proposed syntax intriguing. Personally, I've always been partial to the x = if a then b else c syntax, even though I don't think I've ever used a language that includes it. (Oh wait, the toy ALGOL-knockoff that we used in Intro to Compilers had it, so I *have* written a parser and simplistic code generator for a language that includes it. Perhaps that's why I like it...) But either of these -- ie. elevate "then" to keywordhood, with or without "if", and no colons to be seen -- smell like they would play havoc with Python's grammar. And they turn a statement keyword "if" into an expression keyword. Not being at all familiar with Python's parser, I should just shut up now, but it feels tricky. And of course, any proposed syntax changes nowadays have to take JPython into account. Greg From guido at CNRI.Reston.VA.US Mon Jan 31 15:36:52 2000 From: guido at CNRI.Reston.VA.US (Guido van Rossum) Date: Mon, 31 Jan 2000 09:36:52 -0500 Subject: [Python-Dev] Adding C ternary select (a?b:c) to Python? In-Reply-To: Your message of "Mon, 31 Jan 2000 09:15:08 EST." <20000131091507.A17073@cnri.reston.va.us> References: <000301bf6b79$4f0c8a60$482d153f@tim> <20000131091507.A17073@cnri.reston.va.us> Message-ID: <200001311436.JAA15213@eric.cnri.reston.va.us> > I find Ping's proposed syntax intriguing. Personally, I've always been > partial to the > > x = if a then b else c > > syntax, even though I don't think I've ever used a language that > includes it. (Oh wait, the toy ALGOL-knockoff that we used in Intro to > Compilers had it, so I *have* written a parser and simplistic code > generator for a language that includes it. Perhaps that's why I like > it...) Yes, this was in original Algol 60 and, by magic of a completely different kind, again in Algol 68 (which was a completely different language, and the Mount Everest of languages). > But either of these -- ie. elevate "then" to keywordhood, with or > without "if", and no colons to be seen -- smell like they would play > havoc with Python's grammar. And they turn a statement keyword "if" > into an expression keyword. Not being at all familiar with Python's > parser, I should just shut up now, but it feels tricky. The solution can be the same as what Algol used: 'if' outside parentheses is a statement, and inside parentheses is an expression. It's a bit of a grammar rearrangement, but totally unambiguous. However, the added keyword means it won't be in 1.6. The lively discussion means that Eric's patch will have a hard time getting in too... --Guido van Rossum (home page: http://www.python.org/~guido/) From jim at digicool.com Mon Jan 31 16:04:45 2000 From: jim at digicool.com (Jim Fulton) Date: Mon, 31 Jan 2000 10:04:45 -0500 Subject: [Python-Dev] Adding C ternary select (a?b:c) to Python? References: <200001301332.IAA12252@eric.cnri.reston.va.us> <000301bf6b79$4f0c8a60$482d153f@tim> <20000130184317.A12833@thyrsus.com> <005c01bf6b7f$7a3a8f60$0100000a@ski.org> <20000130195406.A25682@trump.amber.org> Message-ID: <3895A48D.F69B3DFA@digicool.com> Christopher Petrilli wrote: > > The question comes from what "problem" you're trying to solve. It would allow you to incorporate logic into expressions. There are contexts where only expressions are allowed, such as: - lambdas - DTML expr attributes in which I'd very much like to incorporate tests. > The ?: syntax > does not introduce any new "functionality" to the language, Yes it does. > nor does it > make it capable of solving problems or requirements that it can not do > at the current time. Ditto. > The second qustion I'd ask is, who is this aimed at? It's certainly not > aimed at first-time programmers, as I know from experience that the ?: > is one of the hardest things to teach people in C (after pointers), Hm. I can't agree. Smalltalk, came out of an essentially CP4E effort two decades ago at Xerox PARC. Smalltalk *only* had conditional expressions. The message: [condition] ifTrue: [do something ...] ifFalse: [do something else ...] is an expression in Smalltalk. > and > often I leave it out of training when I did it. It's simply a "shorthand" > not a new functionality. No, it allows testing in expressions. > If its aimed at experienced programmers, I'd > argue that it's at best "non-pythonic" and at worst a hack, taken from > a language in which it exposes the "macro assembler" approach. I don't agree. > Python is not a language that has been optimized for "minimal typing", That's not the issue. > it's > much more verbose than most languages, and so that argument shouldn' be > applied. Perhaps it's for optimization? That was I believe the original > argument made for it in K&R, in that optimizers in that day were rather > antiquated, wheras today, I believe that any C compiler would get it > right if it were expressed in its full form. (Timbot?) > > So, it comes down to a few questions for me: > > Does it solve a new problem? No Yes. > Is it pythonic? No Pythonicity is relative. > Does it make it faster? No Who cares? Jim -- Jim Fulton mailto:jim at digicool.com Python Powered! Technical Director (888) 344-4332 http://www.python.org Digital Creations http://www.digicool.com http://www.zope.org Under US Code Title 47, Sec.227(b)(1)(C), Sec.227(a)(2)(B) This email address may not be added to any commercial mail list with out my permission. Violation of my privacy with advertising or SPAM will result in a suit for a MINIMUM of $500 damages/incident, $1500 for repeats. From tismer at tismer.com Mon Jan 31 16:59:15 2000 From: tismer at tismer.com (Christian Tismer) Date: Mon, 31 Jan 2000 16:59:15 +0100 Subject: [Python-Dev] Riskless deletion of nested structures Message-ID: <3895B153.3D2E763D@tismer.com> Howdy, Please review! While implementing Stackless Python, a new problem arose: Nested structures like frame chains and tracebacks can now easily grow somuch that they cause a stack overflow on deallocation. To protect lists, tuples, frames, dicts and tracebacks against this, I wrote a stackless deallocator. At the moment, everything is done in trashcan.c . This gives a slight performance loss of 5% for pystone, most probably due to the double indirection and non-local code reference. It is yet a hack, since I'm grabbing the tp->dealloc pointers of these types and replace them by safe versions. This just in order to try out things quickly. Later I will change this and incorporate the stack checks into the affected modules, after I got some feedback on this. This patch applies to Stackless and standard Python as well: Deallocation of deeply nested structures will never again cause a stack overflow. Installation for the intermediate version: Insert a line _Py_trashcan_install(); at the end of Py_Initialize in pythonrun.c Please try it and check my code wether there is a better solution. cheers - chris -- Christian Tismer :^) Applied Biometrics GmbH : Have a break! Take a ride on Python's D?ppelstr. 31 : *Starship* http://starship.python.net 12163 Berlin : PGP key -> http://wwwkeys.pgp.net PGP Fingerprint E182 71C7 1A9D 66E9 9D15 D3CC D4D7 93E2 1FAE F6DF we're tired of banana software - shipped green, ripens at home -------------- next part -------------- A non-text attachment was scrubbed... Name: trashcan.c Type: application/x-unknown-content-type-cfile Size: 2209 bytes Desc: not available URL: -------------- next part -------------- A non-text attachment was scrubbed... Name: trashcan.h Type: application/x-unknown-content-type-hfile Size: 246 bytes Desc: not available URL: From fdrake at acm.org Mon Jan 31 18:08:11 2000 From: fdrake at acm.org (Fred L. Drake, Jr.) Date: Mon, 31 Jan 2000 12:08:11 -0500 (EST) Subject: [Python-Dev] Adding C ternary select (a?b:c) to Python? In-Reply-To: References: <000301bf6b79$4f0c8a60$482d153f@tim> Message-ID: <14485.49531.600935.643400@weyr.cnri.reston.va.us> Ka-Ping Yee writes: > a scan through a decent chunk of Python would be useful to find out how > often this construct (in its "and"/"or" incarnation) actually gets used. I'm not sure what the survey provides other than a lower bound. I think most Python programmers who want the ?: functionality avoid the and/or approach because of the ugliness. I know I do. But I'd really like to have the functionality if the syntax is reasonable! I could live with something like "if cond then true else false"; the leading "if" is visually important; without it, you have to scan over the test expression to find the "then", and that makes it harder to read. -Fred -- Fred L. Drake, Jr. Corporation for National Research Initiatives From bwarsaw at cnri.reston.va.us Mon Jan 31 18:33:25 2000 From: bwarsaw at cnri.reston.va.us (Barry A. Warsaw) Date: Mon, 31 Jan 2000 12:33:25 -0500 (EST) Subject: [Python-Dev] Adding C ternary select (a?b:c) to Python? References: <000301bf6b79$4f0c8a60$482d153f@tim> <14485.49531.600935.643400@weyr.cnri.reston.va.us> Message-ID: <14485.51045.97448.830202@anthem.cnri.reston.va.us> Put me in the camp of "yeah, occasionally I wish I had it, but I can always hack around it, and the C syntax just blows". I'm sure if it's wedgeable into CPython it would also be in JPython, but I dislike ?: syntax enough to vote strongly against it for CPython 1.6. A Forth-ish syntax might be more acceptable x = y > z if y else z but come on! You'll give ordinarily dandruff-free Python programmers plenty of other reasons to scratch their heads with this one. head-and-shoulders-above-the-rest-ly y'rs, -Barry From gvwilson at nevex.com Mon Jan 31 18:44:53 2000 From: gvwilson at nevex.com (gvwilson at nevex.com) Date: Mon, 31 Jan 2000 12:44:53 -0500 (EST) Subject: [Python-Dev] Adding C ternary select (a?b:c) to Python? In-Reply-To: <3895A48D.F69B3DFA@digicool.com> Message-ID: > It (?:) would allow you to incorporate logic into expressions. > There are contexts where only expressions are allowed, such as: > - lambdas > - DTML expr attributes > in which I'd very much like to incorporate tests. Don't know much about DTML, but believe that being able to put conditionals in lambdas would make the latter much more useful. > > The ?: syntax > > does not introduce any new "functionality" to the language, > Yes it does. Is anything possible with ?: that's impossible without? No --- Python is Turing-equivalent before and after the change. Is anything easier with ?: --- yes. Does this make up for the added complexity? Dunno (see below). > > The second qustion I'd ask is, who is this aimed at? It's certainly not > > aimed at first-time programmers, as I know from experience that the ?: > > is one of the hardest things to teach people in C (after pointers), > Hm. I can't agree. Strongly agree with the first author --- IME, ?: is very hard to teach. Greg From klm at digicool.com Mon Jan 31 18:58:07 2000 From: klm at digicool.com (Ken Manheimer) Date: Mon, 31 Jan 2000 12:58:07 -0500 (EST) Subject: [Python-Dev] Adding C ternary select (a?b:c) to Python? In-Reply-To: <14485.49531.600935.643400@weyr.cnri.reston.va.us> Message-ID: On Mon, 31 Jan 2000, Fred L. Drake, Jr. wrote: > Ka-Ping Yee writes: > > a scan through a decent chunk of Python would be useful to find out how > > often this construct (in its "and"/"or" incarnation) actually gets used. > > I'm not sure what the survey provides other than a lower bound. I > think most Python programmers who want the ?: functionality avoid the > and/or approach because of the ugliness. I know I do. Good point. Just because the workaround is bad doesn't mean the thing being worked-around is unimportant... I should weigh in to say that i have really really wanted, in particular, the ability to have a condition on the right hand side of an assignement. IIR, on some occasions it seemed less clear to have to use separate statements for what was essentially a single assignment that just, eg, differed by a single term. I wanted (want) some reasonable way to express the condition in an expression. I can see how this compactness could lead to regex-style convolution of expressions, but that could be avoided by providing a not-too-terse syntax. (I should admit that may have succumbed to the (a and (b,) or (c,))[0] grotesquerie at some point! Not sure. Wish i could recall what might have justified succumbing - the mere fact that i may have, without compelling justification, might-should disqualify my judgement on the matter, ay? Hey, maybe i didn't, i was just imagining it - now am i not a sterling judge?-) Ken klm at digicool.com From tismer at tismer.com Mon Jan 31 20:55:36 2000 From: tismer at tismer.com (Christian Tismer) Date: Mon, 31 Jan 2000 20:55:36 +0100 Subject: [Python-Dev] Ann: Stackless Python 1.02 Message-ID: <3895E8B8.995CA560@tismer.com> Stackless Python is a Python without C stack usage. It allows for all kinds of non-local control flow. For info see http://www.tismer.com/research/stackless/ Update for Stackless Python V. 1.02: - passes all standard tests - should work with Zope now (try...finally was incorrect) - has a smart object destructor for really deeply nested stuff The "5 percent speedup" is no longer there currently, since the smart object destructor needs to be optimized into the objects. It is not done in this test phase but will come. Please visit the Stackless Python homepage at http://www.tismer.com/research/stackless/ Fact sheet, links to documentation, source and binaries can be found there. cheers - chris

Stackless Python 1.02 + Continuations 0.6 - a version of Python 1.5.2 that does not need space on the C stack, and first-class callable continuation objects for Python. (31-Jan-2000) Christian Tismer Mission Impossible 5oftware Team From tim_one at email.msn.com Sun Jan 2 06:52:34 2000 From: tim_one at email.msn.com (Tim Peters) Date: Sun, 2 Jan 2000 00:52:34 -0500 Subject: [Python-Dev] Re: [Distutils] Questions about distutils strategy In-Reply-To: <199912091617.LAA05742@eric.cnri.reston.va.us> Message-ID: <000401bf54e5$91587280$1f2d153f@tim> Briefly backtracking to an old thread: [Guido] > ... > The problem lies in which key is used. All versions of > Python 1.5.x (1.5, 1.5.1, 1.5.2) use the same key! This > is a main cause of trouble, because it means that different > versions cannot peacefully live together even if the user > installs them into different directories -- they will all > use the registry keys of the last version installed. This, > in turn, means that someone who writes a Python application > that has a dependency on a particular Python version (and > which application worth distributing doesn't :-) cannot > trust that if a Python installation is present, it is the > right one. But they also cannot simply bundle the standard > installer for the correct Python version with their program, > because its installation would overwrite an existing Python > application, thus breaking some *other* Python apps that > the user might already have installed. Right, that's one class of intractable problem under Windows. *Inside* my workplace, another kind of problem is caused when people try to make a Python app available over the Windows network. They stick the Python they want and its libraries out on the network, with python.exe in the same directory as the app. Now some people have highly customized Python setups, and the network Python picks up "the wrong" site.py etc. That sucks, and there appears no sane way to stop it. Telling internal app distributors they need to invent a unique registry key and fiddle their python.exe's resources is a non-starter. Ditto telling people with highly customized Pythons "don't do that". Ditto telling anyone they have to run any sort of installation script just to use a network app (sometimes they don't even know they're running it! e.g., when it's a subsystem invoked by another app). So while everyone is thinking about the hardest possible scenarios, please give a thought to the dirt simple one too <0.5 wink>: an app distributor who knows exactly what they're doing, and for whom *any* magical inference is simply a barrier to overcome. The latter can be satisfied by any number of means, from an envar that says "please don't try to be helpful, *this* is the directory you look in, and if you don't find stuff there give up" to a cmdline switch that says the same. Nothing Windows-specific there -- any OS with an envar or a cmdline will play along . > ... > I thought a bit about how VB solves this. I think that when > you wrap up a VB app in, all the support code (mostly a big > DLL) is wrapped with it. When the user runs the installer, > the DLL is installed (probably in the WINDOWS directory). If > a user installs several VB apps built with the same VB > version, they all attempt to install the exact same DLL; of > course the installers notice this and optimize it away, keeping > a reference count. This is the way most *MS* DLLs work; stuff like the C runtime libraries and MS database drivers work exactly the same way. It's rare for pkgs other than MS's to attempt to use this mechanism, though (the reason is given below). > (Ignoring for now the fact that those reference counts don't > always work!) ? They work very well, in my experience. Where they fail is when installers & uninstallers break the rules. MS publishes the list of MS DLLs that are to be treated this way: an installer "must" use refcounting on the DLLs in the list. Alas, some (especially older) installation pkgs don't. Then the refcounts get screwed up. That's what makes the mechanism brittle: "the system" doesn't enforce it, it relies on universal & intelligent cooperation. It's very likely that someone distributing a Python app will neglect (out of ignorance) to bump the refcount on their Python components, so the refcount will be artificially low, and a later uninstall of some unrelated pkg that *did* follow the rules will merrily delete Python. Gordon and I will repeat this until it sinks in : almost everyone with a successful Windows product ships the non-MS DLLs they rely on and copies them into their own app directory. It's simple and it works; alternatives are complicated and don't work. Many even ship & copy MS DLLs (e.g., Scriptics copies its own msvcrt.dll (the MS C runtime) into Tcl's directories). Worrying about space consumed by redundant Python components is a bad case of premature optimization <0.3 wink>. > ... > How can we do something similar for Python? Seriously, short of getting MS to distribute Python and put the Python DLLs on The List of refcounted resources, we should pursue this line reluctantly if at all. MS may have a better scheme in the future, but for now better safe than sorry. a-couple-mb-on-a-modern-pc-isn't-worth-the-time-it-took- to-read-this-ly y'rs - tim From gstein at lyra.org Mon Jan 3 03:53:24 2000 From: gstein at lyra.org (Greg Stein) Date: Sun, 2 Jan 2000 18:53:24 -0800 (PST) Subject: [Python-Dev] new imputil.py Message-ID: Happy New Year! I've attached a new imputil.py to this message. It isn't posted on my page yet, as I'd like some feedback before declaring this new version viable. In this imputil, there is an ImportManager class. It gets installed as the import hook, with the presumption that it is the only import hook (technically, it could chain, but I've disabled that for now). I think Python 1.6 should drop the __import__ builtin and move to something like sys.import_hook (to allow examination and change). Another alternative would be sys.get_import_hook() and sys.set_import_hook(). [ I don't think we would want a "set" that returned the old version as the only way to get the current hook function; we want to be able to easily find the ImportManager instance. ] The ImportManager knows how to scan sys.path when it needs to find a top-level module/package (e.g. given a.b.c, the "a" is the top-level; b.c falls "below" that). sys.path can contain strings which specify a filesystem directory, or it can contain Importer instances. The manager also records an ordered list of suffix/importer pairs. The add_suffix() method is used to append new suffixes, but clients can also access the .suffixes attribute for fine-grained manipulation/ordering. There is a new importer called _FilesystemImporter which understands how to look into a directory for Python modules. It borrows/refers to the ImportManager's .suffixes attribute, using that to find modules in a directory. This is also the Importer that gets associated with each filesystem-based module. The importers used for suffix-based importing are derived from SuffixImporter. While a function could be used here, future changes will be easier if we presume class instances. The new imputil works fine (use _test_revamp() to switch to the new import mechanism). Importer subclasses using the old imputil should continue to work, although I am deprecating the 2-tuple return value for get_code(). get_code() should return None or the 3-tuple form now. I think I still have a bit more work to do, to enable something like "import a.b.c" where a.zip is an archive on the path and "b.c" resides in the archive. Note: it *is* possible to do sys.path.append(ZipImporter(filename)) and have "a.b.c" in the Zip file. It would simply be nicer to be able to drop arbitrary .zip files onto the path and use their basename as the top-level name of a package. Anyhow: I haven't looked at this scenario yet to find what the new system is missing (if anything). As always: feedback is more than appreciated! Especially from people using imputil today. Did I break anything? Does the new scheme still feel right to you? etc. Cheers, -g p.s. I'd also like to remove PackageArchiveImporter and PackageArchive. They don't seem to add any real value. I might move DirectoryImporter and PathImporter to an "examples" file, too. -- Greg Stein, http://www.lyra.org/ -------------- next part -------------- # # imputil.py # # Written by Greg Stein. Public Domain. # No Copyright, no Rights Reserved, and no Warranties. # # Utilities to help out with custom import mechanisms. # # Additional modifications were contribed by Marc-Andre Lemburg and # Gordon McMillan. # # This module is maintained by Greg and is available at: # http://www.lyra.org/greg/python/imputil.py # # Since this isn't in the Python distribution yet, we'll use the CVS ID # for tracking: # $Id: imputil.py,v 1.9 2000/01/03 02:38:29 gstein Exp $ # # note: avoid importing non-builtin modules import imp import sys import strop import __builtin__ # for the DirectoryImporter import struct import marshal _StringType = type('') _ModuleType = type(sys) class ImportManager: "Manage the import process." def install(self): ### warning: Python 1.6 will have a different hook mechanism; this ### code will need to change. self.__chain_import = __builtin__.__import__ self.__chain_reload = __builtin__.reload __builtin__.__import__ = self._import_hook ### fix this #__builtin__.reload = None #__builtin__.reload = self._reload_hook def add_suffix(self, suffix, importer): assert isinstance(importer, SuffixImporter) self.suffixes.append((suffix, importer)) ###################################################################### # # PRIVATE METHODS # def __init__(self): # we're definitely going to be importing something in the future, # so let's just load the OS-related facilities. if not _os_stat: _os_bootstrap() # Initialize the set of suffixes that we recognize and import. # The default will import dynamic-load modules first, followed by # .py files (or a .py file's cached bytecode) self.suffixes = [ ] for desc in imp.get_suffixes(): if desc[2] == imp.C_EXTENSION: self.suffixes.append((desc[0], DynLoadSuffixImporter(desc))) self.suffixes.append(('.py', PySuffixImporter())) # This is the importer that we use for grabbing stuff from the # filesystem. It defines one more method (import_from_dir) for our use. self.fs_imp = _FilesystemImporter(self.suffixes) def _import_hook(self, fqname, globals=None, locals=None, fromlist=None): """Python calls this hook to locate and import a module.""" parts = strop.split(fqname, '.') # determine the context of this import parent = self._determine_import_context(globals) # if there is a parent, then its importer should manage this import if parent: module = parent.__importer__._do_import(parent, parts, fromlist) if module: return module # has the top module already been imported? try: top_module = sys.modules[parts[0]] except KeyError: # look for the topmost module top_module = self._import_top_module(parts[0]) if not top_module: # the topmost module wasn't found at all. raise ImportError, 'No module named ' + fqname return self.__chain_import(name, globals, locals, fromlist) # fast-path simple imports if len(parts) == 1: if not fromlist: return top_module if not top_module.__dict__.get('__ispkg__'): # __ispkg__ isn't defined (the module was not imported by us), or # it is zero. # # In the former case, there is no way that we could import # sub-modules that occur in the fromlist (but we can't raise an # error because it may just be names) because we don't know how # to deal with packages that were imported by other systems. # # In the latter case (__ispkg__ == 0), there can't be any sub- # modules present, so we can just return. # # In both cases, since len(parts) == 1, the top_module is also # the "bottom" which is the defined return when a fromlist exists. return top_module importer = top_module.__dict__.get('__importer__') if importer: return importer._finish_import(top_module, parts[1:], fromlist) # If the importer does not exist, then we have to bail. A missing importer # means that something else imported the module, and we have no knowledge # of how to get sub-modules out of the thing. raise ImportError, 'No module named ' + fqname return self.__chain_import(name, globals, locals, fromlist) def _determine_import_context(self, globals): """Returns the context in which a module should be imported. The context could be a loaded (package) module and the imported module will be looked for within that package. The context could also be None, meaning there is no context -- the module should be looked for as a "top-level" module. """ if not globals or not globals.get('__importer__'): # globals does not refer to one of our modules or packages. That # implies there is no relative import context (as far as we are # concerned), and it should just pick it off the standard path. return None # The globals refer to a module or package of ours. It will define # the context of the new import. Get the module/package fqname. parent_fqname = globals['__name__'] # if a package is performing the import, then return itself (imports # refer to pkg contents) if globals['__ispkg__']: parent = sys.modules[parent_fqname] assert globals is parent.__dict__ return parent i = strop.rfind(parent_fqname, '.') # a module outside of a package has no particular import context if i == -1: return None # if a module in a package is performing the import, then return the # package (imports refer to siblings) parent_fqname = parent_fqname[:i] parent = sys.modules[parent_fqname] assert parent.__name__ == parent_fqname return parent def _import_top_module(self, name): # scan sys.path looking for a location in the filesystem that contains # the module, or an Importer object that can import the module. for item in sys.path: if type(item) == _StringType: module = self.fs_imp.import_from_dir(item, name) else: module = item.import_top(name) if module: return module return None def _reload_hook(self, module): "Python calls this hook to reload a module." # reloading of a module may or may not be possible (depending on the # importer), but at least we can validate that it's ours to reload importer = module.__dict__.get('__importer__') if not importer: return self.__chain_reload(module) # okay. it is using the imputil system, and we must delegate it, but # we don't know what to do (yet) ### we should blast the module dict and do another get_code(). need to ### flesh this out and add proper docco... raise SystemError, "reload not yet implemented" class Importer: "Base class for replacing standard import functions." def install(self): sys.path.insert(0, self) def import_top(self, name): "Import a top-level module." return self._import_one(None, name, name) ###################################################################### # # PRIVATE METHODS # def _finish_import(self, top, parts, fromlist): # if "a.b.c" was provided, then load the ".b.c" portion down from # below the top-level module. bottom = self._load_tail(top, parts) # if the form is "import a.b.c", then return "a" if not fromlist: # no fromlist: return the top of the import tree return top # the top module was imported by self. # # this means that the bottom module was also imported by self (just # now, or in the past and we fetched it from sys.modules). # # since we imported/handled the bottom module, this means that we can # also handle its fromlist (and reliably use __ispkg__). # if the bottom node is a package, then (potentially) import some modules. # # note: if it is not a package, then "fromlist" refers to names in # the bottom module rather than modules. # note: for a mix of names and modules in the fromlist, we will # import all modules and insert those into the namespace of # the package module. Python will pick up all fromlist names # from the bottom (package) module; some will be modules that # we imported and stored in the namespace, others are expected # to be present already. if bottom.__ispkg__: self._import_fromlist(bottom, fromlist) # if the form is "from a.b import c, d" then return "b" return bottom def _import_one(self, parent, modname, fqname): "Import a single module." # has the module already been imported? try: return sys.modules[fqname] except KeyError: pass # load the module's code, or fetch the module itself result = self.get_code(parent, modname, fqname) if result is None: return None ### backwards-compat if len(result) == 2: result = result + ({},) module = self._process_result(result, fqname) # insert the module into its parent if parent: setattr(parent, modname, module) return module def _process_result(self, (ispkg, code, values), fqname): # did get_code() return an actual module? (rather than a code object) is_module = type(code) is _ModuleType # use the returned module, or create a new one to exec code into if is_module: module = code else: module = imp.new_module(fqname) ### record packages a bit differently?? module.__importer__ = self module.__ispkg__ = ispkg # insert additional values into the module (before executing the code) module.__dict__.update(values) # the module is almost ready... make it visible sys.modules[fqname] = module # execute the code within the module's namespace if not is_module: exec code in module.__dict__ return module def _load_tail(self, m, parts): """Import the rest of the modules, down from the top-level module. Returns the last module in the dotted list of modules. """ for part in parts: fqname = "%s.%s" % (m.__name__, part) m = self._import_one(m, part, fqname) if not m: raise ImportError, "No module named " + fqname return m def _import_fromlist(self, package, fromlist): 'Import any sub-modules in the "from" list.' # if '*' is present in the fromlist, then look for the '__all__' variable # to find additional items (modules) to import. if '*' in fromlist: fromlist = list(fromlist) + list(package.__dict__.get('__all__', [])) for sub in fromlist: # if the name is already present, then don't try to import it (it # might not be a module!). if sub != '*' and not hasattr(package, sub): subname = "%s.%s" % (package.__name__, sub) submod = self._import_one(package, sub, subname) if not submod: raise ImportError, "cannot import name " + subname def _do_import(self, parent, parts, fromlist): """Attempt to import the module relative to parent. This method is used when the import context specifies that imported the parent module. """ top_name = parts[0] top_fqname = parent.__name__ + '.' + top_name top_module = self._import_one(parent, top_name, top_fqname) if not top_module: # this importer and parent could not find the module (relatively) return None return self._finish_import(top_module, parts[1:], fromlist) ###################################################################### # # METHODS TO OVERRIDE # def get_code(self, parent, modname, fqname): """Find and retrieve the code for the given module. parent specifies a parent module to define a context for importing. It may be None, indicating no particular context for the search. modname specifies a single module (not dotted) within the parent. fqname specifies the fully-qualified module name. This is a (potentially) dotted name from the "root" of the module namespace down to the modname. If there is no parent, then modname==fqname. This method should return None, or a 3-tuple. * If the module was not found, then None should be returned. * The first item of the 2- or 3-tuple should be the integer 0 or 1, specifying whether the module that was found is a package or not. * The second item is the code object for the module (it will be executed within the new module's namespace). This item can also be a fully-loaded module object (e.g. loaded from a shared lib). * The third item is a dictionary of name/value pairs that will be inserted into new module before the code object is executed. This is provided in case the module's code expects certain values (such as where the module was found). When the second item is a module object, then these names/values will be inserted *after* the module has been loaded/initialized. """ raise RuntimeError, "get_code not implemented" ###################################################################### # # Some handy stuff for the Importers # # byte-compiled file suffic character _suffix_char = __debug__ and 'c' or 'o' # byte-compiled file suffix _suffix = '.py' + _suffix_char # the C_EXTENSION suffixes _c_suffixes = filter(lambda x: x[2] == imp.C_EXTENSION, imp.get_suffixes()) def _compile(pathname, timestamp): """Compile (and cache) a Python source file. The file specified by is compiled to a code object and returned. Presuming the appropriate privileges exist, the bytecodes will be saved back to the filesystem for future imports. The source file's modification timestamp must be provided as a Long value. """ codestring = open(pathname, 'r').read() if codestring and codestring[-1] != '\n': codestring = codestring + '\n' code = __builtin__.compile(codestring, pathname, 'exec') # try to cache the compiled code try: f = open(pathname + _suffix_char, 'wb') except IOError: pass else: f.write('\0\0\0\0') f.write(struct.pack(' ':': a = a + ':' return a + b else: raise ImportError, 'no os specific module found' if join is None: def join(a, b, sep=sep): if a == '': return b lastchar = a[-1:] if lastchar == '/' or lastchar == sep: return a + b return a + sep + b global _os_stat _os_stat = stat global _os_path_join _os_path_join = join def _os_path_isdir(pathname): "Local replacement for os.path.isdir()." try: s = _os_stat(pathname) except OSError: return None return (s[0] & 0170000) == 0040000 def _timestamp(pathname): "Return the file modification time as a Long." try: s = _os_stat(pathname) except OSError: return None return long(s[8]) def _fs_import(dir, modname, fqname): "Fetch a module from the filesystem." pathname = _os_path_join(dir, modname) if _os_path_isdir(pathname): values = { '__pkgdir__' : pathname, '__path__' : [ pathname ] } ispkg = 1 pathname = _os_path_join(pathname, '__init__') else: values = { } ispkg = 0 # look for dynload modules for desc in _c_suffixes: file = pathname + desc[0] try: fp = open(file, desc[1]) except IOError: pass else: module = imp.load_module(fqname, fp, file, desc) values['__file__'] = file return 0, module, values t_py = _timestamp(pathname + '.py') t_pyc = _timestamp(pathname + _suffix) if t_py is None and t_pyc is None: return None code = None if t_py is None or (t_pyc is not None and t_pyc >= t_py): file = pathname + _suffix f = open(file, 'rb') if f.read(4) == imp.get_magic(): t = struct.unpack('., where can be located using a subclass-specific mechanism and the is found in the archive using a subclass-specific mechanism. This class defines two hooks for subclasses: one to locate an archive (and possibly return some context for future subfile lookups), and one to locate subfiles. """ def get_code(self, parent, modname, fqname): if parent: # the Importer._finish_import logic ensures that we handle imports # under the top level module (package / archive). assert parent.__importer__ == self # if a parent "package" is provided, then we are importing a sub-file # from the archive. result = self.get_subfile(parent.__archive__, modname) if result is None: return None if type(result) == type(()): return (0,) + result return 0, result # no parent was provided, so the archive should exist somewhere on the # default "path". archive = self.get_archive(modname) if archive is None: return None return 1, "", {'__archive__':archive} def get_archive(self, modname): """Get an archive of modules. This method should locate an archive and return a value which can be used by get_subfile to load modules from it. The value may be a simple pathname, an open file, or a complex object that caches information for future imports. Return None if the archive was not found. """ raise RuntimeError, "get_archive not implemented" def get_subfile(self, archive, modname): """Get code from a subfile in the specified archive. Given the specified archive (as returned by get_archive()), locate and return a code object for the specified module name. A 2-tuple may be returned, consisting of a code object and a dict of name/values to place into the target module. Return None if the subfile was not found. """ raise RuntimeError, "get_subfile not implemented" class PackageArchive(PackageArchiveImporter): "PackageArchiveImporter subclass that refers to a specific archive." def __init__(self, modname, archive_pathname): self.__modname = modname self.__path = archive_pathname def get_archive(self, modname): if modname == self.__modname: return self.__path return None # get_subfile is passed the full pathname of the archive ###################################################################### # # Emulate the standard directory-based import mechanism # class DirectoryImporter(Importer): "Importer subclass to emulate the standard importer." def __init__(self, dir): self.dir = dir def get_code(self, parent, modname, fqname): if parent: dir = parent.__pkgdir__ else: dir = self.dir # defer the loading of OS-related facilities if not _os_stat: _os_bootstrap() # Return the module (and other info) if found in the specified # directory. Otherwise, return None. return _fs_import(dir, modname, fqname) def __repr__(self): return '<%s.%s for "%s" at 0x%x>' % (self.__class__.__module__, self.__class__.__name__, self.dir, id(self)) ###################################################################### # # Emulate the standard path-style import mechanism # class PathImporter(Importer): def __init__(self, path=sys.path): self.path = path # we're definitely going to be importing something in the future, # so let's just load the OS-related facilities. if not _os_stat: _os_bootstrap() def get_code(self, parent, modname, fqname): if parent: # we are looking for a module inside of a specific package return _fs_import(parent.__pkgdir__, modname, fqname) # scan sys.path, looking for the requested module for dir in self.path: result = _fs_import(dir, modname, fqname) if result: return result # not found return None ###################################################################### # # Emulate the import mechanism for builtin and frozen modules # class BuiltinImporter(Importer): def get_code(self, parent, modname, fqname): if parent: # these modules definitely do not occur within a package context return None # look for the module if imp.is_builtin(modname): type = imp.C_BUILTIN elif imp.is_frozen(modname): type = imp.PY_FROZEN else: # not found return None # got it. now load and return it. module = imp.load_module(modname, None, modname, ('', '', type)) return 0, module, { } ###################################################################### # # Internal importer used for importing from the filesystem # class _FilesystemImporter(Importer): def __init__(self, suffixes): # this list is shared with the ImportManager. self.suffixes = suffixes def import_from_dir(self, dir, fqname): result = self._import_pathname(_os_path_join(dir, fqname), fqname) if result: return self._process_result(result, fqname) return None def get_code(self, parent, modname, fqname): # This importer is never used with an empty parent. Its existence is # private to the ImportManager. The ImportManager uses the # import_from_dir() method to import top-level modules/packages. # This method is only used when we look for a module within a package. assert parent return self._import_pathname(_os_path_join(parent.__pkgdir__, modname), fqname) def _import_pathname(self, pathname, fqname): if _os_path_isdir(pathname): result = self._import_pathname(_os_path_join(pathname, '__init__'), fqname) if result: values = result[2] values['__pkgdir__'] = pathname values['__path__'] = [ pathname ] return 1, result[1], values return None for suffix, importer in self.suffixes: filename = pathname + suffix try: finfo = _os_stat(filename) except OSError: pass else: return importer.import_file(filename, finfo, fqname) return None ###################################################################### # # SUFFIX-BASED IMPORTERS # class SuffixImporter: def import_file(self, filename, finfo, fqname): raise RuntimeError class PySuffixImporter(SuffixImporter): def import_file(self, filename, finfo, fqname): file = filename[:-3] + _suffix t_py = long(finfo[8]) t_pyc = _timestamp(file) code = None if t_pyc is not None and t_pyc >= t_py: f = open(file, 'rb') if f.read(4) == imp.get_magic(): t = struct.unpack(' Message-ID: <387095F2.2FA64D8E@lemburg.com> Happy New Year :-) [new imputil.py] I tried the new module with the following code: import imputil,sys if sys.argv[1] != 'standard': print 'Installing imputil...', imputil.ImportManager().install() sys.path.insert(0, imputil.BuiltinImporter()) print 'done.' else: print 'Using builtin importer.' print print 'Importing standard stuff...', import string,re,os,sys print 'done.' print 'Importing mx Extensions...', from mx import DateTime,TextTools,ODBC,HTMLTools,UID,URL print 'done.' ### The new importer does load everything in the test set (top level modules, packages, extensions within packages) without problems on Linux. Some comments: ? Why is the sys.path.insert(0,imputil.BuiltinImporter()) needed in order to get b/w compatibility ? ? Why is there no __path__ aware code in imputil.py (this is definitely needed in order to make it a drop-in replacement) ? ? Performance is still 50% of the Python builtin importer -- a bummer if you ask me. More aggressive caching is definitely needed, perhaps even some recoding of methods in C. ? The old chaining code should be moved into a subclass of its own. ? The code should not import strop directly as this module will probably go away RSN. Use string methods instead. ? The design of the ImportManager has some minor flaws: the FS importer should be settable via class attributes, deinstallation should be possible, a query mechanism to find the importer used by a certain import would also be nice to be able to verify correct setup. ? py/pyc/pyo file piping hooks would be nice to allow imports of signed (and trusted) code and/or encrypted code (a mixin class for these filters would do the trick). ? Wish list: a distutils importer hooked to a list of standard package repositories, a module to file location mapper to speed up file system based imports, -- Marc-Andre Lemburg ______________________________________________________________________ Y2000: Happy New Century ! Business: http://www.lemburg.com/ Python Pages: http://www.lemburg.com/python/ From gstein at lyra.org Mon Jan 3 14:53:00 2000 From: gstein at lyra.org (Greg Stein) Date: Mon, 3 Jan 2000 05:53:00 -0800 (PST) Subject: [Python-Dev] new imputil.py In-Reply-To: <387095F2.2FA64D8E@lemburg.com> Message-ID: Excellent... thanx for the feedback! Comments: On Mon, 3 Jan 2000, M.-A. Lemburg wrote: >... > The new importer does load everything in the test set > (top level modules, packages, extensions within packages) > without problems on Linux. Great! > Some comments: > > ? Why is the sys.path.insert(0,imputil.BuiltinImporter()) > needed in order to get b/w compatibility ? Because I didn't want to build too much knowledge into the ImportManager. Heck, I think adding sys.path removed some of the design elegence; adding real knowledge of builtins... well, we'll just not talk about that. :-) We could certainly do it this way; let's see what Guido says. I'm not truly adverse to it, but I'd recommend against adding a knowledge of BuiltinImporter to the ImportManager. > ? Why is there no __path__ aware code in imputil.py (this is > definitely needed in order to make it a drop-in replacement) ? Because I don't like __path__ :-) I don't think it would be too hard to add, though. If Guido says we need __path__, then I'll add it. I do believe there was a poll a while back where he asked whether anybody truly used it. I don't remember the result and/or Guido's resolution of the matter. > ? Performance is still 50% of the Python builtin importer -- > a bummer if you ask me. More aggressive caching is definitely > needed, perhaps even some recoding of methods in C. I'm scared of caching and the possibility for false positives/negatives. But yes, it is still slower and could use some analysis and/or recoding *if* the speed is a problem. Slower imports does not necessarily mean they are "too slow." > ? The old chaining code should be moved into a subclass of > its own. Good thought. But really: I'd just rather torch it. This kind of depends on whether we can get away with saying the ImportManager is *the* gateway between the interpreter and Python-level import hooks. In other words, will ImportManager be the *only* Python code to ever be allowed to call sys.set_import_hook() ? If the ImportManager doesn't have to "play with other import hooks", then the chaining can be removed altogether. > ? The code should not import strop directly as this module > will probably go away RSN. Use string methods instead. Yah. But I'm running this against 1.5.2 :-) I might be able to do something where the string methods are used if available, and use the strop module if not. [ similar to the 'os' bootstrapping that is done ] Finn Bock emailed me to say that JPython does not have strop, but does have string methods. > ? The design of the ImportManager has some minor flaws: the > FS importer should be settable via class attributes, The class or the object itself? Putting a class in there would be nice, or possibly passing it to the constructor (with a suitable default). This is a good idea, though. Please clarify what you'd like to see, and I'll get it added. > deinstallation > should be possible, Maybe. This is somewhat dependent upon whether it must "play nice." Deinstallation would be quite easy if we move to a sys.get/set style of interface, and it wouldn't be an issue to do de-install code. > a query mechanism to find the importer > used by a certain import would also be nice to be able to > verify correct setup. module.__importer__ provides the importer that was used. This is defined behavior (the system relies on that being set to deal with packages properly). Is this sufficient, or were you looking for something else? module.__ispkg__ is also set to 0/1 accordingly. For backwards compat, __file__ and __path__ are also set. The __all__ attribute in an __init__.py file is used for "from package import *". > ? py/pyc/pyo file piping hooks would be nice to allow > imports of signed (and trusted) code and/or encrypted code > (a mixin class for these filters would do the trick). I'd happily accept a base SuffixImporter class for these "pipes". I don't believe that the ImportManager, Importer, or SuffixImporter base classes would need any changes, though. Note that I probably will rearrange the _fs_import() and friends, per Guido's suggestion to move them into a base class. That may be a step towards having "pipes" available. > ? Wish list: a distutils importer hooked to a list of standard > package repositories, a module to file location mapper to > speed up file system based imports, I'm not sure what the former would do. distutils is still a little nebulous to me right now. For a mapper, we can definitely have a custom Importer that knows where certain modules are found. However, I suspect you're looking for some kind of a cache, but there isn't a hook to say "I found at location" (which would be used to build the mapping). Suggestions on both of these would be most welcome! Cheers, -g -- Greg Stein, http://www.lyra.org/ From gvwilson at nevex.com Mon Jan 3 15:02:32 2000 From: gvwilson at nevex.com (gvwilson at nevex.com) Date: Mon, 3 Jan 2000 09:02:32 -0500 (EST) Subject: [Python-Dev] Software Carpentry: GUI Toolkit? Message-ID: Hi, folks. I'm putting together guidelines for submissions to the Software Carpentry design competition (www.software-carpentry.com), and would like to know what I should recommend as a Python GUI toolkit. As I understand it, the alternatives are: - Tkinter: the "standard" answer, but many people think it's showing its age, and it's an installation and update headaches because of its Tcl dependencies. - some other GUI toolkit: but there's no consensus on which one, and documentation is lacking. - CGI scripts (i.e. all interfaces are web pages): has the virtue of simplicity, but could also make some useful interfaces difficult to build (e.g. no drag and drop), and would require users to run a server, or at least get exec privileges, which can be an installation headache. If I've missed a good answer, or if there's somewhere else I should look for a solution, I'd be grateful for a pointer. Thanks, Greg From jim at interet.com Mon Jan 3 15:31:53 2000 From: jim at interet.com (James C. Ahlstrom) Date: Mon, 03 Jan 2000 09:31:53 -0500 Subject: [Python-Dev] new imputil.py References: Message-ID: <3870B2D9.31D0D350@interet.com> Greg Stein wrote: > I've attached a new imputil.py to this message. It isn't posted on my page I don't think you should be using "public domain" as a copyright because you should be protecting the code. Better to use "all rights transferred to CNRI pursuant to the Python contribution agreement", or just copyright it yourself for now. You didn't incorporate the ZipImporter in ftp://ftp.interet.com/pub/importer.py Is that because you want me to, or doesn't it work? JimA From gmcm at hypernet.com Mon Jan 3 15:38:11 2000 From: gmcm at hypernet.com (Gordon McMillan) Date: Mon, 3 Jan 2000 09:38:11 -0500 Subject: [Python-Dev] new imputil.py In-Reply-To: References: <387095F2.2FA64D8E@lemburg.com> Message-ID: <1265213088-25101227@hypernet.com> Greg Stein wrote: > On Mon, 3 Jan 2000, M.-A. Lemburg wrote: [big snip] > > ? Wish list: a distutils importer hooked to a list of standard > > package repositories, a module to file location mapper to speed > > up file system based imports, > For a mapper, we can definitely have a custom Importer that knows > where certain modules are found. However, I suspect you're > looking for some kind of a cache, but there isn't a hook to say > "I found at location" (which would be used to build > the mapping). > > Suggestions on both of these would be most welcome! Haven't played with the new one yet. But for awhile I've been considering a scheme where sys.path[0] has a cache of known binary extensions { logicalname: fullpath, ... } and sys.path[-1] is the brute force importer. For standalones, sys.path[0] could be hardcoded. For normal installations, sys.path[-1] could inform sys.path[0] when a .so / .dll / .pyd is found. So when a new one is installed, the first use will be expensive, but subsequent sessions would import it in 1 I/O. I'd also like to point out that archives *can* be used in a development situation. Obviously I wouldn't bother putting a module under current development into an archive. But if the source is still installed and you haven't mucked with the __file__ attribute when you put it in the archive, then tracebacks will show you what you need. IDLE doesn't know the difference. So for most developers, the standard library can be served from an archive with no effect (other than speed). - Gordon From gstein at lyra.org Mon Jan 3 15:57:35 2000 From: gstein at lyra.org (Greg Stein) Date: Mon, 3 Jan 2000 06:57:35 -0800 (PST) Subject: [Python-Dev] new imputil.py In-Reply-To: <3870B2D9.31D0D350@interet.com> Message-ID: On Mon, 3 Jan 2000, James C. Ahlstrom wrote: > Greg Stein wrote: > > I've attached a new imputil.py to this message. It isn't posted on my page > > I don't think you should be using "public domain" as a > copyright because you should be protecting the code. > Better to use "all rights transferred to CNRI pursuant > to the Python contribution agreement", or just copyright > it yourself for now. Public Domain means there are no copyrights on the code. Anybody can claim copyright to it. Anybody can start with my version, slap their name and license on it, and do as they wish. There isn't a way for anybody to "control" public domain software, so there is no need for protection. I like to use Public Domain for code that I want to see as broadly used as possible and/or for short things. There is also a lot that I just don't care what happens with it. If I don't have a vested interest in something, then PD is fine. I wrote imputil as a tool for myself. It isn't something that I feel a need to keep my name on it -- it works for me, it does what I want, it doesn't matter what others do it. It does matter than other people *can* do stuff with it, and PD gives them the most options. Shades of grey... hard to fully explain in an email... but that's the general sentiment. I've got a few things under other licenses, but PD seemed best for imputil. > You didn't incorporate the ZipImporter in > ftp://ftp.interet.com/pub/importer.py > Is that because you want me to, or doesn't it work? I had the redesign to do first. When that settles towards something that Guido is happy with (or he has decided to punt the design altogether), then I'll integrate the ZipImporter. Cheers, -g -- Greg Stein, http://www.lyra.org/ From fdrake at acm.org Mon Jan 3 21:05:22 2000 From: fdrake at acm.org (Fred L. Drake, Jr.) Date: Mon, 3 Jan 2000 15:05:22 -0500 (EST) Subject: [Python-Dev] new imputil.py In-Reply-To: <1265213088-25101227@hypernet.com> References: <387095F2.2FA64D8E@lemburg.com> <1265213088-25101227@hypernet.com> Message-ID: <14449.258.374018.919406@weyr.cnri.reston.va.us> Gordon McMillan writes: > I'd also like to point out that archives *can* be used in a > development situation. Obviously I wouldn't bother putting a > module under current development into an archive. But if the > source is still installed and you haven't mucked with the > __file__ attribute when you put it in the archive, then > tracebacks will show you what you need. IDLE doesn't know > the difference. So for most developers, the standard library > can be served from an archive with no effect (other than speed). I don't see why we can't just add the source to the archive as well; this would allow proper tracebacks even outside the development of the library. Not including sources would cleanly result in the same situation as we currently see when there's only a .pyc file. Am I missing something fundamental? -Fred -- Fred L. Drake, Jr. Corporation for National Research Initiatives From mal at lemburg.com Mon Jan 3 19:22:02 2000 From: mal at lemburg.com (M.-A. Lemburg) Date: Mon, 03 Jan 2000 19:22:02 +0100 Subject: [Python-Dev] Better text processing support in py2k? References: <000901bf53e1$eb4248c0$472d153f@tim> Message-ID: <3870E8CA.7294B813@lemburg.com> Tim Peters wrote: > > >> This is why I do complex string processing in Icon <0.9 wink>. > > [MAL] > > You can have all that extra magic via callable tag objects > > or callable matching functions. It's not exactly nice to > > write, but I'm sure that a meta-language could do the > > conversions for you. > > That wasn't my point: I do it in Icon because it *is* "exactly nice to > write", and doesn't require any yet-another meta-language. It's all > straightforward, in a way that separate schemes pasted together can never be > (simply because they *are* "separate schemes pasted together" ). > > The point of my Python examples wasn't that they could do something > mxTextTools can't do, but that they were *Python* examples: every variation > I mentioned (or that you're likely to think of) was easy to handle for any > Python programmer because the "control flow" and "data type" etc aspects > could be handled exactly the way they always are in *non* pattern-matching > Python code too, rather than recoded in pattern-scheme-specific different > ways (e.g., where I had a vanailla "if/break", you set up a special > exception to tickle the matching engine). > > I'm not attacking mxTextTools, so don't feel compelled to defend it -- Oh, I wasn't defending it -- I know that it is cryptic and sometimes a pain to use. But given that you don't have to invoke a C compiler to get a raw speed I find it a rather useful alternative to code fast utility functions which would otherwise have to be written in C. The other reason it exists is simply because I don't like the recursive style of regexps too much. mxTextTools is simple and straightforward. Backtracking is still possible, but not recommended. > people using regexps in those examples are dead in the water. mxTextTools > is very good at what it does; if we have a real disagreement, it's probably > that I'm less optimistic about the prospects for higher-level wrappers > (e.g., MikeF's SimpleParse is much slower than "a real" BNF parsing system > (ARBNFPS), in part because he isn't doing all the optimizations ARBNFPS > does, but also in part because ARBNFPS uses an underlying engine more > optimized to its specific task than mxTextTool's more-general engine *can* > be). So I don't see mxTextTools as being the answer to everything -- and if > you hadn't written it, you would agree with that on first glance . Oh, I'm sure it *is* the answer to all out problems ;-) ... def main(*dummy): ... from mx.TextTools import * tag("",((main, Skip + CallTag, 0),)) > > Anyway, I'll keep focussing on the speed aspect of mxTextTools; > > others can focus on abstractions, so that eventually everybody > > will be happy :-) > > You and I will be, anyway . Happy New Year :-) -- Marc-Andre Lemburg ______________________________________________________________________ Y2000: Happy New Century ! Business: http://www.lemburg.com/ Python Pages: http://www.lemburg.com/python/ From mal at lemburg.com Tue Jan 4 19:36:00 2000 From: mal at lemburg.com (M.-A. Lemburg) Date: Tue, 04 Jan 2000 19:36:00 +0100 Subject: [Python-Dev] new imputil.py References: Message-ID: <38723D90.D2AE1CA4@lemburg.com> Greg Stein wrote: > > Comments: > > On Mon, 3 Jan 2000, M.-A. Lemburg wrote: > >... > > The new importer does load everything in the test set > > (top level modules, packages, extensions within packages) > > without problems on Linux. > > Great! > > > Some comments: > > > > ? Why is the sys.path.insert(0,imputil.BuiltinImporter()) > > needed in order to get b/w compatibility ? > > Because I didn't want to build too much knowledge into the ImportManager. > Heck, I think adding sys.path removed some of the design elegence; adding > real knowledge of builtins... well, we'll just not talk about that. :-) > > We could certainly do it this way; let's see what Guido says. I'm not > truly adverse to it, but I'd recommend against adding a knowledge of > BuiltinImporter to the ImportManager. I was under the impression that the ImportManager should replace the current implementation. In that light it should of course provide all the needed techniques per default without the need to tweak sys.path. > > ? Why is there no __path__ aware code in imputil.py (this is > > definitely needed in order to make it a drop-in replacement) ? > > Because I don't like __path__ :-) I don't think it would be too hard to > add, though. > > If Guido says we need __path__, then I'll add it. I do believe there was a > poll a while back where he asked whether anybody truly used it. I don't > remember the result and/or Guido's resolution of the matter. AFAIK, JimF is using it in Zope. I will use it in the b/w compatibility package for the soon to be released mx Extensions packages (instead of using relative imports, BTW -- can't wait for those to happen). > > ? Performance is still 50% of the Python builtin importer -- > > a bummer if you ask me. More aggressive caching is definitely > > needed, perhaps even some recoding of methods in C. > > I'm scared of caching and the possibility for false positives/negatives. > > But yes, it is still slower and could use some analysis and/or recoding > *if* the speed is a problem. Slower imports does not necessarily mean they > are "too slow." There has been some moaning about the current Python startup speed, so I guess people already find the existing strategy too slow. Anyway, put the cache risks into the user's hands and have them decide whether or not to use them. The important thing is providing a standard approach to caching which all importers can use and hook into rather than having three or four separate cache implementations. > > ? The old chaining code should be moved into a subclass of > > its own. > > Good thought. But really: I'd just rather torch it. This kind of depends > on whether we can get away with saying the ImportManager is *the* gateway > between the interpreter and Python-level import hooks. In other words, > will ImportManager be the *only* Python code to ever be allowed to call > sys.set_import_hook() ? If the ImportManager doesn't have to "play with > other import hooks", then the chaining can be removed altogether. Hmm, nuking the chains might cause some problems with code using the old ni.py or other code such as my old ClassModules.py module which emulates modules using classes (provides all the cool __getattr__ and __setattr__ features to modules as well). > > ? The code should not import strop directly as this module > > will probably go away RSN. Use string methods instead. > > Yah. But I'm running this against 1.5.2 :-) > > I might be able to do something where the string methods are used if > available, and use the strop module if not. > [ similar to the 'os' bootstrapping that is done ] > > Finn Bock emailed me to say that JPython does not have strop, but does > have string methods. Since imputil.py targets 1.6 you can safely assume that string methods are in place. > > ? The design of the ImportManager has some minor flaws: the > > FS importer should be settable via class attributes, > > The class or the object itself? Putting a class in there would be nice, or > possibly passing it to the constructor (with a suitable default). > > This is a good idea, though. Please clarify what you'd like to see, and > I'll get it added. I usually put these things into the class so that subclasses can easily override the setting. > > deinstallation > > should be possible, > > Maybe. This is somewhat dependent upon whether it must "play nice." > Deinstallation would be quite easy if we move to a sys.get/set style of > interface, and it wouldn't be an issue to do de-install code. I was thinking mainly of debugging situations where you play around with new importer code -- its probably not important for production code. > > a query mechanism to find the importer > > used by a certain import would also be nice to be able to > > verify correct setup. > > module.__importer__ provides the importer that was used. This is defined > behavior (the system relies on that being set to deal with packages > properly). > > Is this sufficient, or were you looking for something else? I was thinking of a situations like: if : or if : raise SystemError,'wrong setup' Don't know if these queries are possible with the current flags and attributes. > module.__ispkg__ is also set to 0/1 accordingly. > > For backwards compat, __file__ and __path__ are also set. The __all__ > attribute in an __init__.py file is used for "from package import *". > > > ? py/pyc/pyo file piping hooks would be nice to allow > > imports of signed (and trusted) code and/or encrypted code > > (a mixin class for these filters would do the trick). > > I'd happily accept a base SuffixImporter class for these "pipes". I don't > believe that the ImportManager, Importer, or SuffixImporter base classes > would need any changes, though. > > Note that I probably will rearrange the _fs_import() and friends, per > Guido's suggestion to move them into a base class. That may be a step > towards having "pipes" available. It would be nice to be able to use the concept of stackable streams as source for byte and source code. For this to work one would have to make the file reading process a little more abstract by using e.g. a StreamReader instead (see the current unicode-proposal.txt version). > > ? Wish list: a distutils importer hooked to a list of standard > > package repositories, a module to file location mapper to > > speed up file system based imports, > > I'm not sure what the former would do. distutils is still a little > nebulous to me right now. Basically it should scan a set of URLs providing access to package repositories which hold distutils installable package archives. In case it finds a suitable package it should then proceed to auto-install it and then continue the normal import process. > For a mapper, we can definitely have a custom Importer that knows where > certain modules are found. However, I suspect you're looking for some kind > of a cache, but there isn't a hook to say "I found at > location" (which would be used to build the mapping). Right. I would like to see some standard mechanism used throughout the ImportManager for this. One which all importers can use and rely on. E.g. it would be nice to have an option to load the cache from disk upon startup to reduce search times. All this should be left for the user to configure with the standard setting being no cache at all (to avoid confusion and reduce support costs ;-). -- Marc-Andre Lemburg ______________________________________________________________________ Y2000: Happy New Century ! Business: http://www.lemburg.com/ Python Pages: http://www.lemburg.com/python/ From bwarsaw at cnri.reston.va.us Tue Jan 4 22:04:48 2000 From: bwarsaw at cnri.reston.va.us (Barry A. Warsaw) Date: Tue, 4 Jan 2000 16:04:48 -0500 (EST) Subject: [Python-Dev] new imputil.py References: Message-ID: <14450.24688.492098.917284@anthem.cnri.reston.va.us> Happy New Year! >>>>> "GS" == Greg Stein writes: GS> I think Python 1.6 should drop the __import__ builtin and move GS> to something like sys.import_hook (to allow examination and GS> change). Wait! You can't remove builtin __import__ without breaking code. E.g. Mailman uses __import__ quite a bit in its CGI (and other) harnesses. Why does __import__ need to be removed? Why can't it just just the same mechanism the import statement uses? GS> I might be able to do something where the string methods are GS> used if available, and use the strop module if not. [ similar GS> to the 'os' bootstrapping that is done ] GS> Finn Bock emailed me to say that JPython does not have strop, GS> but does have string methods. Sorry Greg, I haven't had time to look at this stuff at all, so maybe I'm missing something essential, but if you just continue to use the string module, you'll be fine for JPython and CPython 1.5.2. In CPython 1.5.2, you /will/ actually be using the strop module under the covers. In CPython 1.6 and JPython 1.1 you'll be using string methods under the covers. Your penalty is one layer of Python function calls. Never use strop directly though. >>>>> "MA" == M writes: MA> There has been some moaning about the current Python startup MA> speed, so I guess people already find the existing strategy MA> too slow. Definitely. -Barry From gmcm at hypernet.com Wed Jan 5 04:49:08 2000 From: gmcm at hypernet.com (Gordon McMillan) Date: Tue, 4 Jan 2000 22:49:08 -0500 Subject: [Python-Dev] new imputil.py In-Reply-To: <14449.258.374018.919406@weyr.cnri.reston.va.us> References: <1265213088-25101227@hypernet.com> Message-ID: <1265079245-1617919@hypernet.com> Fred L. Drake, Jr.wrote: > Gordon McMillan writes: > > I'd also like to point out that archives *can* be used in a > > development situation. Obviously I wouldn't bother putting a > > module under current development into an archive. But if the > > source is still installed and you haven't mucked with the > > __file__ attribute when you put it in the archive, then > > tracebacks will show you what you need. IDLE doesn't know > the > difference. So for most developers, the standard library > can > be served from an archive with no effect (other than speed). > > I don't see why we can't just add the source to the archive as > well; > this would allow proper tracebacks even outside the development > of the library. Not including sources would cleanly result in > the same situation as we currently see when there's only a .pyc > file. > Am I missing something fundamental? Sure you could. Then you could patch IDLE, Pythonwin, etc. to open the proper archive and extract the source. Then you could patch them (and archive) to update on the fly. And while you're at it, I'd really like a jacuzzi jet that gets my neck and shoulders without having to scrunch into all kinds of strange positions. - Gordon Return-Path: Delivered-To: python-dev at dinsdale.python.org Received: from python.org (parrot.python.org [132.151.1.90]) by dinsdale.python.org (Postfix) with ESMTP id A76701CD65 for ; Fri, 14 Jan 2000 12:39:29 -0500 (EST) Received: from merlin.codesourcery.com (IDENT:qmailr@[206.168.99.1]) by python.org (8.9.1a/8.9.1) with SMTP id MAA17463 for ; Fri, 14 Jan 2000 12:39:29 -0500 (EST) Received: (qmail 2115 invoked by uid 513); 14 Jan 2000 17:44:23 -0000 Mailing-List: contact publicity-help at software-carpentry.com; run by ezmlm Delivered-To: mailing list publicity at software-carpentry.com Received: (qmail 2110 invoked from network); 14 Jan 2000 17:44:19 -0000 Date: Fri, 14 Jan 2000 12:40:13 -0500 (EST) From: gvwilson at nevex.com To: publicity at software-carpentry.com Message-ID: MIME-Version: 1.0 Content-Type: MULTIPART/MIXED; BOUNDARY="168427786-1646135556-947871613=:8785" Subject: [Python-Dev] ANNOUNCEMENT: Open Source Design Competition Sender: python-dev-admin at python.org Errors-To: python-dev-admin at python.org X-BeenThere: python-dev at python.org X-Mailman-Version: 1.2 (experimental) Precedence: bulk List-Id: Python core developers This message is in MIME format. The first part should be readable text, while the remaining parts are likely unreadable without MIME-aware tools. Send mail to mime at docserver.cac.washington.edu for more info. --168427786-1646135556-947871613=:8785 Content-Type: TEXT/PLAIN; charset=US-ASCII The Software Carpentry project is pleased to announce the launch of its first Open Source design competition. The project's logo is attached, and details of the competition are included below. This message is being sent to you because you have expressed an interest in covering this story, or publicizing this project. If you have any questions, or do not wish to receive future notices about Software Carpentry, please contact: Dr. Gregory V. Wilson Software Carpentry Project Coordinator (416) 593 2428 gvwilson at software-carpentry.com Thanks for your interest! Greg Wilson ---------------------------------------------------------------------- ---------------------------------------------------------------------- Los Alamos National Laboratory Code Sourcery, LLC Software Carpentry Open Source Design Competition $100,000 in Prizes! ---------------------------------------------------------------------- The Software Carpentry project is pleased to announce its first Open Source design competition, with prizes totaling $100,000. Students and professionals from any country, working individually or in teams, are invited to submit design outlines for: * a platform inspection tool to replace autoconf; * a dependency management tool to replace make; * an issue tracking system to replace gnats and Bugzilla; and * a unit and regression testing harness with the functionality of XUnit, Expect, and DejaGnu. Participants may submit separate entries in one or more categories by March 31, 2000. Entries must be in English, and no more than 5000 words long; examples are available at http://www.software-carpentry.com. The competition will be judged by a panel that includes the following noted software developers, authors, and computational scientists: Stephen Adler Brookhaven National Laboratory Frank Alexander Los Alamos National Laboratory Donnie Barnes Red Hat Chris DiBona VA Linux Paul Dubois Lawrence Livermore National Laboratory Andrew Hunt Pragmatic Programmers, LLC Stephen R. Lee Los Alamos National Laboratory Josh MacDonald University of California, Berkeley Brian Marick Reliable Software Technologies Doug Mewhort Queen's University Bruce Perens co-founder of the Open Source Initiative Dave Thomas Pragmatic Programmers, LLC Jon Udell author of Practical Internet Groupware Guido van Rossum inventor of Python Tom Van Vleck TransIlluminant Phil Wadler Bell Labs Scot Wingo AuctionRover The best four entries in each category will be awarded $2500, and invited to submit full designs by June 1, 2000. The best design in each category will then receive an additional $7500, while runners-up will each receive $2500. Once winning designs have been announced, $200,000 will be available through open bidding for implementation, testing, and documentation. All of the project's work will be Open Source; all tools will be written in, or scriptable with, Python, and will be required to run on both Linux and Microsoft Windows NT. ---------------------------------------------------------------------- The Software Carpentry project is sponsored by the Advanced Computing Laboratory at the U.S. Department of Energy's Los Alamos National Laboratory (http://www.acl.lanl.gov), and administered by Code Sourcery, LLC (http://www.codesourcery.com). The project's aim is to encourage adoption of better software development practices by making software tools easier to use, and by documenting design, testing, and related activities. For more information on the project, or to let us know that you intend to submit a proposal, see http://www.software-carpentry.com, or mail info at software-carpentry.com. --168427786-1646135556-947871613=:8785 Content-Type: IMAGE/GIF; name="software-carpentry-logo.gif" Content-Transfer-Encoding: BASE64 Content-ID: Content-Description: Content-Disposition: attachment; filename="software-carpentry-logo.gif" R0lGODlhLAGhANX/AIACFYU8R2RkZqWlp0pKS+np6tXV1snJyr+/wLW2u+Dh 5srM1Pf4/PT1+e7v877Ax4GDiZygq6Sos4yPl5aZobm7wNrc4aywuXF0efv8 /M7PzywtLJF8U0s4F6mTa76pgXBeQE0+LeDb2M7JxsfAvaCPi7yysJBxb7Ge nf////7+/v39/fv7+/n5+fj4+Pb29vPz8/Ly8u/v7+3t7ebm5uLi4t3d3dnZ 2dLS0sXFxa6urh4eHg8PDwgICAMDAwAAACwAAAAALAGhAEAG/8CUcEgsGo/I pHLJbDqf0Kh0Sq1ar9isdsvter/gsFipcjXLQ1aBhtDg3m/NLdN0rZotVpPV aq7MTH9OLipFOSgxRXZ4dEx5e3pMLJFLGYBLgkxld0yLjpRKj0ktM4VEMgk6 FRcQGBILCrELEwITCRe4uRgEBAICvLwYF6sJEjV9RC4yRjKJRCwzoCkxy0QZ BdIupUUzL0WkpkMyMEUrMnQ2HOoeHh/u7OocJi8uOiEgNUYzAhsbO/0EMPDb UKFQDG/WYtjYEKJfCF4gfIEgQCOGtBfOhqiYcUmINmYIh7SQEU4ItSIZohWB UW3IigLIRM7gJI7csxmNaip5QYNmEv8XNKRV2EBBxYAdDNSETLKChs0lNTRU OFIBgqkZBZrA6MmEp7QiKOJxaDcihQsDJFCUKAHhBIgOHULEKGmEBoF//XYE HDhhhYoCLZXIKKADAwQlJ1sgmNBKgEDHkIsy2ZozCQsaHZFcXpoEcJMCMwTb ALWiRlYiMGx0/BtBQtaiLWxkFDKjhk8WNgKnmGGDZoFYFiwUFPLiBgRftf7S UGTjqRAZo4mUPj1EYcwUKmhoEABiLAEIE2h15/BWQGsJEnANuFGkQA1QGWjY zbvBVz8KQqavVE0kO42SL9jAmXu35bYSCnB15wEJNYR2SnRE0FBDSS40196E RMSWAAUYTHD/zAET2BCOCqbtl5l8ShRwA2dHyHCDc0JQcEEBKsBmgIOh3EAd Ei48oMABQjQgwQY//CCMQAqkUIOITKh4HRIz3HDJDOCBF94EFGQZwZbopYfL A/iZpWMnNmQ1UH13IZCGDRgqUVpvS5AIYYqjIQBXBwpyI+USF0TgCwQX3HJB el12GcFxyGG5I3Y2LIcdBCOscINhBVAAgwpsKlEDDoG1YMANoBSAw464UeBa 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 d8M73tIIAgA7 --168427786-1646135556-947871613=:8785-- From jeremy at cnri.reston.va.us Mon Jan 17 21:35:37 2000 From: jeremy at cnri.reston.va.us (Jeremy Hylton) Date: Mon, 17 Jan 2000 15:35:37 -0500 (EST) Subject: [Python-Dev] developers day session on compilers Message-ID: <14467.32025.761662.841271@goon.cnri.reston.va.us> I am championing a Developers' Day session on a Python compiler. There is a short Web page describing the goals of the session at http://www.python.org/workshops/2000-01/compiler.html. I'd appreciate feedback on the content and format of the session. If you have ideas for what we should talk about or do, please followup to me or to the list. Jeremy From mal at lemburg.com Tue Jan 18 23:55:04 2000 From: mal at lemburg.com (M.-A. Lemburg) Date: Tue, 18 Jan 2000 23:55:04 +0100 Subject: [Python-Dev] Python Tools/ Message-ID: <3884EF48.A6107775@lemburg.com> I was just looking through the Tools dir of the CVS version (looking for a tool which autoexpands tabs in Python source files -- which I didn't find) and found some other useful scripts along the way. To my surprise these executable files did not have a .py extension even though were Python source files. Is this intended ? I find that scripts like "world" provide useful information which would be nice to have in the standard lib -- with .py extension... Other tidbits: I noted that at least in my CVS tree the Tools/ht2html dir does not include any executable: have I missed something ? The script Tools/scripts/parseentities.py is not executable for some reason. -- Marc-Andre Lemburg ______________________________________________________________________ Business: http://www.lemburg.com/ Python Pages: http://www.lemburg.com/python/ From guido at CNRI.Reston.VA.US Wed Jan 19 13:50:05 2000 From: guido at CNRI.Reston.VA.US (Guido van Rossum) Date: Wed, 19 Jan 2000 07:50:05 -0500 Subject: [Python-Dev] Python Tools/ In-Reply-To: Your message of "Tue, 18 Jan 2000 23:55:04 +0100." <3884EF48.A6107775@lemburg.com> References: <3884EF48.A6107775@lemburg.com> Message-ID: <200001191250.HAA18786@eric.cnri.reston.va.us> > I was just looking through the Tools dir of the CVS version > (looking for a tool which autoexpands tabs in Python source > files -- which I didn't find) and found some other useful scripts > along the way. > > To my surprise these executable files did not have a .py > extension even though were Python source files. Is this > intended ? I find that scripts like "world" provide useful > information which would be nice to have in the standard > lib -- with .py extension... I would agree, but that's Barry's creation, so I'll let him answer for himself. Any other scripts with the same problem? > Other tidbits: > > I noted that at least in my CVS tree the Tools/ht2html > dir does not include any executable: have I missed something ? Actually, that directory is a ghost and shouldn't have been exported at all. (Barry, can you erase it from sweetpea?) > The script Tools/scripts/parseentities.py is not executable > for some reason. Fixed now. --Guido van Rossum (home page: http://www.python.org/~guido/) From bwarsaw at cnri.reston.va.us Wed Jan 19 17:24:41 2000 From: bwarsaw at cnri.reston.va.us (Barry A. Warsaw) Date: Wed, 19 Jan 2000 11:24:41 -0500 (EST) Subject: [Python-Dev] Python Tools/ References: <3884EF48.A6107775@lemburg.com> Message-ID: <14469.58697.116588.501355@anthem.cnri.reston.va.us> >>>>> "M" == M writes: M> To my surprise these executable files did not have a .py M> extension even though were Python source files. Is this M> intended ? I find that scripts like "world" provide useful M> information which would be nice to have in the standard M> lib -- with .py extension... I hadn't thought about making world a module, but if others agree, I can play a little CVS magic to move the file to world.py. M> I noted that at least in my CVS tree the Tools/ht2html dir does M> not include any executable: have I missed something ? If you do a `cvs up -P' (-P for prune) you'll find that that directory goes away. At one point I started to add the ht2html scripts to the Python tools, but then we decided not to. Unfortunately, once a directory's been added to CVS it can never be removed (hence -P). If you're really interested in the ht2html scripts, which are used to build the Python.Org and JPython.Org sites (as well as my personal pages), please see http://www.python.org/~bwarsaw/software/pyware.html -Barry From bwarsaw at cnri.reston.va.us Wed Jan 19 18:32:50 2000 From: bwarsaw at cnri.reston.va.us (Barry A. Warsaw) Date: Wed, 19 Jan 2000 12:32:50 -0500 (EST) Subject: [Python-Dev] Python Tools/ References: <3884EF48.A6107775@lemburg.com> <14469.58697.116588.501355@anthem.cnri.reston.va.us> Message-ID: <14469.62786.178265.983781@anthem.cnri.reston.va.us> >>>>> "BAW" == Barry A Warsaw writes: BAW> If you do a `cvs up -P' (-P for prune) you'll find that that BAW> directory goes away. At one point I started to add the BAW> ht2html scripts to the Python tools, but then we decided not BAW> to. Unfortunately, once a directory's been added to CVS it BAW> can never be removed (hence -P). I just check this and there is no ht2html directory in Tools anymore. We probably did remove it after you (MAL) had checked it out. You can either ignore the directory, or delete it from your working dirs. If cvs complains after deleting it, you may have to manually edit the CVS/Entries file. Sorry about that -- we know better now. -Barry From gerrit.holl at pobox.com Wed Jan 19 21:14:27 2000 From: gerrit.holl at pobox.com (Gerrit Holl) Date: Wed, 19 Jan 2000 21:14:27 +0100 Subject: [Python-Dev] ''.join in 1.6 Message-ID: <20000119211427.A3755@stopcontact.palga.uucp> Hello, I have a question/suggestion about ''.join in Python 1.6. Suppose I have this list: l = ["This", "is", "a", "test"] Currently, I would join it this way into a tab-delimeted string: s = string.join(l, '\t') In 1.6, I should do it this way: '\t'.join(s) I think it would be better to have that method on the *list*: s.join('\t') That's more clear, isn't it? regards, Gerrit. -- Please correct any bad English you encounter in my email message! -----BEGIN GEEK CODE BLOCK----- http://www.geekcode.com Version: 3.12 GCS dpu s-:-- a14 C++++>$ UL++ P--- L+++ E--- W++ N o? K? w--- !O !M !V PS+ PE? Y? PGP-- t- 5? X? R- tv- b+(++) DI D+ G++ !e !r !y -----END GEEK CODE BLOCK----- From fredrik at pythonware.com Wed Jan 19 21:43:36 2000 From: fredrik at pythonware.com (Fredrik Lundh) Date: Wed, 19 Jan 2000 21:43:36 +0100 Subject: [Python-Dev] ''.join in 1.6 References: <20000119211427.A3755@stopcontact.palga.uucp> Message-ID: <005e01bf62bd$dc8073d0$f29b12c2@secret.pythonware.com> > In 1.6, I should do it this way: > '\t'.join(s) > > I think it would be better to have that method on the *list*: > s.join('\t') > > That's more clear, isn't it? what if "s" is a tuple? an array? a user-defined sequence type? From bwarsaw at cnri.reston.va.us Wed Jan 19 21:36:24 2000 From: bwarsaw at cnri.reston.va.us (Barry A. Warsaw) Date: Wed, 19 Jan 2000 15:36:24 -0500 (EST) Subject: [Python-Dev] ''.join in 1.6 References: <20000119211427.A3755@stopcontact.palga.uucp> Message-ID: <14470.8264.686274.888365@anthem.cnri.reston.va.us> >>>>> "GH" == Gerrit Holl writes: GH> I think it would be better to have that method on the *list*: GH> s.join('\t') GH> That's more clear, isn't it? Perhaps, but you want join to work on any sequence don't you? By making it a method on string objects, you sort of get that for free (as opposed to putting it on lists, sequences, and requiring all class authors to add it as well). -Barry From da at ski.org Wed Jan 19 21:54:03 2000 From: da at ski.org (David Ascher) Date: Wed, 19 Jan 2000 12:54:03 -0800 Subject: [Python-Dev] ''.join in 1.6 In-Reply-To: <20000119211427.A3755@stopcontact.palga.uucp> Message-ID: <003b01bf62bf$5191abc0$c355cfc0@ski.org> Gerrit Holl > Currently, I would join it this way into a tab-delimeted string: > s = string.join(l, '\t') > > In 1.6, I should do it this way: > '\t'.join(s) > > I think it would be better to have that method on the *list*: > s.join('\t') > > That's more clear, isn't it? As Tim pointed out when they were discussed, the clearest way to express it with the new methods is to do: tab = '\t' tab.join(s) Similarly space = ' ' space.join(s) etc. --david ascher From da at ski.org Wed Jan 19 23:41:47 2000 From: da at ski.org (David Ascher) Date: Wed, 19 Jan 2000 14:41:47 -0800 Subject: [Python-Dev] SOAP Message-ID: <000101bf62ce$5e509e70$c355cfc0@ski.org> Who if anyone is working on SOAP clients and servers for Python? --david ascher -------------- next part -------------- A non-text attachment was scrubbed... Name: David Ascher.vcf Type: text/x-vcard Size: 527 bytes Desc: not available URL: From amk1 at erols.com Thu Jan 20 05:19:33 2000 From: amk1 at erols.com (A.M. Kuchling) Date: Wed, 19 Jan 2000 23:19:33 -0500 Subject: [Python-Dev] Changing existing class instances Message-ID: <200001200419.XAA01969@mira.erols.com> Currently, when you replace a class definition with an updated version, it's really difficult to change existing class instances; you'd have to essentially sweep every Python object and check if it's an instance, starting at roots such as __main__ and sys.modules. This makes developing code in a long-running process difficult, Zope being the best example of this. When you modify a class definition used by Zope code, you can't update existing instances floating around in memory. Over dinner, a friend and I were discussing this, and we thought it probably isn't difficult to add an extra level of indirection to allow fixing this. The only other option we could think of is either the complete scan of all objects, or inserting a forwarding pointer into PyClassObjects that points to the replacing class if !NULL, and then chase pointers when accessing PyInstanceObject->in_class. A quick hack to implement the extra indirection took about half an hour. It does these things: * Defines a PyClassHandle type: struct _PyClassHandle { PyClassHandle *next; /* ptr to next PyClassHandle in linked list */ PyClassObject *klass; /* The class object */ } ; * The in_class attribute of PyInstanceObject becomes a PyClassHandle* instead of a PyClassObject*, and all code such as inst->in_class becomes inst->in_class->klass. * As a quick hack to allow changing the class object referenced by a handle, I added a .forward( ) method to class objects. This basically does self.handle->klass = . The end result is that obj.__class__.forward(newclass) changes obj to be an instance of newclass, and all other instances of obj.__class__ also mutate to become newclass instances. Making this purely automatic seems hard; you'd have to catch things like 'import ftplib; ftplib.FTP = myclass', which would require automatically calling ftplib.FTP.forward( myclass ) to make all existing FTP instances mutate. Would it be worthwhile to export some hook for doing this in 1.6? The cost is adding an extra pointer deref to all access to PyInstanceObject->in_class. (This could probably also be added to ExtensionClass, and probably doesn't need to be added to core Python to help out Zope. Just a thought...) -- A.M. Kuchling http://starship.python.net/crew/amk/ Here the skull of a consumptive child becomes part of a great machine for calculating the motions of the stars. Here, a yellow bird frets within the ribcage of an unjust man. -- Welcome to Orqwith, in DOOM PATROL #22 From guido at CNRI.Reston.VA.US Thu Jan 20 05:41:29 2000 From: guido at CNRI.Reston.VA.US (Guido van Rossum) Date: Wed, 19 Jan 2000 23:41:29 -0500 Subject: [Python-Dev] Changing existing class instances In-Reply-To: Your message of "Wed, 19 Jan 2000 23:19:33 EST." <200001200419.XAA01969@mira.erols.com> References: <200001200419.XAA01969@mira.erols.com> Message-ID: <200001200441.XAA20952@eric.cnri.reston.va.us> > Currently, when you replace a class definition with an updated > version, it's really difficult to change existing class instances; > you'd have to essentially sweep every Python object and check if it's > an instance, starting at roots such as __main__ and sys.modules. This > makes developing code in a long-running process difficult, Zope being > the best example of this. When you modify a class definition used by > Zope code, you can't update existing instances floating around in > memory. There might be another solution. When you reload a module, the module object and its dictionary are reused. Perhaps class and function objects could similarly be reused? It would mean that a class or def statement looks for an existing object with the same name and type, and overwrites that. Voila, all references are automatically updated. This is more work (e.g. for classes, a new bytecode may have to be invented because the class creation process must be done differently) but it's much less of a hack, and I think it would be more reliable. (Even though it alters borderline semantics a bit.) (Your extra indirection also slows things down, although I don't know by how much -- not just the extra memory reference but also less locality of reference so more cache hits.) --Guido van Rossum (home page: http://www.python.org/~guido/) From tim_one at email.msn.com Thu Jan 20 06:59:51 2000 From: tim_one at email.msn.com (Tim Peters) Date: Thu, 20 Jan 2000 00:59:51 -0500 Subject: [Python-Dev] Changing existing class instances In-Reply-To: <200001200441.XAA20952@eric.cnri.reston.va.us> Message-ID: <000b01bf630b$91a409a0$31a2143f@tim> [Guido, on Andrew's idea for automagically updating classes] > There might be another solution. When you reload a module, > the module object and its dictionary are reused. > > Perhaps class and function objects could similarly be > reused? It would mean that a class or def statement > looks for an existing object with the same name and type, > and overwrites that. Voila, all references are > automatically updated. Too dangerous, I think. While uncommon in general, I've certainly seen (even written) functions that e.g. return a contained def or class. The intent in such cases is very much to create distinct defs or classes (despite having the same names). In this case I assume "the same name" wouldn't *usually* be found, since the "contained def or class"'s name is local to the containing function. But if there ever happened to be a module-level function or class of the same name, brrrr. Modules differ because their namespace "search path" consists solely of the more-global-than-global sys.modules. > This is more work (e.g. for classes, a new bytecode may > have to be invented because the class creation process > must be done differently) but it's much less of a hack, > and I think it would be more reliable. (Even though it > alters borderline semantics a bit.) How about an explicit function in the "new" module, new.update(class_or_def_old, class_or_def_new) which overwrites old's guts with new's guts (in analogy with dict.update)? Then no semantics change and you don't need new bytecodes. In return, a user who wants to e.g. replace an existing class C would need to do oldC = C do whatever they do to get the new C new.update(oldC, C) Building on that, a short Python loop could do the magic for every class and function in a module; and building on *that*, a short "updating import" function could be written in Python. View it as providing mechanism instead of policy <0.9 wink>. > (Your extra indirection also slows things down, although > I don't know by how much -- not just the extra memory > reference but also less locality of reference so more > cache hits.) Across the universe of all Python programs on all platforms, weighted by importance, it was a slowdown of nearly 4.317%. if-i-had-used-only-one-digit-everyone-would-have- known-i-was-making-it-up-ly y'rs - tim From gstein at lyra.org Thu Jan 20 08:48:29 2000 From: gstein at lyra.org (Greg Stein) Date: Wed, 19 Jan 2000 23:48:29 -0800 (PST) Subject: [Python-Dev] Changing existing class instances In-Reply-To: <000b01bf630b$91a409a0$31a2143f@tim> Message-ID: Oh man, oh man... I think this is where I get to say something akin to "I told you so." :-) I already described Tim's proposal in my type proposal paper, as a way to deal with incomplete classes. Essentially, a class object is created "empty" and is later "updated" with the correct bits. The empty class allows two classes to refer to each other in the "recursive type" scenario. In other words, I definitely would support a new class object behavior that allows us to update a class' set of bases and dictionary on the fly. This could then be used to support my solution for the recursive type scenario (which, in turn, means that we don't have to introduce Yet Another Namespace into Python to hold type names). Note: I would agree with Guido, however, on the "look for a class object with the same name", but with the restriction that the name is only replaced in the *target* namespace. i.e. a "class Foo" in a function will only look for Foo in the function's local namespace; it would not overwrite a class in the global space, nor would it overwrite class objects returned by a prior invocation of the function. Cheers, -g On Thu, 20 Jan 2000, Tim Peters wrote: > [Guido, on Andrew's idea for automagically updating > classes] > > > There might be another solution. When you reload a module, > > the module object and its dictionary are reused. > > > > Perhaps class and function objects could similarly be > > reused? It would mean that a class or def statement > > looks for an existing object with the same name and type, > > and overwrites that. Voila, all references are > > automatically updated. > > Too dangerous, I think. While uncommon in general, I've certainly seen > (even written) functions that e.g. return a contained def or class. The > intent in such cases is very much to create distinct defs or classes > (despite having the same names). In this case I assume "the same name" > wouldn't *usually* be found, since the "contained def or class"'s name is > local to the containing function. But if there ever happened to be a > module-level function or class of the same name, brrrr. > > Modules differ because their namespace "search path" consists solely of the > more-global-than-global sys.modules. > > > This is more work (e.g. for classes, a new bytecode may > > have to be invented because the class creation process > > must be done differently) but it's much less of a hack, > > and I think it would be more reliable. (Even though it > > alters borderline semantics a bit.) > > How about an explicit function in the "new" module, > > new.update(class_or_def_old, class_or_def_new) > > which overwrites old's guts with new's guts (in analogy with dict.update)? > Then no semantics change and you don't need new bytecodes. In return, a > user who wants to e.g. replace an existing class C would need to do > > oldC = C > do whatever they do to get the new C > new.update(oldC, C) > > Building on that, a short Python loop could do the magic for every class and > function in a module; and building on *that*, a short "updating import" > function could be written in Python. View it as providing mechanism instead > of policy <0.9 wink>. > > > (Your extra indirection also slows things down, although > > I don't know by how much -- not just the extra memory > > reference but also less locality of reference so more > > cache hits.) > > Across the universe of all Python programs on all platforms, weighted by > importance, it was a slowdown of nearly 4.317%. > > if-i-had-used-only-one-digit-everyone-would-have- > known-i-was-making-it-up-ly y'rs - tim > > > > _______________________________________________ > Python-Dev maillist - Python-Dev at python.org > http://www.python.org/mailman/listinfo/python-dev > -- Greg Stein, http://www.lyra.org/ From fredrik at pythonware.com Thu Jan 20 09:06:32 2000 From: fredrik at pythonware.com (Fredrik Lundh) Date: Thu, 20 Jan 2000 09:06:32 +0100 Subject: [Python-Dev] SOAP References: <000101bf62ce$5e509e70$c355cfc0@ski.org> Message-ID: <006901bf631d$449eea50$f29b12c2@secret.pythonware.com> David Ascher wrote: > Who if anyone is working on SOAP clients and servers for Python? we are (or rather, we will). hope to have code available during (late) Q1. From gerrit.holl at pobox.com Thu Jan 20 09:08:01 2000 From: gerrit.holl at pobox.com (Gerrit Holl) Date: Thu, 20 Jan 2000 09:08:01 +0100 Subject: [Python-Dev] ''.join in 1.6 In-Reply-To: <005e01bf62bd$dc8073d0$f29b12c2@secret.pythonware.com>; from fredrik@pythonware.com on Wed, Jan 19, 2000 at 09:43:36PM +0100 References: <20000119211427.A3755@stopcontact.palga.uucp> <005e01bf62bd$dc8073d0$f29b12c2@secret.pythonware.com> Message-ID: <20000120090801.A903@stopcontact.palga.uucp> Fredrik Lundh wrote on 948314616: > > In 1.6, I should do it this way: > > '\t'.join(s) > > > > I think it would be better to have that method on the *list*: > > s.join('\t') > > > > That's more clear, isn't it? > > what if "s" is a tuple? an array? a user-defined > sequence type? I understand. Thanks for your answers. regards, Gerrit. -- Please correct any bad English you encounter in my email message! -----BEGIN GEEK CODE BLOCK----- http://www.geekcode.com Version: 3.12 GCS dpu s-:-- a14 C++++>$ UL++ P--- L+++ E--- W++ N o? K? w--- !O !M !V PS+ PE? Y? PGP-- t- 5? X? R- tv- b+(++) DI D+ G++ !e !r !y -----END GEEK CODE BLOCK----- From jim at digicool.com Thu Jan 20 15:06:29 2000 From: jim at digicool.com (Jim Fulton) Date: Thu, 20 Jan 2000 09:06:29 -0500 Subject: [Python-Dev] Changing existing class instances References: <200001200419.XAA01969@mira.erols.com> Message-ID: <38871665.C3B6FFEE@digicool.com> "A.M. Kuchling" wrote: > > Currently, when you replace a class definition with an updated > version, it's really difficult to change existing class instances; > you'd have to essentially sweep every Python object and check if it's > an instance, starting at roots such as __main__ and sys.modules. This > makes developing code in a long-running process difficult, Zope being > the best example of this. When you modify a class definition used by > Zope code, you can't update existing instances floating around in > memory. In the case of Zope, if the objects that you care about happen to be persistent objects, then it's relatively easy to arrange to get the objects flushed from memory and reloaded with the new classes. (There are some subtle issues to deal with, like worrying about multiple threads, but in a development environment, you can deal with these, for example, by limiting the server to one thread.) Note that this is really only a special case of a much larger problem. Reloading a module redefines the global variables in a module. It doesn't update any references to those global references from other places, such as instances or *other* modules. For example, imports like: from foo import spam are not updated when foo is reloaded. Maybe you are expecting too much from reload. Jim -- Jim Fulton mailto:jim at digicool.com Technical Director (888) 344-4332 Python Powered! Digital Creations http://www.digicool.com http://www.python.org Under US Code Title 47, Sec.227(b)(1)(C), Sec.227(a)(2)(B) This email address may not be added to any commercial mail list with out my permission. Violation of my privacy with advertising or SPAM will result in a suit for a MINIMUM of $500 damages/incident, $1500 for repeats. From jim at digicool.com Thu Jan 20 15:34:13 2000 From: jim at digicool.com (Jim Fulton) Date: Thu, 20 Jan 2000 09:34:13 -0500 Subject: Python 2 namespace change? (was Re: [Python-Dev] Changing existing class instances) References: <200001200419.XAA01969@mira.erols.com> <38871665.C3B6FFEE@digicool.com> Message-ID: <38871CE5.53FB9D68@digicool.com> Jim Fulton wrote: > > Reloading a module redefines the global variables in a module. > It doesn't update any references to those global references > from other places, such as instances or *other* modules. > > For example, imports like: > > from foo import spam > > are not updated when foo is reloaded. A change to the way that namespaces are handled could make this work and have a number of other benefits, like global name usage without namespace lookups. I've suggested this to Guido in the past. His reasonable response is that this would be too big a change for Python 1. Maybe this is something to consider for Python 2? The basic idea (borrowed from Smalltalk) is to have a kind of dictionary that is a collection of "association" objects. An association object is simply a pairing of a name with a value. Association objects can be shared among multiple namespaces. An import like: from foo import spam would copy the association between the name 'foo' and a value from module 'spam' into the current module. If foo is reloaded or if the name is reassigned in spam, the association is modified and the change is seen in any namespaces that imported foo. Similarly if a function uses a global variable: spam=1 def bar(): global spam return spam*2 the compiled function contains the association between spam and it's value. This means that: - When spam is used in the function, it doesn't have to be looked up, - The function object no longer needs to keep a reference to it's globals. This eliminates an annoying circular reference. (I would not replace existing dictionaries with this new kind. I'd have both kinds available.) I think that this would be a really nice change for Python 2. Jim -- Jim Fulton mailto:jim at digicool.com Technical Director (888) 344-4332 Python Powered! Digital Creations http://www.digicool.com http://www.python.org Under US Code Title 47, Sec.227(b)(1)(C), Sec.227(a)(2)(B) This email address may not be added to any commercial mail list with out my permission. Violation of my privacy with advertising or SPAM will result in a suit for a MINIMUM of $500 damages/incident, $1500 for repeats. From guido at CNRI.Reston.VA.US Thu Jan 20 16:20:45 2000 From: guido at CNRI.Reston.VA.US (Guido van Rossum) Date: Thu, 20 Jan 2000 10:20:45 -0500 Subject: [Python-Dev] Changing existing class instances In-Reply-To: Your message of "Thu, 20 Jan 2000 00:59:51 EST." <000b01bf630b$91a409a0$31a2143f@tim> References: <000b01bf630b$91a409a0$31a2143f@tim> Message-ID: <200001201520.KAA21137@eric.cnri.reston.va.us> > From: "Tim Peters" > > [Guido, on Andrew's idea for automagically updating > classes] > > > There might be another solution. When you reload a module, > > the module object and its dictionary are reused. > > > > Perhaps class and function objects could similarly be > > reused? It would mean that a class or def statement > > looks for an existing object with the same name and type, > > and overwrites that. Voila, all references are > > automatically updated. > > Too dangerous, I think. While uncommon in general, I've certainly seen > (even written) functions that e.g. return a contained def or class. The > intent in such cases is very much to create distinct defs or classes > (despite having the same names). In this case I assume "the same name" > wouldn't *usually* be found, since the "contained def or class"'s name is > local to the containing function. But if there ever happened to be a > module-level function or class of the same name, brrrr. Agreed that that would be bad. But I wouldn't search outer scopes -- I would only look for a class/def that I was about to stomp on. > Modules differ because their namespace "search path" consists solely of the > more-global-than-global sys.modules. "The search path doesn't enter into it." > > This is more work (e.g. for classes, a new bytecode may > > have to be invented because the class creation process > > must be done differently) but it's much less of a hack, > > and I think it would be more reliable. (Even though it > > alters borderline semantics a bit.) > > How about an explicit function in the "new" module, > > new.update(class_or_def_old, class_or_def_new) > > which overwrites old's guts with new's guts (in analogy with dict.update)? > Then no semantics change and you don't need new bytecodes. Only a slight semantics change (which my full proposal would require too): function objects would become mutable -- their func_code, func_defaults, func_doc and func_globals fields (and, why not, func_name too) should be changeable. If you make all these assignable, it doesn't even have to be a privileged function. > In return, a > user who wants to e.g. replace an existing class C would need to do > > oldC = C > do whatever they do to get the new C > new.update(oldC, C) > > Building on that, a short Python loop could do the magic for every class and > function in a module; and building on *that*, a short "updating import" > function could be written in Python. View it as providing mechanism instead > of policy <0.9 wink>. That's certainly a reasonable compromise. Note that the update on a class should imply an update on its methods, right? --Guido van Rossum (home page: http://www.python.org/~guido/) From guido at CNRI.Reston.VA.US Thu Jan 20 16:45:40 2000 From: guido at CNRI.Reston.VA.US (Guido van Rossum) Date: Thu, 20 Jan 2000 10:45:40 -0500 Subject: Python 2 namespace change? (was Re: [Python-Dev] Changing existing class instances) In-Reply-To: Your message of "Thu, 20 Jan 2000 09:34:13 EST." <38871CE5.53FB9D68@digicool.com> References: <200001200419.XAA01969@mira.erols.com> <38871665.C3B6FFEE@digicool.com> <38871CE5.53FB9D68@digicool.com> Message-ID: <200001201545.KAA21304@eric.cnri.reston.va.us> > I've suggested this to Guido in the past. His > reasonable response is that this would be too big a > change for Python 1. Maybe this is something to consider > for Python 2? Note: from now on the new name for Python 2 is Python 3000. :-) > The basic idea (borrowed from Smalltalk) is to have a kind > of dictionary that is a collection of "association" > objects. An association object is simply a pairing of a > name with a value. Association objects can be shared among > multiple namespaces. I've never liked this very much, mostly because it breaks simplicity: the idea that a namespace is a mapping from names to values (e.g. {"limit": 100, "doit": , ...}) is beautifully simple, while the idea of inserting an extra level of indirection, no matter how powerful, is much murkier. There's also the huge change in semantics, as you point out; currently, from foo import bar has the same effect (on bar anyway) as import foo bar = foo.bar # i.e. copying an object reference del foo while under your proposal it would be more akin to changing all references to bar to become references to foo.bar. Of course that's what the moral equivalent of "from ... import ..." does in most other languages anyway, so we might consider this for Python 3000; however it would break a considerable amount of old code, I think. (Not to mention brain and book breakage. :-) --Guido van Rossum (home page: http://www.python.org/~guido/) From guido at CNRI.Reston.VA.US Thu Jan 20 17:01:38 2000 From: guido at CNRI.Reston.VA.US (Guido van Rossum) Date: Thu, 20 Jan 2000 11:01:38 -0500 Subject: [Python-Dev] Python 1.6 timing Message-ID: <200001201601.LAA21359@eric.cnri.reston.va.us> Andrew let me repost this mail of his to this list. It's worth a discussion here (if not in a larger forum). My responses are at the bottom. ------- Forwarded Message Date: Wed, 19 Jan 2000 20:17:55 -0500 From: "A.M. Kuchling" To: guido at python.org Subject: Python 1.6 timing I thought a bit more about the release schedule for 1.6, and like the idea of delaying it less and less. Another bad effect of delaying it is that not having Unicode in the core handicaps developing XML tools; we can continue working with wstrop, or integrate MAL's code into the XML-SIG's CVS tree, but it might mean abandoning the XML processing field to Perl & Tcl because the tools can't be made fully standard compliant in time. Options I can think of: 1) Delegating some control to a pumpkin holder [...]. 2) Releasing the Unicode+sre modules as separate add-ons to 1.5. (But would that impose annoying backward-compatibility constraints when they get integrated into 1.6?) 3) Add Unicode, sre, Distutils, plus other minor things and call it 1.5.5, meaning it's not as big a revision as a 1.6 release, but it's bigger than just another patchlevel of bugfixes. I don't remember what other features were planned for 1.6; was there anything major, if static typing is left for 2.0? - -- A.M. Kuchling http://starship.python.net/crew/amk/ Life's too short for chess. -- H.J. Byron ------- End of Forwarded Message There are several other things I can think of now that were planned for 1.6: revamped import, rich comparisons, revised coercions, parallel for loop (for i in L; j in M: ...), extended slicing for all sequences. I've also been thinking about making classes be types (not as huge a change as you think, if you don't allow subclassing built-in types), and adding a built-in array type suitable for use by NumPy. I've also received a conservative GC patch that seems to be fairly easy to apply and has some of Tim Peters' blessing. For 1.5.5 (what happened to 1.5.3 and 1.5.4?), we can have a more conservative agenda, as suggested by Andrew: Unicode and distutils are probably the most important things to integrate. (The import utilities are not ready for prime time in my opinion; there are too many issues.) Anybody care to be the pumpkin? That would cut the discussion short; otherwise the problem remains that I can't spend too much time on the next release unless I get funded for it; what little money I've received for CP4E I had better spend on getting some CP4E-related results ASAP, because the next installment of this funding is very much at stake... --Guido van Rossum (home page: http://www.python.org/~guido/) Life's better without braces. -- Bruce Eckel From bwarsaw at cnri.reston.va.us Thu Jan 20 17:21:30 2000 From: bwarsaw at cnri.reston.va.us (Barry A. Warsaw) Date: Thu, 20 Jan 2000 11:21:30 -0500 (EST) Subject: [Python-Dev] Python 1.6 timing References: <200001201601.LAA21359@eric.cnri.reston.va.us> Message-ID: <14471.13834.480356.541389@anthem.cnri.reston.va.us> >>>>> "Guido" == Guido van Rossum writes: Guido> There are several other things I can think of now that were Guido> planned for 1.6: revamped import, rich comparisons, revised Guido> coercions, parallel for loop (for i in L; j in M: ...), Guido> extended slicing for all sequences. I've also been Guido> thinking about making classes be types (not as huge a Guido> change as you think, if you don't allow subclassing Guido> built-in types), and adding a built-in array type suitable Guido> for use by NumPy. I've also received a conservative GC Guido> patch that seems to be fairly easy to apply and has some of Guido> Tim Peters' blessing. All very cool things that could easily wait until 1.7. After all, what's in a number? If, as Andrew puts forth, getting a stable Python release with Unicode is very important for Python's future positioning, then I say let's go with his more modest list, mainly Unicode, sre, and Distutils. We've already got string meths, tons of library improvements, and sundry other things. That's a good enough laundry list for the next release. From jim at digicool.com Thu Jan 20 17:21:33 2000 From: jim at digicool.com (Jim Fulton) Date: Thu, 20 Jan 2000 11:21:33 -0500 Subject: Version numbering (was Re: [Python-Dev] Python 1.6 timing) References: <200001201601.LAA21359@eric.cnri.reston.va.us> Message-ID: <3887360D.C29A9836@digicool.com> Guido van Rossum wrote: > > Andrew let me repost this mail of his to this list. It's worth a > discussion here (if not in a larger forum). My responses are at the > bottom. > (snip) > > There are several other things I can think of now that were planned > for 1.6: revamped import, rich comparisons, revised coercions, > parallel for loop (for i in L; j in M: ...), extended slicing for all > sequences. I've also been thinking about making classes be types (not > as huge a change as you think, if you don't allow subclassing built-in > types), and adding a built-in array type suitable for use by NumPy. > I've also received a conservative GC patch that seems to be fairly > easy to apply and has some of Tim Peters' blessing. > > For 1.5.5 (what happened to 1.5.3 and 1.5.4?), we can have a more > conservative agenda, as suggested by Andrew: Unicode and distutils are > probably the most important things to integrate. (The import > utilities are not ready for prime time in my opinion; there are too > many issues.) (snip) What is the basis of the Python numbering scheme? I thought that there was a notion that: - The first part changed with huge, possibly backward incompatible, changes, - The second part was for new functionality - The third part was for bug fixes. I thought I saw this scheme referenced somewhere and possibly even attributed to Guido. (?) I think that this is a better scheme that what I've seen with the 1.5 releases. Jim -- Jim Fulton mailto:jim at digicool.com Technical Director (888) 344-4332 Python Powered! Digital Creations http://www.digicool.com http://www.python.org Under US Code Title 47, Sec.227(b)(1)(C), Sec.227(a)(2)(B) This email address may not be added to any commercial mail list with out my permission. Violation of my privacy with advertising or SPAM will result in a suit for a MINIMUM of $500 damages/incident, $1500 for repeats. From petrilli at amber.org Thu Jan 20 17:33:52 2000 From: petrilli at amber.org (Christopher Petrilli) Date: Thu, 20 Jan 2000 11:33:52 -0500 Subject: [Python-Dev] Python 1.6 timing In-Reply-To: <14471.13834.480356.541389@anthem.cnri.reston.va.us>; from bwarsaw@cnri.reston.va.us on Thu, Jan 20, 2000 at 11:21:30AM -0500 References: <200001201601.LAA21359@eric.cnri.reston.va.us> <14471.13834.480356.541389@anthem.cnri.reston.va.us> Message-ID: <20000120113352.A23763@trump.amber.org> Barry A. Warsaw [bwarsaw at cnri.reston.va.us] wrote: > All very cool things that could easily wait until 1.7. After all, > what's in a number? If, as Andrew puts forth, getting a stable Python > release with Unicode is very important for Python's future > positioning, then I say let's go with his more modest list, mainly > Unicode, sre, and Distutils. We've already got string meths, tons of > library improvements, and sundry other things. That's a good enough > laundry list for the next release. Heck, Python is infinately more conservative in its numbering than a lot of projects. All that was mentioned would normally be enough to call it 2.0 easily. :-) Modesty can be counter productive in PR business...also there is the issue of having two copies of 1.5.x installed at the same time, which with Unicode could be a manjor consideraton for some of us. For me, numbering has always been (and I try and keep it this way with Zope): X.Y.Z X = structural changes, backward incompaibility Y = new features Z = bug fixes only Chris -- | Christopher Petrilli | petrilli at amber.org From bwarsaw at cnri.reston.va.us Thu Jan 20 17:30:32 2000 From: bwarsaw at cnri.reston.va.us (Barry A. Warsaw) Date: Thu, 20 Jan 2000 11:30:32 -0500 (EST) Subject: [Python-Dev] Python 1.6 timing References: <200001201601.LAA21359@eric.cnri.reston.va.us> <14471.13834.480356.541389@anthem.cnri.reston.va.us> <20000120113352.A23763@trump.amber.org> Message-ID: <14471.14376.9881.702264@anthem.cnri.reston.va.us> >>>>> "CP" == Christopher Petrilli writes: CP> For me, numbering has always been (and I try and keep it this CP> way with Zope): CP> X.Y.Z | X = structural changes, backward incompaibility | Y = new features | Z = bug fixes only I agree. -Barry From petrilli at amber.org Thu Jan 20 17:41:24 2000 From: petrilli at amber.org (Christopher Petrilli) Date: Thu, 20 Jan 2000 11:41:24 -0500 Subject: [Python-Dev] SOAP In-Reply-To: <006901bf631d$449eea50$f29b12c2@secret.pythonware.com>; from fredrik@pythonware.com on Thu, Jan 20, 2000 at 09:06:32AM +0100 References: <000101bf62ce$5e509e70$c355cfc0@ski.org> <006901bf631d$449eea50$f29b12c2@secret.pythonware.com> Message-ID: <20000120114124.B23763@trump.amber.org> Fredrik Lundh [fredrik at pythonware.com] wrote: > David Ascher wrote: > > Who if anyone is working on SOAP clients and servers for Python? > > we are (or rather, we will). hope to have code > available during (late) Q1. > > For what it's worth, this is also Zope's strategy. We are commited to having full SOAP integration in the system soon (when soon is, is another queston for the marketing department). :-) I am pretty sure that it will be a bi-directional integration. Chris -- | Christopher Petrilli | petrilli at amber.org From akuchlin at mems-exchange.org Thu Jan 20 17:38:53 2000 From: akuchlin at mems-exchange.org (Andrew M. Kuchling) Date: Thu, 20 Jan 2000 11:38:53 -0500 (EST) Subject: [Python-Dev] Python 1.6 timing In-Reply-To: <14471.13834.480356.541389@anthem.cnri.reston.va.us> References: <200001201601.LAA21359@eric.cnri.reston.va.us> <14471.13834.480356.541389@anthem.cnri.reston.va.us> Message-ID: <14471.14877.434886.471929@amarok.cnri.reston.va.us> Barry A. Warsaw writes: > Guido> There are several other things I can think of now that were > Guido> planned for 1.6: revamped import, rich comparisons, revised > Guido> coercions, parallel for loop (for i in L; j in M: ...), > Guido> extended slicing for all sequences. I'm not clear on the status of these various things; how many of these changes are deep ones that need lots of design, or affect massive amounts of the code base? For example, revamped import is a tricky design problem (as we've seen on this list). Is the spec for rich comparisons clearly defined at this point? Something like the parallel for loop seems like a parser modification combined with a code-generator modification, with no subtle implications for the rest of the implementation, and so that seems a simple matter of programming -- a week or so of effort. (Maybe I've missed something?) > Guido> I've also been > Guido> thinking about making classes be types (not as huge a > Guido> change as you think, if you don't allow subclassing > Guido> built-in types), and adding a built-in array type suitable > Guido> for use by NumPy. I've also received a conservative GC > Guido> patch that seems to be fairly easy to apply and has some of > Guido> Tim Peters' blessing. Similarly, does the conservative GC patch splatter changes all over the place, or is it very localized? Is adding the NumPy array type straightforward? Remember, there would presumably be a couple of 1.6 alphas and betas to shake out bugs. >From a political standpoint, I'd call the next release 1.6 and not >bother with another installment in 1.5.x series. And I agree with Fair enough; forget about the 1.5.5 suggestion, and call it as 1.6. >tree. My free-time plate is pretty full with JPython and Mailman, but >I'm willing to help where possible. Ditto. -- A.M. Kuchling http://starship.python.net/crew/amk/ One trouble with being efficient is that it makes everybody hate you so. -- Bob Edwards, the Calgary Eyeopener, March 18, 1916 From jim at digicool.com Thu Jan 20 17:48:18 2000 From: jim at digicool.com (Jim Fulton) Date: Thu, 20 Jan 2000 11:48:18 -0500 Subject: Python 2 namespace change? (was Re: [Python-Dev] Changing existing class instances) References: <200001200419.XAA01969@mira.erols.com> <38871665.C3B6FFEE@digicool.com> <38871CE5.53FB9D68@digicool.com> <200001201545.KAA21304@eric.cnri.reston.va.us> Message-ID: <38873C52.29FEAC6D@digicool.com> Guido van Rossum wrote: > > > I've suggested this to Guido in the past. His > > reasonable response is that this would be too big a > > change for Python 1. Maybe this is something to consider > > for Python 2? > > Note: from now on the new name for Python 2 is Python 3000. :-) I like it. > > The basic idea (borrowed from Smalltalk) is to have a kind > > of dictionary that is a collection of "association" > > objects. An association object is simply a pairing of a > > name with a value. Association objects can be shared among > > multiple namespaces. > > I've never liked this very much, mostly because it breaks simplicity: > the idea that a namespace is a mapping from names to values > (e.g. {"limit": 100, "doit": , ...}) is beautifully > simple, while the idea of inserting an extra level of indirection, no > matter how powerful, is much murkier. How so? It doesn't change the mapping semantics. > There's also the huge change in semantics, as you point out; > currently, > > from foo import bar > > has the same effect (on bar anyway) as > > import foo > bar = foo.bar # i.e. copying an object reference > del foo > > while under your proposal it would be more akin to changing all > references to bar to become references to foo.bar. > > Of course that's what the moral equivalent of "from ... import ..." > does in most other languages anyway, so we might consider this for > Python 3000; Cool. Again, it would also make function global variable access faster and cleaner in some ways. > however it would break a considerable amount of old code, > I think. Really? I wonder. I bet it would break alot less old code that other recent changes. > (Not to mention brain It makes my brain feel much better. :) > and book breakage. :-) Hey, all of the books will have to be rewritten for Python 3000. Jim -- Jim Fulton mailto:jim at digicool.com Technical Director (888) 344-4332 Python Powered! Digital Creations http://www.digicool.com http://www.python.org Under US Code Title 47, Sec.227(b)(1)(C), Sec.227(a)(2)(B) This email address may not be added to any commercial mail list with out my permission. Violation of my privacy with advertising or SPAM will result in a suit for a MINIMUM of $500 damages/incident, $1500 for repeats. From gstein at lyra.org Thu Jan 20 18:22:40 2000 From: gstein at lyra.org (Greg Stein) Date: Thu, 20 Jan 2000 09:22:40 -0800 (PST) Subject: [Python-Dev] Python 1.6 timing In-Reply-To: <200001201601.LAA21359@eric.cnri.reston.va.us> Message-ID: On Thu, 20 Jan 2000, Guido van Rossum wrote: >... > Date: Wed, 19 Jan 2000 20:17:55 -0500 > From: "A.M. Kuchling" > To: guido at python.org > Subject: Python 1.6 timing > > I thought a bit more about the release schedule for 1.6, and like the > idea of delaying it less and less. Another bad effect of delaying it > is that not having Unicode in the core handicaps developing XML tools; > we can continue working with wstrop, or integrate MAL's code into the > XML-SIG's CVS tree, but it might mean abandoning the XML processing > field to Perl & Tcl because the tools can't be made fully standard > compliant in time. I agree with Andrew's basic premise. > Options I can think of: > > 1) Delegating some control to a pumpkin holder [...]. Seems fine. > 2) Releasing the Unicode+sre modules as separate add-ons to > 1.5. (But would that impose annoying > backward-compatibility constraints when they get integrated > into 1.6?) Icky. :-) > 3) Add Unicode, sre, Distutils, plus other minor things and > call it 1.5.5, meaning it's not as big a revision as a 1.6 > release, but it's bigger than just another patchlevel of > bugfixes. I don't remember what other features were > planned for 1.6; was there anything major, if static typing > is left for 2.0? Call it 1.6, per the rest of the thread. >... > For 1.5.5 (what happened to 1.5.3 and 1.5.4?), we can have a more > conservative agenda, as suggested by Andrew: Unicode and distutils are > probably the most important things to integrate. Unicode: definitely. distutils seems pretty early, but I bet that some key concepts could be added to 1.6, to make the transition and continued development easier. Note that if an announcement were made to the effect of "feature freeze on February 15; only bug fixes afterwards," that you would get a lot of people scrambling to submit their pet features. This would be a good way to light some fires, to see what kinds of things get completed (i.e. we may think some things aren't ready or are too far out, put that deadline in and those positions could change...) > (The import > utilities are not ready for prime time in my opinion; there are too > many issues.) I'm waiting for that review :-) If you raise issues, then I can knock them down. I don't see all that many at the moment. But I'm biased :-) > Anybody care to be the pumpkin? That would cut the discussion short; > otherwise the problem remains that I can't spend too much time on the > next release unless I get funded for it; what little money I've > received for CP4E I had better spend on getting some CP4E-related > results ASAP, because the next installment of this funding is very > much at stake... I would volunteer for the pumpkin... around April-ish. My plate is rather full with completing mod_dav and then integrating that into Apache 2.0. Once the Apache integration begins, then I'd have some more free time. But this begs the question of: what does the pumpkin-holder mean in the *Python* world? If it is collating fixes, producing snapshots, etc, then I'm comfy with it. If it also contains responsibility for specific kinds of work, then Fred would probably veto me :-), as I've got an outstanding doc that I owe him (for about six months now... sigh; maybe I'll bribe MAL to write it; he knows the interface :-)). But stll: what's it mean? How does the pumpkin reduce the Guido-load, yet still enable the Guido-control? [ I just had a talk about this with the guys at Inprise, re: InterBase, mentioning that the Dictator model works well for Python, but doesn't necessarily work well for new projects or commercially-started projects due to control/prejudice issues. Python people like it because of the resulting simplicity and cleanliness; I doubt we want a pumpkin approach that would allow that to go away! ] Cheers, -g -- Greg Stein, http://www.lyra.org/ From guido at CNRI.Reston.VA.US Thu Jan 20 18:20:33 2000 From: guido at CNRI.Reston.VA.US (Guido van Rossum) Date: Thu, 20 Jan 2000 12:20:33 -0500 Subject: Python 2 namespace change? (was Re: [Python-Dev] Changing existing class instances) In-Reply-To: Your message of "Thu, 20 Jan 2000 11:48:18 EST." <38873C52.29FEAC6D@digicool.com> References: <200001200419.XAA01969@mira.erols.com> <38871665.C3B6FFEE@digicool.com> <38871CE5.53FB9D68@digicool.com> <200001201545.KAA21304@eric.cnri.reston.va.us> <38873C52.29FEAC6D@digicool.com> Message-ID: <200001201720.MAA21534@eric.cnri.reston.va.us> [me] > > I've never liked this very much, mostly because it breaks simplicity: > > the idea that a namespace is a mapping from names to values > > (e.g. {"limit": 100, "doit": , ...}) is beautifully > > simple, while the idea of inserting an extra level of indirection, no > > matter how powerful, is much murkier. [Jim F] > How so? It doesn't change the mapping semantics. My assumption is that in your version, the dictionary would contain special objects which then would contain the referenced objects. E.g. {"limit": , "doit": >}. Thus, d["limit"] would be that object, while previously it would return 100. > Again, it would also make function global variable access > faster and cleaner in some ways. But I have other plans for that (if the optional static typing stuff ever gets implemented). > > however it would break a considerable amount of old code, > > I think. > > Really? I wonder. I bet it would break alot less old > code that other recent changes. Oh? Name some changes that broke a lot of code? --Guido van Rossum (home page: http://www.python.org/~guido/) From jeremy at cnri.reston.va.us Thu Jan 20 18:36:32 2000 From: jeremy at cnri.reston.va.us (Jeremy Hylton) Date: Thu, 20 Jan 2000 12:36:32 -0500 (EST) Subject: [Python-Dev] Python 1.6 timing In-Reply-To: <14471.13834.480356.541389@anthem.cnri.reston.va.us> References: <200001201601.LAA21359@eric.cnri.reston.va.us> <14471.13834.480356.541389@anthem.cnri.reston.va.us> Message-ID: <14471.18336.257653.730100@bitdiddle.cnri.reston.va.us> >>>>> "BAW" == Barry A Warsaw writes: >>>>> "Guido" == Guido van Rossum writes: Guido> There are several other things I can think of now that were Guido> planned for 1.6: revamped import, rich comparisons, revised Guido> coercions, parallel for loop (for i in L; j in M: ...), Guido> extended slicing for all sequences. I've also been thinking Guido> about making classes be types (not as huge a change as you Guido> think, if you don't allow subclassing built-in types), and Guido> adding a built-in array type suitable for use by NumPy. I've Guido> also received a conservative GC patch that seems to be fairly Guido> easy to apply and has some of Tim Peters' blessing. BAW> All very cool things that could easily wait until 1.7. After BAW> all, what's in a number? If, as Andrew puts forth, getting a BAW> stable Python release with Unicode is very important for BAW> Python's future positioning, then I say let's go with his more BAW> modest list, mainly Unicode, sre, and Distutils. We've already BAW> got string meths, tons of library improvements, and sundry BAW> other things. That's a good enough laundry list for the next BAW> release. We've had this conversation before, so it'll comes as no surprise that I agree with you. Question: If we go with the feature set you've described, when will those features be ready? What kind of schedule could we set for releasing the first alpha? Jeremy From guido at CNRI.Reston.VA.US Thu Jan 20 18:40:51 2000 From: guido at CNRI.Reston.VA.US (Guido van Rossum) Date: Thu, 20 Jan 2000 12:40:51 -0500 Subject: [Python-Dev] Python 1.6 timing In-Reply-To: Your message of "Thu, 20 Jan 2000 09:22:40 PST." References: Message-ID: <200001201740.MAA21608@eric.cnri.reston.va.us> > Call it 1.6, per the rest of the thread. OK. I expect I'll get some complaints from some people who asked when 1.6 would be out (I've generally told them end of 2000); but it sounds like a 1.7 would be necessary to fulfill the other promises, so it shouldn't really matter -- it's all a case of relabeling for PR purposes. > Unicode: definitely. distutils seems pretty early, but I bet that some key > concepts could be added to 1.6, to make the transition and continued > development easier. The point of adding distutils is that it will allow distribution of packages without including distutils with each distribution. Since distutils was about 200K itself last time I looked, this is important. I don't believe it would be good to have to say "My FooBar package is really easy to install. All you need to do is download and install distutils, (which by the way is a 200K package that you have to manually install), and then run "python setup.py" in the FooBar root directory..." This would be enough for the average person to run away screaming. I think I saw a distribution by AMK that had a setup.py that tried to use distutils but had a crude fallback if distutils didn't exist; however that defeats much of the purpose since the package author has to figure out how to do the fallback. Large distributions (e.g. NumPy) can afford to squeeze distutils in a corner of their distribution, but for the average package it wouldn't be of much use. In other words, I'm for putting distutils in the next release, essentially feature-freezing it. Greg Ward, what do you think of that? > Note that if an announcement were made to the effect of "feature freeze on > February 15; only bug fixes afterwards," that you would get a lot of > people scrambling to submit their pet features. This would be a good way > to light some fires, to see what kinds of things get completed (i.e. we > may think some things aren't ready or are too far out, put that deadline > in and those positions could change...) I bet you we couldn't complete the import hooks by that date; I consider imputil.py as a nice prototype, but the integration with the C code is still missing. Also the 50% slowdown is a problem I worry about for inclusion a production version. (Plus breakage of everybody else's code who uses or hacks __import__; e.g. have you tested it with rexec?) > > (The import > > utilities are not ready for prime time in my opinion; there are too > > many issues.) > > I'm waiting for that review :-) It was kept up by the need to get the types documents out. > If you raise issues, then I can knock them down. I don't see all that many > at the moment. But I'm biased :-) > > > Anybody care to be the pumpkin? That would cut the discussion short; > > otherwise the problem remains that I can't spend too much time on the > > next release unless I get funded for it; what little money I've > > received for CP4E I had better spend on getting some CP4E-related > > results ASAP, because the next installment of this funding is very > > much at stake... > > I would volunteer for the pumpkin... around April-ish. My plate is rather > full with completing mod_dav and then integrating that into Apache 2.0. > Once the Apache integration begins, then I'd have some more free time. > > But this begs the question of: what does the pumpkin-holder mean in the > *Python* world? > > If it is collating fixes, producing snapshots, etc, then I'm comfy with > it. If it also contains responsibility for specific kinds of work, then > Fred would probably veto me :-), as I've got an outstanding doc that I owe > him (for about six months now... sigh; maybe I'll bribe MAL to write it; > he knows the interface :-)). > > But stll: what's it mean? How does the pumpkin reduce the Guido-load, yet > still enable the Guido-control? Good questions. I have to say that I feel reluctant to release any kind of control -- yet at the same time I desperately need help getting trivial stuff checked in. One of the most important time-consuming tasks is quality control: collecting fixes is all well and good, but I routinely reject fixes that superficially look fine, because they are subtly broken, or interfere with other plans, or just because the code looks poorly written. I also spend a lot of testing before I check things in; running the standard test suite is a good safeguard against general breakage, but you really have to play with the code affected by the change before you can know that it works as advertised. My work attitude here means that what gets checked in is generally rock solid, and that helps Python's reputation; but it is very costly... > [ I just had a talk about this with the guys at Inprise, re: InterBase, > mentioning that the Dictator model works well for Python, but doesn't > necessarily work well for new projects or commercially-started projects > due to control/prejudice issues. Python people like it because of the > resulting simplicity and cleanliness; I doubt we want a pumpkin approach > that would allow that to go away! ] Agreed, of course. --Guido van Rossum (home page: http://www.python.org/~guido/) From da at ski.org Thu Jan 20 18:57:51 2000 From: da at ski.org (David Ascher) Date: Thu, 20 Jan 2000 09:57:51 -0800 Subject: [Python-Dev] Python 1.6 timing In-Reply-To: <14471.13834.480356.541389@anthem.cnri.reston.va.us> Message-ID: <000701bf636f$de37c5e0$c355cfc0@ski.org> [I just got GvR's post on the topic, but I'll send this anyway] BAW: > All very cool things that could easily wait until 1.7. After all, > what's in a number? Guido has promised some of those features as being in 1.6 at conferences in the past, but I agree that string methods for example are a more major change than I'd expect to see in a 0.0.3-delta version change. Maybe with a deadline (as Greg suggests) we can integrate some of the pending patches (I agree with Greg that I at least would have found the time for a revised patch for rich comparisons if I'd had a deadline -- call me human =). Coercion and extended slicing also seem like relatively minor changes, compared with changing everything to be a class or adding GC! Regardless, just like Greg, I'd like to know what a pumpkin-holder would mean in the Python world. I propose that it be called the Oracle instead. As in, whoever is Oracle would get some training with Tim Peters and learn how to channel G__do. As a Python user, I'd be most comfortable with such a change if the Oracle just took over the technical stuff (reviewing patches, CVS checkins, running tests, corralling help for doc & code, maintaining release notes, building installers, etc.), but that the important decisions (e.g. whether to add a feature to the core language) would be checked with G__do first. We could call the position "Administrative Assistant", but somehow that doesn't have the prestige. A progressive schedule where Guido watches over the Oracle periodically would probably help build trust in the new mechanism. The Oracle would be expected to ask Guido for his opinion with everything at the beginning, and as a trust builds between Guido and the Oracle and the community and the mechanism, progressively less. --david ascher From gstein at lyra.org Thu Jan 20 19:30:52 2000 From: gstein at lyra.org (Greg Stein) Date: Thu, 20 Jan 2000 10:30:52 -0800 (PST) Subject: [Python-Dev] Python 1.6 timing In-Reply-To: <200001201740.MAA21608@eric.cnri.reston.va.us> Message-ID: On Thu, 20 Jan 2000, Guido van Rossum wrote: >... > In other words, I'm for putting distutils in the next release, > essentially feature-freezing it. Greg Ward, what do you think of > that? Oh, don't get me wrong. I'd like to see it in there for at least all the reasons you cite. But it seems (to me) that it is still pretty alpha. But hey: I'm shooting from the peanut gallery; we need GregW's comments. > > Note that if an announcement were made to the effect of "feature freeze on > > February 15; only bug fixes afterwards," that you would get a lot of > > people scrambling to submit their pet features. This would be a good way > > to light some fires, to see what kinds of things get completed (i.e. we > > may think some things aren't ready or are too far out, put that deadline > > in and those positions could change...) > > I bet you we couldn't complete the import hooks by that date; I > consider imputil.py as a nice prototype, but the integration with the > C code is still missing. Also the 50% slowdown is a problem I worry > about for inclusion a production version. (Plus breakage of everybody > else's code who uses or hacks __import__; e.g. have you tested it with > rexec?) hehe... if the static typing is to be deferred, then I'll take that bet! [discussion omitted; too tangental to this thread right now...] >... > Good questions. I have to say that I feel reluctant to release any > kind of control -- yet at the same time I desperately need help > getting trivial stuff checked in. Reading your comments below, we may be able to help. First, presume that at least one (best would be several) people man the "front lines" for any/all patches and bug reports. The front line can deal with the bug reports, mostly by responding with "go away; enter it into Jitterbug." Patches fall under several catagories, detailed below: > One of the most important > time-consuming tasks is quality control: collecting fixes is all well > and good, but I routinely reject fixes that superficially look fine, Conversely, your "lieutenants" (LTs) would filter all ugly-looking patches. > because they are subtly broken, If the LTs didn't catch these, then you could catch them from the checkin diff email. However, the LTs would reduce the number of broken ones that you would review. > or interfere with other plans, The LTs may know of this, but if not: you'd catch it at checkin time. The patches would then be backed out, altered, or whatever. > or just > because the code looks poorly written. The LTs would definitely catch this. If the style was *still* not up to snuff, I'd have to believe it would only be in minor ways that you could then touch up at your leisure. > I also spend a lot of testing > before I check things in; Done by the LTs. > running the standard test suite is a good > safeguard against general breakage, Ditto. > but you really have to play with > the code affected by the change before you can know that it works as > advertised. Ditto. > My work attitude here means that what gets checked in is > generally rock solid, and that helps Python's reputation; but it is > very costly... Based on my responses, I would venture to state that a group of LTs would manage to keep the Python core rock solid, except for: 1) subtle breakages that require your broader knowledge of Python 2) changes that "go against the plan" (and the LTs were ignorant of it) 3) minor format issues You would still review checkins, but the number of reviews would drop since the (obvious) crap has been eliminated. #1 is based on your *broad* knowledge of Python; I presume the LTs would be your match on various subsets of Python. By keeping the LTs well-informed, #2 could be nearly eliminated. #3 isn't that big of a deal, as I think your desired style is relatively well-known and the LTs would simply endeavor to match existing style. You could avoid a lot of testing; you would probably be inclined to do testing of items that you find dubious, but still this would be a reduction. ===== That may be an answer to the checkin problem. How about actual snapshots, alphas, betas, releases, and accompanying notes/news/readme files? I presume your LTs could run the alpha and beta aspects, but you would still issue final releases. Does your mail volume need to be reduced? (I think this has been asked before) Specifically, would patches at python.org (and similar targets) need to be established? (I would think so, as a matter of course, with the expectation that some patches would still end up with you and need to be bounced to patches@) Cheers, -g -- Greg Stein, http://www.lyra.org/ From klm at digicool.com Thu Jan 20 19:31:52 2000 From: klm at digicool.com (Ken Manheimer) Date: Thu, 20 Jan 2000 13:31:52 -0500 (EST) Subject: [Python-Dev] Python 1.6 timing In-Reply-To: <000701bf636f$de37c5e0$c355cfc0@ski.org> Message-ID: I must have missed the historic landmark where "pumpkin" was coined, but i think i get the gist. How about "Python Marshall" or "Python Activity Marshall" (a la the PS_A_)? Ken David Ascher wrote: > [...] > Regardless, just like Greg, I'd like to know what a pumpkin-holder would > mean in the Python world. > > I propose that it be called the Oracle instead. As in, whoever is Oracle > would get some training with Tim Peters and learn how to channel G__do. As > a Python user, I'd be most comfortable with such a change if the Oracle just > took over the technical stuff (reviewing patches, CVS checkins, running > tests, corralling help for doc & code, maintaining release notes, building > installers, etc.), but that the important decisions (e.g. whether to add a > feature to the core language) would be checked with G__do first. We could > call the position "Administrative Assistant", but somehow that doesn't have > the prestige. > > A progressive schedule where Guido watches over the Oracle periodically > would probably help build trust in the new mechanism. The Oracle would be > expected to ask Guido for his opinion with everything at the beginning, and > as a trust builds between Guido and the Oracle and the community and the > mechanism, progressively less. From gstein at lyra.org Thu Jan 20 19:42:43 2000 From: gstein at lyra.org (Greg Stein) Date: Thu, 20 Jan 2000 10:42:43 -0800 (PST) Subject: [Python-Dev] Python 1.6 timing In-Reply-To: Message-ID: On Thu, 20 Jan 2000, Ken Manheimer wrote: > I must have missed the historic landmark where "pumpkin" was coined, but i > think i get the gist. How about "Python Marshall" or "Python Activity > Marshall" (a la the PS_A_)? The "pumpkin" term comes from Perl-land... I'm not super clear on the pumpkin-holders's entire job, but I think it is basically the guy who sees that the version for which he "holds the pumpkin" is completed and shipped. Not necessarily by himself :-), but as the overseer (or "release manager" if you will). The current Perl pumpkin-holder is a guy at ActiveState. I think it changes for each version. Cheers, -g -- Greg Stein, http://www.lyra.org/ From gvwilson at nevex.com Thu Jan 20 19:51:17 2000 From: gvwilson at nevex.com (gvwilson at nevex.com) Date: Thu, 20 Jan 2000 13:51:17 -0500 (EST) Subject: [Python-Dev] Python 1.6 timing (fwd) Message-ID: Guido> There are several other things I can think of now that were Guido> planned for 1.6: revamped import, rich comparisons, revised Guido> coercions, parallel for loop (for i in L; j in M: ...), Guido> extended slicing for all sequences. I've also been thinking Guido> about making classes be types (not as huge a change as you Guido> think, if you don't allow subclassing built-in types), and Guido> adding a built-in array type suitable for use by NumPy. I've Guido> also received a conservative GC patch that seems to be fairly Guido> easy to apply and has some of Tim Peters' blessing. BAW> All very cool things that could easily wait until 1.7. After BAW> all, what's in a number? GVW writes: I agree on all counts except garbage collection --- I'm half-way through the second day of the Python class I teach at Los Alamos (the people who are funding the Python tool design competition), and it's come up a couple of times. People want to be able to prototype meshes, throw callbacks around without worrying about circularity, and some other things that I don't really understand yet. There's also a couple of smart guys in the class who are wondering about CPython vs. JPython ("So this'll be safe in one version of the language, but not in the other?"), and about marketing ("Help me win a feature comparison against Java in my group..."). There's also been questions about tighter integration of NumPy (e.g. overloading operators rather than calling 'greater()' to do comparison), but I think that's a separate discussion... My $0.02, Greg From tismer at tismer.com Thu Jan 20 20:11:13 2000 From: tismer at tismer.com (Christian Tismer) Date: Thu, 20 Jan 2000 20:11:13 +0100 Subject: [Python-Dev] Python 1.6 timing (fwd) References: Message-ID: <38875DD1.B6596@tismer.com> [garbage collection] gvwilson at nevex.com wrote: > I agree on all counts except garbage collection --- I'm half-way through > the second day of the Python class I teach at Los Alamos (the people who > are funding the Python tool design competition), and it's come up a couple > of times. People want to be able to prototype meshes, throw callbacks > around without worrying about circularity, and some other things that I > don't really understand yet. There's also a couple of smart guys in the > class who are wondering about CPython vs. JPython ("So this'll be safe in > one version of the language, but not in the other?"), and about marketing > ("Help me win a feature comparison against Java in my group..."). Guido once posted some proposal of a hybrid system *with* refcounts and some additional garbage collection scheme to match circular things. I believe this is a much better approach than what Java and therefor also JPython does at the moment. Although people might argue differently, I'm pretty sure that reference counting is the stronger concept. By reference counting, the idea of object ownership can be made explicit. This plays a central role in the Corba specification for instance, and I made the same observation when implementing continuations for Stackless Python. Refcounts are no burden but a virtue. Even better: Refcounting can lead to many new optimizations if we pay the cost to make INCREF/DECREF into methods. It has its cost (about 10 percent less pystones), but massive long-term benefits. I'm currently in charge to develop a custom version of Python's builtin types where this concept is used. Everything is refcounted, but without storing the refcounts in the objects. This is possible (proven) and will be shown in my next paper. Conclusion: I vote for a kind of GC that does just what refcounts cannot do, but please keep with the refcounts. cheers - chris -- Christian Tismer :^) Virtual Photonics GmbH : Have a break! Take a ride on Python's Carnotstr. 6 : *Starship* http://starship.python.net 10587 Berlin : PGP key -> http://wwwkeys.pgp.net PGP Fingerprint E182 71C7 1A9D 66E9 9D15 D3CC D4D7 93E2 1FAE F6DF we're tired of banana software - shipped green, ripens at home From tim_one at email.msn.com Thu Jan 20 20:47:01 2000 From: tim_one at email.msn.com (Tim Peters) Date: Thu, 20 Jan 2000 14:47:01 -0500 Subject: [Python-Dev] Changing existing class instances In-Reply-To: <200001201520.KAA21137@eric.cnri.reston.va.us> Message-ID: <000301bf637f$1f1c2d80$b72d153f@tim> [Tim worries about stomping on unintended classes/defs] [Guido] > Agreed that that would be bad. But I wouldn't search outer > scopes -- I would only look for a class/def that I was about > to stomp on. Maybe I just don't grasp what that means, exactly. Fair enough, since I'm not expressing myself clearly either! Suppose someone does from Tkinter import * in my.py, and later in my.py just *happens* to define, at module level, class Misc: blah blah blah Now Misc was already in my.py's global namespace because Tkinter.py just happens to export a class of that name too (more by accident than design -- but accidents are what I'm most worried about here). At the time my.py defines Misc, does Misc count as a class we're "about to stomp on"? If so-- & I've assumed so --it would wreak havoc. But if not, I don't see how this case can be reliably distinguished "by magic" from the cases where update is desired (if people are doing dynamic updates to a long-running program, a new version of a class can come from anywhere, so nothing like original file name or line number can distinguish correctly either). >> Modules differ because their namespace "search path" >> consists solely of the more-global-than-global >> sys.modules. > "The search path doesn't enter into it." I agree, but am at a loss to describe what's happening in the case above using other terminology . In a sense, you need a system-wide "unique handle" to support bulletproof updating, and while sys.modules has supplied that all along for module objects (in the form of the module name), I don't believe there's anything analogous to key off of for function or class objects. >> [suggesting] >> new.update(class_or_def_old, class_or_def_new) > Only a slight semantics change (which my full proposal > would require too): function objects would become mutable > -- their func_code, func_defaults, func_doc and func_globals > fields (and, why not, func_name too) should be changeable. Of course I meant "no new semantics" in the sense of "won't cause current exception-free code to alter behavior in any way". > If you make all these assignable, it doesn't even have to > be a privileged function. I'm all for that! > [sketching a Python approach to "updating import/reload" > building on the hypothetical new.update] > That's certainly a reasonable compromise. Note that the > update on a class should imply an update on its methods, > right? Hadn't considered that! Of course you're right. So make it a pair of nested loops . so-long-as-it-can-be-written-in-python-it's-easy-ly y'rs - tim From guido at CNRI.Reston.VA.US Thu Jan 20 21:02:20 2000 From: guido at CNRI.Reston.VA.US (Guido van Rossum) Date: Thu, 20 Jan 2000 15:02:20 -0500 Subject: [Python-Dev] Changing existing class instances In-Reply-To: Your message of "Thu, 20 Jan 2000 14:47:01 EST." <000301bf637f$1f1c2d80$b72d153f@tim> References: <000301bf637f$1f1c2d80$b72d153f@tim> Message-ID: <200001202002.PAA22435@eric.cnri.reston.va.us> > [Tim worries about stomping on unintended classes/defs] > > [Guido] > > Agreed that that would be bad. But I wouldn't search outer > > scopes -- I would only look for a class/def that I was about > > to stomp on. > > Maybe I just don't grasp what that means, exactly. Fair enough, since I'm > not expressing myself clearly either! > > Suppose someone does > > from Tkinter import * > > in my.py, and later in my.py just *happens* to define, at module level, > > class Misc: > blah blah blah > > Now Misc was already in my.py's global namespace because Tkinter.py just > happens to export a class of that name too (more by accident than design -- > but accidents are what I'm most worried about here). For a second I thought you got me there! > At the time my.py defines Misc, does Misc count as a class we're "about to > stomp on"? If so-- & I've assumed so --it would wreak havoc. > > But if not, I don't see how this case can be reliably distinguished "by > magic" from the cases where update is desired (if people are doing dynamic > updates to a long-running program, a new version of a class can come from > anywhere, so nothing like original file name or line number can distinguish > correctly either). Fortunately, there's magic available: recently, all classes have a __module__ attribute that is set to the full name of the module that defined it (its key in __sys__.modules). For functions, we would have to invent something similar. > >> Modules differ because their namespace "search path" > >> consists solely of the more-global-than-global > >> sys.modules. > > > "The search path doesn't enter into it." > > I agree, but am at a loss to describe what's happening in the case above > using other terminology . In a sense, you need a system-wide "unique > handle" to support bulletproof updating, and while sys.modules has supplied > that all along for module objects (in the form of the module name), I don't > believe there's anything analogous to key off of for function or class > objects. > > >> [suggesting] > >> new.update(class_or_def_old, class_or_def_new) > > > Only a slight semantics change (which my full proposal > > would require too): function objects would become mutable > > -- their func_code, func_defaults, func_doc and func_globals > > fields (and, why not, func_name too) should be changeable. > > Of course I meant "no new semantics" in the sense of "won't cause current > exception-free code to alter behavior in any way". > > > If you make all these assignable, it doesn't even have to > > be a privileged function. > > I'm all for that! > > > [sketching a Python approach to "updating import/reload" > > building on the hypothetical new.update] > > > That's certainly a reasonable compromise. Note that the > > update on a class should imply an update on its methods, > > right? > > Hadn't considered that! Of course you're right. So make it a pair of > nested loops . > > so-long-as-it-can-be-written-in-python-it's-easy-ly > y'rs - tim --Guido van Rossum (home page: http://www.python.org/~guido/) From guido at CNRI.Reston.VA.US Thu Jan 20 21:12:58 2000 From: guido at CNRI.Reston.VA.US (Guido van Rossum) Date: Thu, 20 Jan 2000 15:12:58 -0500 Subject: [Python-Dev] Python 1.6 timing (fwd) In-Reply-To: Your message of "Thu, 20 Jan 2000 20:11:13 +0100." <38875DD1.B6596@tismer.com> References: <38875DD1.B6596@tismer.com> Message-ID: <200001202012.PAA22501@eric.cnri.reston.va.us> > Conclusion: I vote for a kind of GC that does just what refcounts > cannot do, but please keep with the refcounts. The patch that I received and that has Tim's <0.5 blessing> does just that. I haven't had the time to understand why it doesn't have his <1.0 blessing>. --Guido van Rossum (home page: http://www.python.org/~guido/) From tim_one at email.msn.com Thu Jan 20 21:35:44 2000 From: tim_one at email.msn.com (Tim Peters) Date: Thu, 20 Jan 2000 15:35:44 -0500 Subject: [Python-Dev] Python 1.6 timing (fwd) In-Reply-To: <200001202012.PAA22501@eric.cnri.reston.va.us> Message-ID: <000901bf6385$eccfba20$b72d153f@tim> [Christian] > Conclusion: I vote for a kind of GC that does just > what refcounts cannot do, but please keep with the > refcounts. [Guido] > The patch that I received and that has Tim's <0.5 > blessing> does just that. I haven't had the time to > understand why it doesn't have his <1.0 blessing>. Primarily because it doesn't reclaim the most common cycles; e.g., cycles among class instances aren't touched. This seems easily repairable, but at an unknown cost (it needs to do the "reachability" transitive closure business from the set of all "suspicious" objects, and instances are never considered suspicious now; adding them will certainly cause a lot more pointer chasing). Apart from that, the code appears unreasonably expensive as written today, using e.g. splay trees instead of hash tables to keep track of objects. The author hasn't said anything more in a bit over two weeks, so I suspect he's off on other things now. The technical approach is sound, but even its inventor (Rafael Lins; Toby Kelsey may have reinvented it on his own, though) stresses that getting it to run fast is difficult. needs-work!-ly y'rs - tim, who hasn't the time to do it From tismer at tismer.com Thu Jan 20 21:35:27 2000 From: tismer at tismer.com (Christian Tismer) Date: Thu, 20 Jan 2000 21:35:27 +0100 Subject: [Python-Dev] Stackless Python 1.0 + Continuations 0.6 Message-ID: <3887718F.82E1B327@tismer.com> ANNOUNCING: Stackless Python 1.0 A Python Implementation That Does Not Use The C Stack * plus the real toy * Continuation Module 0.6 Continuations as First Class Objects What is it? A plugin-replacement for core Python. It should run any program which runs under Python 1.5.2 . But it does not need space on the C stack. Why did I write it? Stackless Python was never written before (afaik), since it was said to be impossible without major rewrites of core Python. I have proven the controverse: It is easy to write, just hard to think. About 3 times harder was finally the continuation module. The whole project took about 6 man months where 80 percent of the time was thinking and trying. The rest was coding and to become a reference counting champion :-) Recent changes: Version 1.0 has been optimized like hell and is now 3-5 percent faster than Standard Python. Continuation module is in version 0.6, very stable, and it allows to save a program's "future" at any time, in a portable way. Continuations are callable Python objects with a very small footprint. Who needs it? Since the continuations are done, this is no more only useful for C programmers who want to try certain new ideas. Everybody who is interested to develop his own generators, coroutines and tiny threads is invited to check it out. Status of the final 1.0: Pystone works correctly and is 5% faster than standard Python. Version 0.3 was 10 percent slower. Continuations work with PythonWin and Idle. The overall result is now better than expected, and I'm happy to call this *FINAL* (until the next version of course:) Downloadable files can be found at http://www.tismer.com/research/stackless/ Some older documentation: http://www.tismer.com/research/stackless/stackless.htm Some better documentation can be found in my IPC8 paper: http://www.tismer.com/research/stackless/spc_final.zip or be read directly as HTML http://www.tismer.com/research/stackless/spcpaper.htm Source code and a VC++6.0 build for Windows (340K): http://www.tismer.com/research/stackless/spc_win32.zip cheers - chris == Christian Tismer :^) Applied Biometrics GmbH : Have a break! Take a ride on Python's Kaiserin-Augusta-Allee 101 : *Starship* http://starship.python.net 10553 Berlin : PGP key -> http://wwwkeys.pgp.net PGP Fingerprint E182 71C7 1A9D 66E9 9D15 D3CC D4D7 93E2 1FAE F6DF we're tired of banana software - shipped green, ripens at home

Stackless Python 1.0 - a version of Python 1.5.2 that does not need space on the C stack. (20-Jan-00) From bwarsaw at cnri.reston.va.us Thu Jan 20 22:12:37 2000 From: bwarsaw at cnri.reston.va.us (Barry A. Warsaw) Date: Thu, 20 Jan 2000 16:12:37 -0500 (EST) Subject: [Python-Dev] Python 1.6 timing References: Message-ID: <14471.31301.504670.201702@anthem.cnri.reston.va.us> We'd have to rework the CVS arrangement in order to give non-CNRI employees write access to the tree. I think I know how I'd go about this, and it wouldn't be too hard, just a bit time-consuming. If that's the way we're going to go, I can start making plans. -Barry From guido at CNRI.Reston.VA.US Thu Jan 20 22:16:39 2000 From: guido at CNRI.Reston.VA.US (Guido van Rossum) Date: Thu, 20 Jan 2000 16:16:39 -0500 Subject: [Python-Dev] Python 1.6 timing In-Reply-To: Your message of "Thu, 20 Jan 2000 16:12:37 EST." <14471.31301.504670.201702@anthem.cnri.reston.va.us> References: <14471.31301.504670.201702@anthem.cnri.reston.va.us> Message-ID: <200001202116.QAA22943@eric.cnri.reston.va.us> [Barry] > We'd have to rework the CVS arrangement in order to give non-CNRI > employees write access to the tree. I think I know how I'd go about > this, and it wouldn't be too hard, just a bit time-consuming. If > that's the way we're going to go, I can start making plans. I think before you make such changes you'd have to talk to Bob (good luck). I don't mind applying patches and doing the checkins -- it's the decision-making that's time-consuming. --Guido van Rossum (home page: http://www.python.org/~guido/) From da at ski.org Thu Jan 20 22:28:24 2000 From: da at ski.org (David Ascher) Date: Thu, 20 Jan 2000 13:28:24 -0800 Subject: [Python-Dev] Python 1.6 timing (fwd) In-Reply-To: Message-ID: <001401bf638d$486488f0$c355cfc0@ski.org> Daddy Warbucks (uh, Greg Wilson =): > There's also been questions about tighter integration of NumPy (e.g. > overloading operators rather than calling 'greater()' to do comparison), > but I think that's a separate discussion... That's the rich comparison proposal which Guido mentioned. --david From bwarsaw at cnri.reston.va.us Thu Jan 20 22:30:24 2000 From: bwarsaw at cnri.reston.va.us (Barry A. Warsaw) Date: Thu, 20 Jan 2000 16:30:24 -0500 (EST) Subject: [Python-Dev] Python 1.6 timing References: <14471.31301.504670.201702@anthem.cnri.reston.va.us> <200001202116.QAA22943@eric.cnri.reston.va.us> Message-ID: <14471.32368.730988.252872@anthem.cnri.reston.va.us> >>>>> "Guido" == Guido van Rossum writes: Guido> I think before you make such changes you'd have to talk to Guido> Bob (good luck). Heh. Guido> I don't mind applying patches and doing the checkins -- Guido> it's the decision-making that's time-consuming. Then maybe the current CVS arrangement is fine (cool with me). -Barry From klm at digicool.com Thu Jan 20 23:08:28 2000 From: klm at digicool.com (Ken Manheimer) Date: Thu, 20 Jan 2000 17:08:28 -0500 (EST) Subject: [Python-Dev] Python 1.6 timing In-Reply-To: <14471.31301.504670.201702@anthem.cnri.reston.va.us> Message-ID: On Thu, 20 Jan 2000, Barry A. Warsaw wrote: > We'd have to rework the CVS arrangement in order to give non-CNRI > employees write access to the tree. I think I know how I'd go about > this, and it wouldn't be too hard, just a bit time-consuming. If > that's the way we're going to go, I can start making plans. Though it may be moot if guido's going to continue mediating the checkins, maybe this would be interesting (if only for barry, to compare procedures). We basically use a captive cvs-":ext:"-over-ssh method, where the captive .ssh/authorized_keys command is quite succinct: command="set $SSH_ORIGINAL_COMMAND; shift; exec cvs $@" 1024 35 ... The shellisms (set/shift/exec cvs $@) lock the user of the qualifying key into executing a cvs command, and only a cvs command. Also, for us the checkins are to a public mirror of our CVS repository, so penetration of the security there doesn't jepordize the master repository base. We don't currently have any outsiders checking into our master repository, and it doesn't seem to me that CVS provides sufficiently managable discretion for doing that. Oh, and a disappointment - the account under which cvs conducts the checkins is the account on the CVS server host, not that of the host where the checkins are being done. This means that you can't use a single account to serve multiple remote users (preventing masquerading quite reliably by using a separate authorized_key public-key entry for each remote user). Therefore we have to have distinct (nailed-down) accounts for each checkin-privileged person - more management burden. Ken From tim_one at email.msn.com Fri Jan 21 00:53:18 2000 From: tim_one at email.msn.com (Tim Peters) Date: Thu, 20 Jan 2000 18:53:18 -0500 Subject: [Python-Dev] Python 1.6 timing (fwd) In-Reply-To: <001401bf638d$486488f0$c355cfc0@ski.org> Message-ID: <000201bf63a1$8641b1c0$6ea0143f@tim> [Greg Wilson] > There's also been questions about tighter integration > of NumPy (e.g. overloading operators rather than > calling 'greater()' to do comparison), but I think ? that's a separate discussion... [David Ascher] > That's the rich comparison proposal which Guido mentioned. But there's also been talk about moving (at least) the basic NumPy array type into the core. This would be a Good Thing. Speaking for my employer, however, only Unicode is an Important Thing . As a developer, I have railed against schedule-driven release cycles. Python tends toward the opposite end of that spectrum, driven by features no matter how bloody long they take. Add Unicode to what's already waiting to go, and that's *good enough* reason for a major release; heck, it's been 9 months & we haven't even had a 1.5.2 bugfix patch. BTW, do the Perl-Porters have real jobs? pay-me-to-do-python-releases-and-you'll-get-a-major-new- release-every-three-days-ly y'rs - tim From da at ski.org Fri Jan 21 01:01:45 2000 From: da at ski.org (David Ascher) Date: Thu, 20 Jan 2000 16:01:45 -0800 Subject: [Python-Dev] Python 1.6 timing (fwd) In-Reply-To: <000201bf63a1$8641b1c0$6ea0143f@tim> Message-ID: <002601bf63a2$b4acf9b0$c355cfc0@ski.org> Tim Peters > But there's also been talk about moving (at least) the basic NumPy array > type into the core. This would be a Good Thing. IMNSHO, moving the current NumPy array into the core would be a Bad Thing. Moving a new similar object with cleaned up semantics and better implementation in would be a Good Thing. But it won't happen until 1.7 at the earliest, as the semantics haven't even been agreed on, let alone the code written. --david From da at ski.org Fri Jan 21 01:07:16 2000 From: da at ski.org (David Ascher) Date: Thu, 20 Jan 2000 16:07:16 -0800 Subject: [Python-Dev] Conference Schedules Message-ID: <002701bf63a3$79a15ae0$c355cfc0@ski.org> Given the rush of interesting discussions and progress which occurs in the two weeks before Python conferences, I propose that we have a bi-weekly conference. We'll just have to remember to cancel them at the last minute except a couple of times a year. --david ascher -------------- next part -------------- A non-text attachment was scrubbed... Name: David Ascher.vcf Type: text/x-vcard Size: 527 bytes Desc: not available URL: From gstein at lyra.org Fri Jan 21 01:53:59 2000 From: gstein at lyra.org (Greg Stein) Date: Thu, 20 Jan 2000 16:53:59 -0800 (PST) Subject: [Python-Dev] Python 1.6 timing In-Reply-To: <14471.31301.504670.201702@anthem.cnri.reston.va.us> Message-ID: On Thu, 20 Jan 2000, Barry A. Warsaw wrote: > We'd have to rework the CVS arrangement in order to give non-CNRI > employees write access to the tree. I think I know how I'd go about > this, and it wouldn't be too hard, just a bit time-consuming. If > that's the way we're going to go, I can start making plans. Or move the CVS tree off-site. Cheers, -g -- Greg Stein, http://www.lyra.org/ From guido at CNRI.Reston.VA.US Fri Jan 21 02:29:30 2000 From: guido at CNRI.Reston.VA.US (Guido van Rossum) Date: Thu, 20 Jan 2000 20:29:30 -0500 Subject: [Python-Dev] Python 1.6 timing In-Reply-To: Your message of "Thu, 20 Jan 2000 10:30:52 PST." References: Message-ID: <200001210129.UAA28292@eric.cnri.reston.va.us> (I accidentally mailed this only to Greg; here's a repost of the relevant parts to the list:) [me] > > Good questions. I have to say that I feel reluctant to release any > > kind of control -- yet at the same time I desperately need help > > getting trivial stuff checked in. [Greg Stein] > Reading your comments below, we may be able to help. [...Proposal of lieutenants condensed...] > Based on my responses, I would venture to state that a group of LTs would > manage to keep the Python core rock solid, except for: > > 1) subtle breakages that require your broader knowledge of Python > 2) changes that "go against the plan" (and the LTs were ignorant of it) > 3) minor format issues > > You would still review checkins, but the number of reviews would drop > since the (obvious) crap has been eliminated. #1 is based on your *broad* > knowledge of Python; I presume the LTs would be your match on various > subsets of Python. By keeping the LTs well-informed, #2 could be nearly > eliminated. #3 isn't that big of a deal, as I think your desired style is > relatively well-known and the LTs would simply endeavor to match existing > style. > > You could avoid a lot of testing; you would probably be inclined to do > testing of items that you find dubious, but still this would be a > reduction. > > ===== > > That may be an answer to the checkin problem. How about actual snapshots, > alphas, betas, releases, and accompanying notes/news/readme files? I > presume your LTs could run the alpha and beta aspects, but you would still > issue final releases. There's a lot of work in these (you may have noticed that the release notes got sloppier as 1.5.2 neared its completion). I would be happy to have the responsibility to decide to release without the burden of having to do all the work. > Does your mail volume need to be reduced? (I think this has been asked > before) Specifically, would patches at python.org (and similar targets) need > to be established? (I would think so, as a matter of course, with the > expectation that some patches would still end up with you and need to be > bounced to patches@) It's not the mail volume that bothers me -- I can ignore 100s of messages a day very quickly. It's the time it takes to respond to all of them. As an experiment, I've collected about 40 messages with suggested patches in them that I found in my inbox; the oldest are nearly two years old. You can access these from this address: http://www.python.org/~guido/patch/ I would love any help I could get in responding with these, and taking action in the form of patches. I propose that if you decide that a particular patch is worth checking in, you ask the author for the bugrelease or wetsign disclaimer and let me know that I can check it in; if changes to the patch are needed, I propose that you negotiate these with the author first. (I often ask them to test my version of a patch when I have style suggestions but don't have access the target platform or problem it solves.) --Guido van Rossum (home page: http://www.python.org/~guido/) From tim_one at email.msn.com Fri Jan 21 10:38:21 2000 From: tim_one at email.msn.com (Tim Peters) Date: Fri, 21 Jan 2000 04:38:21 -0500 Subject: [Python-Dev] Changing existing class instances In-Reply-To: Message-ID: <001801bf63f3$414e0c60$ec2d153f@tim> [Greg Stein] > ... > In other words, I definitely would support a new class > object behavior that allows us to update a class' set of > bases and dictionary on the fly. This could then be used > to support my solution for the recursive type scenario (which, > in turn, means that we don't have to introduce Yet Another > Namespace into Python to hold type names). Parenthetically, I never grasped the appeal of the parenthetical comment. Yet Another Namespace for Yet Another Entirely New Purpose seems highly *desirable* to me! Trying to overload the current namespace set makes it so much harder to see that these are compile-time gimmicks, and users need to be acutely aware of that if they're to use it effectively. Note that I understand (& wholly agree with) the need for runtime introspection. different-things-different-rules-ly y'rs - tim From tim_one at email.msn.com Fri Jan 21 10:38:24 2000 From: tim_one at email.msn.com (Tim Peters) Date: Fri, 21 Jan 2000 04:38:24 -0500 Subject: [Python-Dev] Python 1.6 timing In-Reply-To: <20000120113352.A23763@trump.amber.org> Message-ID: <001901bf63f3$432404e0$ec2d153f@tim> [Christopher Petrilli] > Heck, Python is infinately more conservative in its > numbering than a lot of projects. All that was mentioned > would normally be enough to call it 2.0 easily. :-) Modesty > can be counter productive in PR business... Indeed, where I work a number of managers met the suggestion to use Python 1.5.x with "what?! we don't want to use software that's barely out of alpha release -- besides, Perl is already on release 5". I hear that Guido got normal American glasses -- time to do normal American hyperinflated version numbering too. heck-ms-windows-will-soon-be-at-version-2000-ly y'rs - tim From tim_one at email.msn.com Fri Jan 21 10:38:26 2000 From: tim_one at email.msn.com (Tim Peters) Date: Fri, 21 Jan 2000 04:38:26 -0500 Subject: [Python-Dev] Python 1.6 timing In-Reply-To: <14471.14877.434886.471929@amarok.cnri.reston.va.us> Message-ID: <001a01bf63f3$4473b660$ec2d153f@tim> [Andrew M. Kuchling] > ... > Similarly, does the conservative GC patch splatter changes > all over the place, or is it very localized? Part of its problem is that it's *too* localized (which was, paradoxically, I suspect part of its initial quick-eyeball appeal to Guido -- it "looks like" an amazingly self-contained patch). For example, all the code to chase pointers in various types of objects is hiding in a single function, which does a string of "if type is list then this else if type is tuple then that ..." tests. This stuff clearly needs to be distributed across the object implementations and dispatched to via a new slot in type objects; there's no code for that now. I expect it would take a minimum of two weeks (full-time work) to make this code ready for prime time (but mostly to slash the space and time use -- and with no certainty of "good enough" in the end). BTW, "conservative" is a misleading adjective for this approach -- it never guesses ("guessing on the safe side" whether or not some bit pattern is a pointer is what "conservative" customarily means in the GC world). > Is adding the NumPy array type straightforward? DavidA nixed that one in no uncertain terms! maybe-hp-will-give-up-unicode-and-we-can-release-tomorrow-ly y'rs - tim From tim_one at email.msn.com Fri Jan 21 10:52:13 2000 From: tim_one at email.msn.com (Tim Peters) Date: Fri, 21 Jan 2000 04:52:13 -0500 Subject: [Python-Dev] Python 1.6 timing (fwd) In-Reply-To: Message-ID: <001d01bf63f5$318e2600$ec2d153f@tim> [Greg Wilson] > ... > There's also a couple of smart guys in the class who are > wondering about CPython vs. JPython ("So this'll be safe in > one version of the language, but not in the other?"), Greg, people who have been exposed to Fortran (this is LANL, right ?) can't possibly have a problem with the concept of "not defined by the standard". Don't sell these as different *versions* of the language, but as different implementations. That's what they are. The Python *language* doesn't define anything about the lifetime of objects. Even when CPython grows "real GC", thanks to refcounting too you'll still be able to *rely* on behaviors in CPython you'll see only accidentally in JPython. You do so at your own risk, same as e.g. you rely on floating point Fortran x+y+z getting evaluated "left to right" at your own risk (BTW, x+y+z *is* "left to right" in Python -- maybe they'll trade that for the lack of GC promises ). From tim_one at email.msn.com Fri Jan 21 11:22:51 2000 From: tim_one at email.msn.com (Tim Peters) Date: Fri, 21 Jan 2000 05:22:51 -0500 Subject: [Python-Dev] Changing existing class instances In-Reply-To: <200001202002.PAA22435@eric.cnri.reston.va.us> Message-ID: <001e01bf63f9$79660980$ec2d153f@tim> [Tim, still worried about stomping on unintended classes/defs] [example abusing Tkinter.Misc] > For a second I thought you got me there! That's twice as long as I thought you'd think that, so I win after all . > Fortunately, there's magic available: recently, all classes > have a __module__ attribute that is set to the full name > of the module that defined it (its key in __sys__.modules). > > For functions, we would have to invent something similar. OK! I didn't know about class.__module__ -- I hope you realize that relying on your time machine is making you lazy . I remain uncomfortable with automagic updating, but not as much so. Both kinds of errors still seem possible to me: 1. Automagically updating when it wasn't wanted. Examples of this are getting harder to come by . Off the top of my head I'm reduced to stuff like this: >>> adders = [] >>> for i in range(10): def adder(y, x=i): return y+x adders.append(adder) >>> adders[2](40) 42 >>> adders[9](33) 42 >>> "That kind of thing" has got to be rare, but can't be non-existent either (well, isn't -- I've done it). 2. Failing to automagically update when it was wanted. Implicit in the discussion so far is that long-running systems want to update code at a granularity no finer than module level. Is that realistic? I'm unsure. It's certainly easy to *imagine* the app running an updater server thread, accepting new source for functions and classes, and offering to compile and install the objects. Under the explicit new.update scheme, such a service needn't bother clients with communicating the full name of the original module; heck, in a *truly* long-running app, over time the source tree will change, and classes and functions will migrate across modules. That will be a problem for the explicit scheme too (how does it know *which* "class Misc" to update) -- but at least it's an explicit problem then, and not a "mysterous failure" of hidden magic. I could live with both of those (#1 is more worrisome); but think it easier all around to give the users some tools and tell them to solve the problems however they see fit. or-maybe-we-already-agreed-about-that-ly y'rs - tim From gstein at lyra.org Fri Jan 21 12:08:19 2000 From: gstein at lyra.org (Greg Stein) Date: Fri, 21 Jan 2000 03:08:19 -0800 (PST) Subject: [Python-Dev] namespaces (was: Changing existing class instances) In-Reply-To: <001801bf63f3$414e0c60$ec2d153f@tim> Message-ID: On Fri, 21 Jan 2000, Tim Peters wrote: > [Greg Stein] > > ... > > In other words, I definitely would support a new class > > object behavior that allows us to update a class' set of > > bases and dictionary on the fly. This could then be used > > to support my solution for the recursive type scenario (which, > > in turn, means that we don't have to introduce Yet Another > > Namespace into Python to hold type names). > > Parenthetically, I never grasped the appeal of the parenthetical comment. > Yet Another Namespace for Yet Another Entirely New Purpose seems highly > *desirable* to me! Trying to overload the current namespace set makes it so > much harder to see that these are compile-time gimmicks, and users need to > be acutely aware of that if they're to use it effectively. Note that I > understand (& wholly agree with) the need for runtime introspection. And that is the crux of the issue: I think the names that are assigned to these classes, interfaces, typedefs, or whatever, can follow the standard Python semantics and be plopped into the appropriate namespace. There is no overloading. The compile-time behavior certainly understands what names have what types; in this case, if a name is a "typedecl", then it can remember the *value*, too. When the name is used later, it knows the corresponding value to use. For instance: IntOrString = typedef int|str def foo(x: IntOrString): ... In this example, the type-checker knows that IntOrString is a typedecl. It also knows the *value* of "int|str" so the name IntOrString now has two items associated with it at type-check time: # not "real" syntax, but you get the idea... namespace["IntOrString"] = (TypeDeclarator, int|str) With the above information in hand, the type-checker knows what IntOrString means in the declaration for foo(). The cool benefit is that the runtime semantics are exactly as you would expect: a typedecl object is created and assigned to IntOrString. That object is also associated with the "x" argument in the function object referred to by the name "foo". There is no "overloading" of namespaces. We are using Python namespaces just like they should be, and the type-checker doesn't even have to be all the smart to track this stuff. To get back to the recursive class problem, consider the following code: decl incomplete class Foo decl incomplete class Bar class Foo: decl a: Bar class Bar: decl b: Foo The "decl" statements would create an empty class object and store that into the "current" namespace. There is no need to shove that off into another namespace. When the "class Foo" comes along, the class object is updated with the class definition for Foo. It is conceivable to remove the need for "decl" if you allow "class" and "def" to omit the ": suite" portion of their grammar: class Foo class Bar class Foo: decl a: Bar ... def some_function(x: some_type, y: another_type) -> third_type ... lots o' code ... def some_function(x, y): ... Guido suggested that it may be possible to omit "decl" altogether. Certainly, it can work for member declarations such as: class Foo: a: Bar Anyhow... my point is that a new namespace is not needed. Assuming we want objects for reflection at runtime, then the above proposal states *how* those objects are realized at runtime. Further, the type-checker can easily follow that information and perform the appropriate compile-time checks. No New Namespaces! (lather, rinse, repeat) Cheers, -g -- Greg Stein, http://www.lyra.org/ From gstein at lyra.org Fri Jan 21 12:12:57 2000 From: gstein at lyra.org (Greg Stein) Date: Fri, 21 Jan 2000 03:12:57 -0800 (PST) Subject: [Python-Dev] Changing existing class instances In-Reply-To: <200001202002.PAA22435@eric.cnri.reston.va.us> Message-ID: On Thu, 20 Jan 2000, Guido van Rossum wrote: > Tim Peters: >... > > At the time my.py defines Misc, does Misc count as a class we're "about to > > stomp on"? If so-- & I've assumed so --it would wreak havoc. > > > > But if not, I don't see how this case can be reliably distinguished "by > > magic" from the cases where update is desired (if people are doing dynamic > > updates to a long-running program, a new version of a class can come from > > anywhere, so nothing like original file name or line number can distinguish > > correctly either). > > Fortunately, there's magic available: recently, all classes have a > __module__ attribute that is set to the full name of the module that > defined it (its key in __sys__.modules). > > For functions, we would have to invent something similar. func.func_globals __module__ and func_globals can prevent *other* modules from redefining something accidentally, but it doesn't prevent Badness from within the module. [ Tim just posted an example of this: his "def adder()" example... ] Cheers, -g -- Greg Stein, http://www.lyra.org/ From bwarsaw at cnri.reston.va.us Fri Jan 21 15:38:52 2000 From: bwarsaw at cnri.reston.va.us (Barry A. Warsaw) Date: Fri, 21 Jan 2000 09:38:52 -0500 (EST) Subject: [Python-Dev] Changing existing class instances References: <200001202002.PAA22435@eric.cnri.reston.va.us> <001e01bf63f9$79660980$ec2d153f@tim> Message-ID: <14472.28540.765858.16133@anthem.cnri.reston.va.us> >>>>> "TP" == Tim Peters writes: TP> Under the explicit new.update scheme, such a service needn't TP> bother clients with communicating the full name of the TP> original module; heck, in a *truly* long-running app, over TP> time the source tree will change, and classes and functions TP> will migrate across modules. That will be a problem for the TP> explicit scheme too (how does it know *which* "class Misc" to TP> update) -- but at least it's an explicit problem then, and not TP> a "mysterous failure" of hidden magic. I completely agree. I think in general, such long running apps are rare, and in those cases you probably want to be explicit about when and how the updates occur anyway. The one place where automatic updates would be convenient would be at the interactive prompt, so it might be nice to add a module that could be imported by PYTHONSTARTUP, and play hook games to enable automatic updates. -Barry From bwarsaw at cnri.reston.va.us Fri Jan 21 15:39:32 2000 From: bwarsaw at cnri.reston.va.us (Barry A. Warsaw) Date: Fri, 21 Jan 2000 09:39:32 -0500 (EST) Subject: [Python-Dev] Python 1.6 timing References: <14471.31301.504670.201702@anthem.cnri.reston.va.us> Message-ID: <14472.28580.945266.658533@anthem.cnri.reston.va.us> >>>>> "GS" == Greg Stein writes: GS> Or move the CVS tree off-site. I don't see what this buys us. -Barry From gstein at lyra.org Fri Jan 21 15:48:40 2000 From: gstein at lyra.org (Greg Stein) Date: Fri, 21 Jan 2000 06:48:40 -0800 (PST) Subject: [Python-Dev] Python 1.6 timing In-Reply-To: <14472.28580.945266.658533@anthem.cnri.reston.va.us> Message-ID: On Fri, 21 Jan 2000, Barry A. Warsaw wrote: > >>>>> "GS" == Greg Stein writes: > > GS> Or move the CVS tree off-site. > > I don't see what this buys us. I was under the impression that CVS access restrictions are based on CNRI security policy. If the CVS repository moves elsewhere, then many people can access it without impact on CNRI's network and security policies. However, if the external access issue is based on legal reasons (for example, only CNRI people should alter Python code), then yes: moving the repository will buy nothing. Cheers, -g -- Greg Stein, http://www.lyra.org/ From bwarsaw at python.org Fri Jan 21 17:08:11 2000 From: bwarsaw at python.org (bwarsaw at python.org) Date: Fri, 21 Jan 2000 11:08:11 -0500 (EST) Subject: [Python-Dev] Python 1.6 timing References: <14472.28580.945266.658533@anthem.cnri.reston.va.us> Message-ID: <14472.33899.20409.602096@anthem.cnri.reston.va.us> >>>>> "GS" == Greg Stein writes: GS> I was under the impression that CVS access restrictions are GS> based on CNRI security policy. If the CVS repository moves GS> elsewhere, then many people can access it without impact on GS> CNRI's network and security policies. Well, access to our /internal/ network is of course restricted. CNRI employees have write access to the tree by virtue of access to the filesystem (i.e. by NFS). My current arrangement for external ssh mediated access to a writable cvs server on an internal machine is a hack and not something that I want to perpetuate if more users were added. GS> However, if the external access issue is based on legal GS> reasons (for example, only CNRI people should alter Python GS> code), then yes: moving the repository will buy nothing. I'll let Guido comment on policy concerning write access to the Python CVS tree. From a technical standpoint, if this is something Guido wanted to extend to non-CNRI employees, the way to do it would be to host the primary repository on a CNRI machine outside our firewall, e.g cvs.python.org. At that point, we'd be accessing the tree the same as anybody else. -Barry From gstein at lyra.org Fri Jan 21 17:19:33 2000 From: gstein at lyra.org (Greg Stein) Date: Fri, 21 Jan 2000 08:19:33 -0800 (PST) Subject: [Python-Dev] Python 1.6 timing In-Reply-To: <14472.33899.20409.602096@anthem.cnri.reston.va.us> Message-ID: On Fri, 21 Jan 2000 bwarsaw at python.org wrote: > >>>>> "GS" == Greg Stein writes: >... > From a technical standpoint, if this is something Guido > wanted to extend to non-CNRI employees, the way to do it would be to > host the primary repository on a CNRI machine outside our firewall, > e.g cvs.python.org. At that point, we'd be accessing the tree the > same as anybody else. Gotcha. Sounds great! I'm not sure yet that Guido is looking for external people to do checkins (as opposed to delivering refined patches to him)... So we probably don't need an assessment from the legal department :-), but if Guido already knows, then I'd be curious. thx! -g -- Greg Stein, http://www.lyra.org/ From paul at prescod.net Fri Jan 21 17:51:24 2000 From: paul at prescod.net (Paul Prescod) Date: Fri, 21 Jan 2000 08:51:24 -0800 Subject: [Python-Dev] Re: [Types-sig] namespaces (was: Changing existing class instances) References: Message-ID: <38888E8C.FE369A86@prescod.net> Greg Stein wrote: > Tim Peters: > > Trying to overload the current namespace set makes it so > > much harder to see that these are compile-time gimmicks, and users need to > > be acutely aware of that if they're to use it effectively. Note that I > > understand (& wholly agree with) the need for runtime introspection. > > And that is the crux of the issue: I think the names that are assigned to > these classes, interfaces, typedefs, or whatever, can follow the standard > Python semantics and be plopped into the appropriate namespace. There is > no overloading. This is indeed the crux of the issue. For those that missed it last time, it became very clear to me that we are working with radically different design aesthetics when we discussed the idea of having an optional keyword that said: "this thing is usually handled at compile time but I want to handle it at runtime. I know what I am doing." Greg complained that that would require the programmer to understand too much what was being done at compile time and what at runtime and what. >From my point of view this is *exactly* what a programmer *needs* to know and if we make it too hard for them to know it then we have failed. > There is no "overloading" of namespaces. We are using Python namespaces > just like they should be, and the type-checker doesn't even have to be all > the smart to track this stuff. There is an overloading of namespaces because we will separately specify the *compile time semantics* of these names. We need to separately specify these semantics because we need all compile time type checkers to behave identically. Yes, it seems elegant to make type objects seem as if they are "just like" Python objects. Unfortunately they aren't. Type objects are evaluated -- and accepted or rejected -- at compile time. Every programmer needs to understand that and it should be blatantly obvious in the syntax, just as everything else in Python syntax is blatantly obvious. -- Paul Prescod - ISOGEN Consulting Engineer speaking for himself Earth will soon support only survivor species -- dandelions, roaches, lizards, thistles, crows, rats. Not to mention 10 billion humans. - Planet of the Weeds, Harper's Magazine, October 1998 From skaller at maxtal.com.au Fri Jan 21 22:01:03 2000 From: skaller at maxtal.com.au (skaller) Date: Sat, 22 Jan 2000 08:01:03 +1100 Subject: [Python-Dev] Re: [Types-sig] namespaces (was: Changing existing class instances) References: <38888E8C.FE369A86@prescod.net> Message-ID: <3888C90F.BECA3FF6@maxtal.com.au> Paul Prescod wrote: > Yes, it seems elegant to make type objects seem as if they are "just > like" Python objects. Unfortunately they aren't. Yes they are. They even have a type, TypeType. -- John (Max) Skaller, mailto:skaller at maxtal.com.au 10/1 Toxteth Rd Glebe NSW 2037 Australia voice: 61-2-9660-0850 homepage: http://www.maxtal.com.au/~skaller download: ftp://ftp.cs.usyd.edu/au/jskaller From tim_one at email.msn.com Sun Jan 23 00:18:14 2000 From: tim_one at email.msn.com (Tim Peters) Date: Sat, 22 Jan 2000 18:18:14 -0500 Subject: [Python-Dev] Python 1.6 timing In-Reply-To: <000701bf636f$de37c5e0$c355cfc0@ski.org> Message-ID: <000401bf652e$f5266b60$132d153f@tim> [David Ascher] > ... > Regardless, just like Greg, I'd like to know what a > pumpkin-holder would mean in the Python world. > > I propose that it be called the Oracle instead. As in, > whoever is Oracle would get some training with Tim Peters > and learn how to channel G__do. I'm afraid that wouldn't work. The whole secret to channeling Guido in the *past* was to have been an ABC user: all you had to do is notice the things about ABC that you loved and the ones that would drive any sane *experienced* programmer mad with frustration. Voila! Guido's mind is your mind . But the more Python sails into uncharted waters, the less reliable my Guido-channeling pseudo-skills get. He is, in Essence, Unfathomable. Also indispensable. > As a Python user, I'd be most comfortable with such a change > if the Oracle just took over the technical stuff (reviewing > patches, CVS checkins, running tests, corralling help for > doc & code, maintaining release notes, building installers, > etc.), but that the important decisions (e.g. whether to add > a feature to the core language) would be checked with G__do > first. Definitely. But where do you find someone like that? It's (or at least *should* be) several full-time jobs. Languages like Icon & Scheme do it via university association (scads of grad student slave labor); REBOL did it by floating a trendy Internet business plan that actually attracted enough venture capital to hire about 30 people; Python, unfortunately , seems to attract people who already have demanding jobs. So I see it as an issue of finding warm bodies more than anything else. In the absence of funding "real jobs", I really don't see much hope. Bits & pieces can be farmed out (e.g., I doubt Guido has had to do any work on the regular expression code since Andrew arrived), but that's it -- I expect the past predicts the future quite accurately here. Certainly much more *could* be "farmed out", but no single volunteer of the kind Python has attracted so far is going to do a lot on their own month after month after month. Even with the best of intentions, their "real life" will interfere severely more often than not (voice of experience, there -- and I'd guess it's the same for *all* of us). if-something-doesn't-change-nothing-will-change-ly y'rs - tim From tim_one at email.msn.com Sun Jan 23 00:18:11 2000 From: tim_one at email.msn.com (Tim Peters) Date: Sat, 22 Jan 2000 18:18:11 -0500 Subject: Python 2 namespace change? (was Re: [Python-Dev] Changing existing class instances) In-Reply-To: <38871CE5.53FB9D68@digicool.com> Message-ID: <000301bf652e$f348d1c0$132d153f@tim> [Jim Fulton] > ... > A change to the way that namespaces are handled > could make this work and have a number of other benefits, > like global name usage without namespace lookups. > > I've suggested this to Guido in the past. His > reasonable response is that this would be too big a > change for Python 1. Maybe this is something to consider > for Python 2? > > The basic idea (borrowed from Smalltalk) is to have a kind > of dictionary that is a collection of "association" > objects. An association object is simply a pairing of a > name with a value. Association objects can be shared among > multiple namespaces. Jim, I've been intrigued by this idea for all the years you've been suggesting it , but I've never understood what it is you're proposing! This is the Python-Dev list, so feel encouraged to present it in concrete implementation terms instead of ambiguous English. Or maybe an interface? interface a_kind_of_dictionary_that_is_a_collection_of_\ association_objects: # ??? beats me ... Or maybe as a C struct? For example, is "an association object" a (char*, PyObject*) pair? Does this kind of dictionary have keys? If so, of what type? What type are the values? Best I can make sense of the above, the values are "association objects", each of which contains a name and a value, and a key is maybe a duplicate of the name in the association object to which it maps. "A name" may or may not be a string -- I can't tell. Or maybe by "dictionary" you didn't intend Python's current meaning for that word at all. I assume "a value" is a PyObject*. The whole thrust *appears* to be to get names to map to a PyObject** instead of PyObject*, but if that's the ticket I don't know what association objeects have to do with it. > An import like: > > from foo import spam > > would copy the association between the name 'foo' and a > value from module 'spam' into the current module. Where does the idea that 'spam' is a *module* here come from? It doesn't make sense to me, and I'm so lost I'll spare everyone my further confusions . suspecting-the-last-actually-doesn't-make-any-sense-ly y'rs - tim From tim_one at email.msn.com Sun Jan 23 00:29:45 2000 From: tim_one at email.msn.com (Tim Peters) Date: Sat, 22 Jan 2000 18:29:45 -0500 Subject: [Python-Dev] Python 1.6 timing (fwd) In-Reply-To: <38875DD1.B6596@tismer.com> Message-ID: <000701bf6530$90cc31c0$132d153f@tim> [hristian Tismer] > ... > Even better: Refcounting can lead to many new optimizations > if we pay the cost to make INCREF/DECREF into methods. It > has its cost (about 10 percent less pystones), but massive > long-term benefits. The GC patch Guido forced me to look at is based on the observation that it's impossible to create cyclic trash unless a decref leaves a nonzero refcount. So the patch adds a function call to the DECREF macro (if the new refcount is > 0, the object must be added to the set of "suspicious" objects; else the object must be removed from that set). So it roughly adds the cost of a method call to each decref anyway. You would think it adds less , but "the set" now is represented as a splay tree, so *gobs* of hairy code get executed in either case (splay trees do mutating rotations even on a lookup). > ... > Conclusion: I vote for a kind of GC that does just what > refcounts cannot do, but please keep with the refcounts. I like 'em too! BTW, Toby posted (at least an earlier version of) the patch to c.l.py, if anyone else wants to dig into it (I may have mentioned before that I'm short on time ). From tim_one at email.msn.com Sun Jan 23 05:59:38 2000 From: tim_one at email.msn.com (Tim Peters) Date: Sat, 22 Jan 2000 23:59:38 -0500 Subject: [Python-Dev] Changing existing class instances In-Reply-To: <14472.28540.765858.16133@anthem.cnri.reston.va.us> Message-ID: <000201bf655e$a6a49b80$732d153f@tim> [Barry A. Warsaw] > I completely agree. That's no fun . > I think in general, such long running apps are rare, By definition, they're non-existent under Windows <0.7 wink>. But it depends on which field you're working in. The closer you get to being part of a business or consumer service, the more important it gets; e.g., I've seen serious RFQs for software systems guaranteed to suffer no more than 5 minutes of downtime per *year* (& stiff penalties for failure to meet that). I've never been on the winning end of such an RFQ, so am not sure what it takes to meet it. It's interesting to ponder. Psion has published a little about the software techniques they use in their PDAs (my Psion 3a's remarkably capable "Agenda" app has been running non-stop for a bit over 3 years!). > and in those cases you probably want to be explicit about when > and how the updates occur anyway. My guess is you'd want to be *paranoidly* explicit, leaving nothing to chance. > The one place where automatic updates would be convenient would > be at the interactive prompt, so it might be nice to add a > module that could be imported by PYTHONSTARTUP, and play hook > games to enable automatic updates. Returning the favor, I completely agree. The single thing people at work gripe most about is how to do development under IDLE in such a way that their package-laden systems exhibit the hoped-for changes in response to editing a module deep in the bowels of the system. I don't have a *good* answer to that now; reduced to stuff like writing custom scripts to selectively clear out sys.modules. non-stop-ly y'rs - tim From bwarsaw at cnri.reston.va.us Sun Jan 23 16:07:26 2000 From: bwarsaw at cnri.reston.va.us (Barry A. Warsaw) Date: Sun, 23 Jan 2000 10:07:26 -0500 (EST) Subject: [Python-Dev] Python 1.6 timing References: <000701bf636f$de37c5e0$c355cfc0@ski.org> <000401bf652e$f5266b60$132d153f@tim> Message-ID: <14475.6446.336166.192186@anthem.cnri.reston.va.us> >>>>> "TP" == Tim Peters writes: TP> REBOL did it by floating a trendy Internet business plan that TP> actually attracted enough venture capital to hire about 30 TP> people; Python, unfortunately , seems to attract people TP> who already have demanding jobs. I think all we have to do is change the name for 1.6 to LinuxPython 2.0, then split off and go IPO. The more money we lose, the higher our stock will go and we can use our market cap to hire all those warm bodies. -Barry From jeremy at cnri.reston.va.us Sun Jan 23 19:54:40 2000 From: jeremy at cnri.reston.va.us (Jeremy Hylton) Date: Sun, 23 Jan 2000 13:54:40 -0500 (EST) Subject: [Python-Dev] Python 1.6 timing In-Reply-To: <000401bf652e$f5266b60$132d153f@tim> References: <000701bf636f$de37c5e0$c355cfc0@ski.org> <000401bf652e$f5266b60$132d153f@tim> Message-ID: <14475.20080.508651.261991@bitdiddle.cnri.reston.va.us> >>>>> "TP" == Tim Peters writes: TP> [David Ascher] >> I propose that it be called the Oracle instead. As in, whoever >> is Oracle would get some training with Tim Peters and learn how >> to channel G__do. TP> I'm afraid that wouldn't work. The whole secret to channeling TP> Guido in the *past* was to have been an ABC user: all you had to TP> do is notice the things about ABC that you loved and the ones TP> that would drive any sane *experienced* programmer mad with TP> frustration. Voila! Guido's mind is your mind . I have discovered another approach. CNRI put in a cleam room on the second floor last year. I recently discovered a little door behind some metrology device in a corner of the clean room. The door opens onto a tunnel that leads directly into Guido's mind. Unfortunately, it won't be of much use for a pumpkin-holder or channeler, because after about 15 minutes you are deposited on the shoulder of the Dulles Toll Road. who-wants-to-be-John-Malkovich-when-they-could-be-Guido-ly y'rs, Jeremy From skip at mojam.com Wed Jan 26 04:42:06 2000 From: skip at mojam.com (Skip Montanaro) Date: Tue, 25 Jan 2000 21:42:06 -0600 Subject: [Python-Dev] Multiple dicts for string interpolation? Message-ID: <200001260342.VAA10627@beluga.mojam.com> Every once in awhile I want to perform string interpolation using more than one dictionary. One way is to build a dictionary that's a union of multiple dictionaries: dict = {} dict.update(d1) dict.update(d2) ... s = format % dict Another way is the MultiDict approach that Digital Creations (used to?) use in their DocumentTemplate module (I can't remember the exact usage any more): dict = MultiDict() dict.append(d1) dict.append(d2) ... s = format % dict A MultiDict object maintains a list of the dicts it's been fed and searches them in order when __getitem__ is called. I'd like to propose a third alternative. How about if the string interpolation function accepted a tuple of dictionaries directly: s = format % (d1, d2) It would only be used when named interpolation was expected. I don't think there would be any conflict with current % operator semantics. Skip Montanaro | http://www.mojam.com/ skip at mojam.com | http://www.musi-cal.com/ 847-971-7098 From guido at CNRI.Reston.VA.US Wed Jan 26 05:13:28 2000 From: guido at CNRI.Reston.VA.US (Guido van Rossum) Date: Tue, 25 Jan 2000 23:13:28 -0500 Subject: [Python-Dev] Multiple dicts for string interpolation? In-Reply-To: Your message of "Tue, 25 Jan 2000 21:42:06 CST." <200001260342.VAA10627@beluga.mojam.com> References: <200001260342.VAA10627@beluga.mojam.com> Message-ID: <200001260413.XAA02813@eric.cnri.reston.va.us> > I'd like to propose a third alternative. How about if the string > interpolation function accepted a tuple of dictionaries directly: > > s = format % (d1, d2) > > It would only be used when named interpolation was expected. I don't think > there would be any conflict with current % operator semantics. Gut feeling: it's dangerous to fill up every possible dark corner with specific semantics that are occasionally useful, because if you go too far you lose useful redundancy, and you end up with Perl. Not sure whether this particular suggestion is "going too far." I think it depends on to what extent this is a common, useful idiom. Do you have evidence of that? Examples? --Guido van Rossum (home page: http://www.python.org/~guido/) From skip at mojam.com Wed Jan 26 05:38:53 2000 From: skip at mojam.com (Skip Montanaro) Date: Tue, 25 Jan 2000 22:38:53 -0600 (CST) Subject: [Python-Dev] Multiple dicts for string interpolation? In-Reply-To: <200001260413.XAA02813@eric.cnri.reston.va.us> References: <200001260342.VAA10627@beluga.mojam.com> <200001260413.XAA02813@eric.cnri.reston.va.us> Message-ID: <14478.31325.891846.701373@beluga.mojam.com> >> I'd like to propose a third alternative. How about if the string >> interpolation function accepted a tuple of dictionaries directly: >> >> s = format % (d1, d2) Guido> Gut feeling: it's dangerous to fill up every possible dark corner Guido> with specific semantics that are occasionally useful, because if Guido> you go too far you lose useful redundancy, and you end up with Guido> Perl. Yeah, I am kind of taking advantage of the fact that the format operator doesn't happen to use tuples of dicts already, though this seems like a natural extension of the current semantics. Currently, you can have Style of Simple form Complex form Interpolation ------- ----------- ------------ sprintf string tuple of strings named dict tuple of dicts It does complicate the decision making process in the string format routine a bit. Guido> I think it depends on to what extent this is a common, useful Guido> idiom. Do you have evidence of that? Examples? Well, the first place I ran into it was in DocumentTemplates a few years ago. They used an idiom heavily which may have now been replaced by acquisition where you'd effectively push and pop value dicts onto a stack as you entered and exited nested blocks of DTML code. Their solution was a special dict-like object. The example that made the light click for me this evening was having an object whose class dict stores constants and whose instant dict stores varying values. It seemed cleaner to me to do obj = Class() ... s = format % (Class.__dict__, obj.__dict__) than go through the intermediate step of building a separate dict which would just get discarded as soon as this bit of string building was complete. (I will perform this once for each of several thousand instances.) It's not a big deal. If it seems too obscure the other obvious solutions are not gruesome. Skip From skip at mojam.com Wed Jan 26 05:40:20 2000 From: skip at mojam.com (Skip Montanaro) Date: Tue, 25 Jan 2000 22:40:20 -0600 (CST) Subject: [Python-Dev] Multiple dicts for string interpolation? In-Reply-To: <14478.31325.891846.701373@beluga.mojam.com> References: <200001260342.VAA10627@beluga.mojam.com> <200001260413.XAA02813@eric.cnri.reston.va.us> <14478.31325.891846.701373@beluga.mojam.com> Message-ID: <14478.31412.36960.440988@beluga.mojam.com> Oh crap... Of course, the table should have been Style of Simple form Complex form Interpolation ------- ----------- ------------ sprintf string tuple of strings named dict (empty fourth cell...) Skip From klm at digicool.com Wed Jan 26 06:01:36 2000 From: klm at digicool.com (Ken Manheimer) Date: Wed, 26 Jan 2000 00:01:36 -0500 (EST) Subject: [Python-Dev] Multiple dicts for string interpolation? In-Reply-To: <14478.31325.891846.701373@beluga.mojam.com> Message-ID: On Tue, 25 Jan 2000, Skip Montanaro wrote: > Guido> Skip: > >> I'd like to propose a third alternative. How about if the string > >> interpolation function accepted a tuple of dictionaries directly: > >> > >> s = format % (d1, d2) > [...] > Guido> I think it depends on to what extent this is a common, useful > Guido> idiom. Do you have evidence of that? Examples? > > Well, the first place I ran into it was in DocumentTemplates a few years > ago. They used an idiom heavily which may have now been replaced by > acquisition where you'd effectively push and pop value dicts onto a stack as > you entered and exited nested blocks of DTML code. Their solution was a > special dict-like object. Implementation of acquisition basically uses a MultiDict underneath. Consider acquisition as a cumulative context composed from the containers of the target of a web request. (Actually, a distinction is made between the object containment hierarchy of the target and the successive components of the path along which the target is reached by the request, with the containment contexts taking precedence - but that's probably not important here:-) Add in incidental things like the server environment (from which you can get HTTP_REFERER and cookies and so forth). Each of the components can be a dictionary or a MultiDict (or a sequence of pairs, i think), and they're ultimately composed in a MultiDict. I think another place in zope where multidicts play prominently is in the security mechanism, where any object can have local roles, and the ultimate role of a user within a context is composed from the union across the containment hierarchy. There probably are lots of other places where multidicts are used. Suffice to say that there's a lot of composing of contexts that goes on in Zope in general, acquistion being a prime example but not the only one, and multidicts play heavily in many. I would be surprised if this need to combine contexts is peculiar to web server, or general server applications. > [...] > It's not a big deal. If it seems too obscure the other obvious solutions > are not gruesome. I suppose we'd be pretty happy to have something like MultiDict as part of python... Ken klm at digicool.com (Who's the only one left in fredericksburg to speak up, at the moment:-) From tim_one at email.msn.com Wed Jan 26 06:39:19 2000 From: tim_one at email.msn.com (Tim Peters) Date: Wed, 26 Jan 2000 00:39:19 -0500 Subject: [Python-Dev] Multiple dicts for string interpolation? In-Reply-To: <200001260413.XAA02813@eric.cnri.reston.va.us> Message-ID: <000101bf67bf$b103e460$592d153f@tim> [Skip, wants to interpolate multiple dicts via "%", suggests passing a tuple of dicts: format % (d1, d2, ...)] [Guido] > ... > I think it depends on to what extent this is a common, useful > idiom. Do you have evidence of that? Examples? You yourself raised one last century : simply wanting to interpolate from both locals() and globals(). At the time, the idea of a new dict-like mapping object (capturing Python's lookup rules) appealed to you. I still like that, and note that the apparent need becomes more acute if "deep nesting" is ever added. I wasn't aware of the MultiDict approach Skip mentioned, but thought it looked spot on for the general case! Skip, is the long-windedness of dict = MultiDict() dict.append(d1) dict.append(d2) ... s = format % dict the part you didn't like about that? If so, how about changing the constructor to def __init__(self, *dicts): ... instead so you could use it as a one-liner format % MultiDict(d1, d2, ...) ? That's exactly the same as the tuple idea, except there's a nice descriptive word in the middle of it . From jack at oratrix.nl Wed Jan 26 10:56:18 2000 From: jack at oratrix.nl (Jack Jansen) Date: Wed, 26 Jan 2000 10:56:18 +0100 Subject: [Python-Dev] Multiple dicts for string interpolation? In-Reply-To: Message by "Tim Peters" , Wed, 26 Jan 2000 00:39:19 -0500 , <000101bf67bf$b103e460$592d153f@tim> Message-ID: <20000126095619.DC67D36E440@snelboot.oratrix.nl> > the part you didn't like about that? If so, how about changing the > constructor to > > def __init__(self, *dicts): > ... > > instead so you could use it as a one-liner > > format % MultiDict(d1, d2, ...) > > ? That's exactly the same as the tuple idea, except there's a nice > descriptive word in the middle of it . I've always wonderer why dict+dict isn't supported (or possibly dict|dict, if the key-collision semantics of + on dict are seen as a problem). Is there a good reason for this, or is it just that there are other more important things to implement? This wouldn't be a replacement for all uses of MultiDict, as it would probably have to create a new dict to keep semantics in line with those of list+list -- Jack Jansen | ++++ stop the execution of Mumia Abu-Jamal ++++ Jack.Jansen at oratrix.com | ++++ if you agree copy these lines to your sig ++++ www.oratrix.nl/~jack | see http://www.xs4all.nl/~tank/spg-l/sigaction.htm From guido at CNRI.Reston.VA.US Wed Jan 26 13:41:45 2000 From: guido at CNRI.Reston.VA.US (Guido van Rossum) Date: Wed, 26 Jan 2000 07:41:45 -0500 Subject: [Python-Dev] Multiple dicts for string interpolation? In-Reply-To: Your message of "Wed, 26 Jan 2000 10:56:18 +0100." <20000126095619.DC67D36E440@snelboot.oratrix.nl> References: <20000126095619.DC67D36E440@snelboot.oratrix.nl> Message-ID: <200001261241.HAA03001@eric.cnri.reston.va.us> [Tim] > > format % MultiDict(d1, d2, ...) > > > > ? That's exactly the same as the tuple idea, except there's a nice > > descriptive word in the middle of it . Nice. [Jack] > I've always wonderer why dict+dict isn't supported (or possibly > dict|dict, if the key-collision semantics of + on dict are seen as a > problem). Is there a good reason for this, or is it just that there > are other more important things to implement? The reason is that + (or |) looks symmetrical, but for the key collisions, one of them has to lose. We now have dict1.update(dict2), which is a bit more cumbersome, but makes it much clearer who is the loser. --Guido van Rossum (home page: http://www.python.org/~guido/) From skip at mojam.com Wed Jan 26 15:30:09 2000 From: skip at mojam.com (Skip Montanaro) Date: Wed, 26 Jan 2000 08:30:09 -0600 (CST) Subject: [Python-Dev] Multiple dicts for string interpolation? In-Reply-To: <000101bf67bf$b103e460$592d153f@tim> References: <200001260413.XAA02813@eric.cnri.reston.va.us> <000101bf67bf$b103e460$592d153f@tim> Message-ID: <14479.1265.213769.810138@beluga.mojam.com> Tim> Skip, is the long-windedness of Tim> dict = MultiDict() Tim> dict.append(d1) Tim> dict.append(d2) Tim> ... Tim> s = format % dict Tim> the part you didn't like about that? If so, how about changing the Tim> constructor to Tim> def __init__(self, *dicts): Tim> ... Tim> instead so you could use it as a one-liner Tim> format % MultiDict(d1, d2, ...) Tim> ? That's exactly the same as the tuple idea, except there's a nice Tim> descriptive word in the middle of it . The long-windedness was part of it. The performance hit of composing dictionaries thousands of times to perform a single format operation was also a consideration. Okay, side excursion into the Zope source tree... What I was calling MultiDict is actually MultiMapping (written in C, BTW). As a side effect of my Zope install here, I even already have it in sys.path (go figure!). And it turns out to work just as Tim surmised: >>> d1 = {"a": 1} >>> d2 = {"b": 2} >>> d = MultiMapping.MultiMapping(d1, d2) >>> d["b"] 2 >>> d["a"] 1 Dang! Turns out Jim Fulton has a time machine also. I guess the next question is to extend Ken's comment about getting it into the Python core. Would that be something possible for 1.6? I used a Python version of MultiMapping in an ancient version of DocumentTemplate. I'm sure the C version has been around for at least two or three years and would appear pretty darn stable, since it seems to be at the core of a lot of Zope's coolness. Skip From ping at lfw.org Thu Jan 27 08:06:01 2000 From: ping at lfw.org (Ka-Ping Yee) Date: Wed, 26 Jan 2000 23:06:01 -0800 (PST) Subject: [Python-Dev] Multiple dicts for string interpolation? In-Reply-To: <14478.31325.891846.701373@beluga.mojam.com> Message-ID: On Tue, 25 Jan 2000, Skip Montanaro wrote: > > Guido> I think it depends on to what extent this is a common, useful > Guido> idiom. Do you have evidence of that? Examples? > > Well, the first place I ran into it was in DocumentTemplates a few years > ago. They used an idiom heavily which may have now been replaced by > acquisition where you'd effectively push and pop value dicts onto a stack as > you entered and exited nested blocks of DTML code. Their solution was a > special dict-like object. That's really interesting. I wrote a bunch of Python wrappers for a UI toolkit a little while ago, and there were two main pieces of machinery i built to make the toolkit pleasant to use: 1. a reasonably nice C++ extension class kit (this is where i tried overloading operator new for the first time, so it would allocate memory that could be freed by PyMem_DEL -- i don't know if CXX uses the same approach) 2. a second layer of Python wrapper classes for the extension classes that implements extra methods in Python, and maintains a hierarchy of default keyword argument values along the inheritance hierarchy of widgets The second of these things involved implementing exactly the kind of dictionary stack that you mentioned. The programming idiom for building widgets goes something like: defaultstack = {} # maps class object to list of defaults dictionaries class Label(Component): defaults = _dict(text="Label", align=LEFT) class Button(Label): defaults = _dict(text="Button", align=CENTER, shadow=2) ... w = Window(...) Button.push(fg="white", bg="red", font="-*-courier-bold-r-normal--14-*-*-*-*-*-*-*") a = Button(w, text="one") b = Button(w, text="two") c = Button(w, text="three") Button.pop() This way you can install some options for a while and make a bunch of widgets with your defaults, then pop the options and go back to the previous state. The layers of dictionaries that get composed in every widget's __init__ function are (in order of priority): 1. any non-None keyword arguments to __init__ 2. any non-None values in class.defaults 3. any non-None values in class.__bases__[0].defaults 4. any non-None values in class.__bases__[0].__bases__[0].defaults etc. When a new set of defaults is push()ed, the class's current defaults are saved on the defaultstack for the class, and restored when pop() gets called. I don't *know* if this is really the best way to do things, but it has seemed to work out pretty well in practice. It makes it more convenient to deal with all the options you have to throw around especially when doing UI stuff. Anyway, i noticed the same sort of thing today while wondering about using keyword arguments for HTML tag attributes. (Perhaps HTMLgen does this sort of thing already -- sorry i haven't looked at it.) Anyway, the following sort of helper might be useful in general: class Default: def __init__(self, cl, **defaults): self.cl = cl self.defaults = defaults def __call__(self, *args, **kw): for key, value in self.defaults: if not kw.has_key(key): kw[key] = value return apply(self.cl, args, kw) Then you could do the same thing as above with: MyButton = Default(Button, fg="white", bg="red", font="-*-courier-bold-r-normal--14-*-*-*-*-*-*-*") a = MyButton(w, text="one") b = MyButton(w, text="two") c = MyButton(w, text="three") This is probably a cleaner way to do things. I haven't tried it, but it might be a nice thing to have in Tkinter. -- ?!ng From ping at lfw.org Fri Jan 28 05:36:49 2000 From: ping at lfw.org (Ka-Ping Yee) Date: Thu, 27 Jan 2000 20:36:49 -0800 (PST) Subject: [Python-Dev] Python 1.6 timing In-Reply-To: <14475.20080.508651.261991@bitdiddle.cnri.reston.va.us> Message-ID: On Sun, 23 Jan 2000, Jeremy Hylton wrote: > > I have discovered another approach. CNRI put in a cleam room on the > second floor last year. I recently discovered a little door behind > some metrology device in a corner of the clean room. The door opens > onto a tunnel that leads directly into Guido's mind. Unfortunately, > it won't be of much use for a pumpkin-holder or channeler, because > after about 15 minutes you are deposited on the shoulder of the Dulles > Toll Road. I almost fell out of my chair laughing when i read this. What do you think would happen if Guido went into the tunnel? Perhaps http://www.lfw.org/jminc/Guido/http://www.python.org/ (What you get is a generalization of some earlier silliness... the description of the original is at http://www.lfw.org/jminc/.) -- ?!ng From jim at digicool.com Fri Jan 28 16:02:12 2000 From: jim at digicool.com (Jim Fulton) Date: Fri, 28 Jan 2000 10:02:12 -0500 Subject: [Python-Dev] Multiple dicts for string interpolation? References: <200001260342.VAA10627@beluga.mojam.com> Message-ID: <3891AF74.1E81D7F8@digicool.com> Skip Montanaro wrote: > > Every once in awhile I want to perform string interpolation using more than > one dictionary. One way is to build a dictionary that's a union of multiple > dictionaries: > > dict = {} > dict.update(d1) > dict.update(d2) > ... > s = format % dict > > Another way is the MultiDict approach that Digital Creations (used to?) use > in their DocumentTemplate module (I can't remember the exact usage any > more): > > dict = MultiDict() > dict.append(d1) > dict.append(d2) Actually, push (and pop). The namspaces are managed as a stack. > ... > s = format % dict > > A MultiDict object maintains a list of the dicts it's been fed and searches > them in order when __getitem__ is called. > > I'd like to propose a third alternative. How about if the string > interpolation function accepted a tuple of dictionaries directly: > > s = format % (d1, d2) > > It would only be used when named interpolation was expected. I don't think > there would be any conflict with current % operator semantics. Yes. In the current semantics, you output the two dictionaries. Try: '%s %s' % ({'hello':'skip'},{}) Jim -- Jim Fulton mailto:jim at digicool.com Python Powered! Technical Director (888) 344-4332 http://www.python.org Digital Creations http://www.digicool.com http://www.zope.org Under US Code Title 47, Sec.227(b)(1)(C), Sec.227(a)(2)(B) This email address may not be added to any commercial mail list with out my permission. Violation of my privacy with advertising or SPAM will result in a suit for a MINIMUM of $500 damages/incident, $1500 for repeats. From jim at digicool.com Fri Jan 28 16:07:24 2000 From: jim at digicool.com (Jim Fulton) Date: Fri, 28 Jan 2000 10:07:24 -0500 Subject: [Python-Dev] Multiple dicts for string interpolation? References: Message-ID: <3891B0AC.D39275DF@digicool.com> Ken Manheimer wrote: > > On Tue, 25 Jan 2000, Skip Montanaro wrote: > > > Guido> Skip: > > >> I'd like to propose a third alternative. How about if the string > > >> interpolation function accepted a tuple of dictionaries directly: > > >> > > >> s = format % (d1, d2) > > [...] > > Guido> I think it depends on to what extent this is a common, useful > > Guido> idiom. Do you have evidence of that? Examples? > > > > Well, the first place I ran into it was in DocumentTemplates a few years > > ago. They used an idiom heavily which may have now been replaced by > > acquisition where you'd effectively push and pop value dicts onto a stack as > > you entered and exited nested blocks of DTML code. Their solution was a > > special dict-like object. > > Implementation of acquisition basically uses a MultiDict underneath. No it doesn't. Acquisition achieves combination of multiple namespaces in much the same way that inheritence does (through delagation). > Consider acquisition as a cumulative context composed from the containers > of the target of a web request. (Actually, a distinction is made between > the object containment hierarchy of the target and the successive > components of the path along which the target is reached by the request, > with the containment contexts taking precedence - but that's probably not > important here:-) Add in incidental things like the server environment > (from which you can get HTTP_REFERER and cookies and so forth). Each of > the components can be a dictionary or a MultiDict (or a sequence of pairs, > i think), and they're ultimately composed in a MultiDict. > > I think another place in zope where multidicts play prominently is in the > security mechanism, where any object can have local roles, and the > ultimate role of a user within a context is composed from the union across > the containment hierarchy. There probably are lots of other places where > multidicts are used. Acquisition plays a role in security, but MultiDicts-like things are not used. > Suffice to say that there's a lot of composing of contexts that goes on in > Zope in general, acquistion being a prime example but not the only one, > and multidicts play heavily in many. I would be surprised if this need to > combine contexts is peculiar to web server, or general server > applications. > > > [...] > > It's not a big deal. If it seems too obscure the other obvious solutions > > are not gruesome. > > I suppose we'd be pretty happy to have something like MultiDict as part of > python... Note that Zope actually uses two separate flavors. The one used most in Zope (in DocumentTemplate) has very specific hooks to work with Zope's security machinery. Jim -- Jim Fulton mailto:jim at digicool.com Python Powered! Technical Director (888) 344-4332 http://www.python.org Digital Creations http://www.digicool.com http://www.zope.org Under US Code Title 47, Sec.227(b)(1)(C), Sec.227(a)(2)(B) This email address may not be added to any commercial mail list with out my permission. Violation of my privacy with advertising or SPAM will result in a suit for a MINIMUM of $500 damages/incident, $1500 for repeats. From jim at digicool.com Fri Jan 28 16:10:26 2000 From: jim at digicool.com (Jim Fulton) Date: Fri, 28 Jan 2000 10:10:26 -0500 Subject: [Python-Dev] Multiple dicts for string interpolation? References: <000101bf67bf$b103e460$592d153f@tim> Message-ID: <3891B162.554622E2@digicool.com> Tim Peters wrote: > (snip) > I wasn't aware of the MultiDict approach Skip mentioned, See the MultiMapping module in ExtensionClass. You can get the latest flavor of this in the latest Zope release. > but thought it > looked spot on for the general case! Skip, is the long-windedness of > > dict = MultiDict() > dict.append(d1) > dict.append(d2) > ... > s = format % dict Note the rather important *stack* sematics of MultiMappings. We often push and pop namespaces on and off of MultiMappings in use. > the part you didn't like about that? If so, how about changing the > constructor to > > def __init__(self, *dicts): > ... > > instead so you could use it as a one-liner > > format % MultiDict(d1, d2, ...) > > ? That's exactly the same as the tuple idea, except there's a nice > descriptive word in the middle of it . This is exactly what the current MultiMapping "class" does. Jim -- Jim Fulton mailto:jim at digicool.com Python Powered! Technical Director (888) 344-4332 http://www.python.org Digital Creations http://www.digicool.com http://www.zope.org Under US Code Title 47, Sec.227(b)(1)(C), Sec.227(a)(2)(B) This email address may not be added to any commercial mail list with out my permission. Violation of my privacy with advertising or SPAM will result in a suit for a MINIMUM of $500 damages/incident, $1500 for repeats. From gward at cnri.reston.va.us Fri Jan 28 17:39:54 2000 From: gward at cnri.reston.va.us (Greg Ward) Date: Fri, 28 Jan 2000 11:39:54 -0500 Subject: [Python-Dev] To-do for Distutils 0.2 (and beyond) Message-ID: <20000128113954.A12965@cnri.reston.va.us> Hi all -- [oops: I *said* that I was cc'ing this to python-dev when I posted it to distutils-sig, but I just plain forgot to. So here it is again, still presumed relevant to python-dev'ers because it directly affects the planned Python 1.6 feature set. Please reply either to me directly or to distutils-sig, because that's where the implementation will be done.] recent developments in the planned release schedule for Python 1.6 (Guido doesn't want to wait for everything planned, but get something out the door in the next couple of months) are lighting a fire under me to get a seriously usable version of Distutils ready *really* soon now. This will be Distutils 0.2; I anticipate that 0.2.x will be included in Python 1.6, where x is the number of attempts it takes me to get something reasonably bug-free out the door. Those if you who were at the Python Conference this past week will have seen bits and pieces of my "laundry list" of desired features that should be added to the Distutils at some point in the future. Given the shortened schedule, it looks like it's necessary to do some pruning and concentrate on the essentials to get something in Python 1.6. So, here is my current laundry list, sorted into a couple of categories: essential for 0.2 (Python 1.6) ----------------- * fix the "dist" command (two-phase manifest, better feedback) (steal ideas and hopefully code from Gordon Macmillan's installer) * fix the "install" command (have the right interface and do the right thing for installating to non-standard or personal directories) * fix some bad nomenclature in the command classes (most likely 'options' -> 'user_options', 'set_default_options()' -> 'initialize_options()', and 'set_final_options()' -> ??? (maybe 'finalize_options()'?)) * build C libraries (for PIL, and other similar distributions) * documentation (two small manuals that should become standard Python manuals: "Installing Python Modules" and "Developing and Distributing Python Modules") * add a bdist command; should at least be able to generate dumb archives of built distributions (eg. a tarball that you unpack from /usr/local, or maybe /usr/local/lib/python1.5/site-packages) desirable for 0.2 ----------------- * "what's installed" database * dependency checking ("is version 1.3 of foo installed?") * don't automatically clobber an existing installation -- confirm, or require a "force" option, or something * command to install C headers (assuming more extensions than NumPy need to do this) put off to 0.3 (Python 1.7?) ---------------------------- * JPython support (most importantly, know where to install .py modules when run from JPython and be able to build Java extensions for JPython) * build static Python binary (for shared-library-challenged OSs) * SWIG support (mainly, know how to run it before building the C extension it generates) * PyFort support (ditto) * Mac support * allow overlapping multi-architecture installations (Michel Sanner's pet peeve and Guido's nightmare ;-) (this would *not* be the default; it would have to be explicitly chosen by brave/cheap/foolhardy installers) * support for archive sites (Parnassus) to pull out meta-info Anyone feel strongly about moving any of these items around, or discarding any entirely, or adding anything? Please let me know by email; I'll summarize to the list. Thanks -- Greg From jeremy at cnri.reston.va.us Sat Jan 29 00:52:53 2000 From: jeremy at cnri.reston.va.us (Jeremy Hylton) Date: Fri, 28 Jan 2000 18:52:53 -0500 (EST) Subject: [Python-Dev] To-do for Distutils 0.2 (and beyond) In-Reply-To: <20000128113954.A12965@cnri.reston.va.us> References: <20000128113954.A12965@cnri.reston.va.us> Message-ID: <14482.11221.451866.695357@bitdiddle.cnri.reston.va.us> >>>>> "GW" == Greg Ward writes: GW> desirable for 0.2 GW> ----------------- GW> * "what's installed" database GW> * dependency checking ("is version 1.3 of foo installed?") These are *not* desirable for version 0.2. Paul Dubois expressed some concern about the complexity of these tasks. I agree completely. I think the chances of getting this done correctly in the next month are slim to none. Don't waste your time adding the kitchen sink to distutils :-); just bang on the simple stuff until it's rock solid. Jeremy From jim at digicool.com Sat Jan 29 02:40:22 2000 From: jim at digicool.com (Jim Fulton) Date: Fri, 28 Jan 2000 20:40:22 -0500 Subject: [Python-Dev] Multiple dicts for string interpolation? References: <200001260413.XAA02813@eric.cnri.reston.va.us> <000101bf67bf$b103e460$592d153f@tim> <14479.1265.213769.810138@beluga.mojam.com> Message-ID: <38924506.808D34F5@digicool.com> Skip Montanaro wrote: > (snip) > I guess the next question is to extend Ken's comment about getting it into > the Python core. Would that be something possible for 1.6? I used a Python > version of MultiMapping in an ancient version of DocumentTemplate. I'm sure > the C version has been around for at least two or three years and would > appear pretty darn stable, Yes. I'm sure you'd have to de-ExtensionClass-ify it to get it into the core. :) > since it seems to be at the core of a lot of > Zope's coolness. Actually, it isn't, as there is a separate similar thing (TemplateDict) used in DocumentTemplate. Jim -- Jim Fulton mailto:jim at digicool.com Python Powered! Technical Director (888) 344-4332 http://www.python.org Digital Creations http://www.digicool.com http://www.zope.org Under US Code Title 47, Sec.227(b)(1)(C), Sec.227(a)(2)(B) This email address may not be added to any commercial mail list with out my permission. Violation of my privacy with advertising or SPAM will result in a suit for a MINIMUM of $500 damages/incident, $1500 for repeats. From guido at CNRI.Reston.VA.US Sun Jan 30 14:32:18 2000 From: guido at CNRI.Reston.VA.US (Guido van Rossum) Date: Sun, 30 Jan 2000 08:32:18 -0500 Subject: [Python-Dev] Adding C ternary select (a?b:c) to Python? Message-ID: <200001301332.IAA12252@eric.cnri.reston.va.us> Dear developers, Eric Raymond has sent me the following patch, which adds conditional expressions to Python. I'd like to hear opinions on whether this is a good thing to add to Python, and whether this is the right syntax. I am a bit skeptical about whether this is sufficiently Pythonic, but on the other hand there have always been requests for such a feature, and the existing solutions are ugly: a and b or c only works when you know for sure that b will never be false, and (a and [b] or [c])[0] is dead ugly... --Guido van Rossum (home page: http://www.python.org/~guido/) Subject: Ternary select -- here it is. From: "Eric S. Raymond" To: Guido Van Rossum Date: Sat, 29 Jan 2000 17:40:31 -0500 X-Eric-Conspiracy: There is no conspiracy Dang, Guido, this was *fun*! This patch extends the Python interpreter to support the C ternary operator, and documents the extension in the Reference Manual. The implementation is dead simple and robust: it's adapted from the existing code for if statements, and adds or changes less than 70 lines of code all told. Diffs between last version checked in and current workfile(s): --- Grammar/Grammar 2000/01/28 17:10:18 1.1 +++ Grammar/Grammar 2000/01/29 22:14:05 @@ -61,7 +61,8 @@ except_clause: 'except' [test [',' test]] suite: simple_stmt | NEWLINE INDENT stmt+ DEDENT -test: and_test ('or' and_test)* | lambdef +test: bool_test ['?' bool_test ':' bool_test] +bool_test: and_test ('or' and_test)* | lambdef and_test: not_test ('and' not_test)* not_test: 'not' not_test | comparison comparison: expr (comp_op expr)* --- Include/token.h 2000/01/28 17:38:55 1.1 +++ Include/token.h 2000/01/29 01:27:00 @@ -74,10 +74,11 @@ #define LEFTSHIFT 34 #define RIGHTSHIFT 35 #define DOUBLESTAR 36 +#define QUERY 37 /* Don't forget to update the table _PyParser_TokenNames in tokenizer.c! */ -#define OP 37 -#define ERRORTOKEN 38 -#define N_TOKENS 39 +#define OP 38 +#define ERRORTOKEN 39 +#define N_TOKENS 34 /* Special definitions for cooperation with parser */ --- Modules/parsermodule.c 2000/01/28 18:03:27 1.1 +++ Modules/parsermodule.c 2000/01/29 22:13:45 @@ -945,6 +945,7 @@ #define validate_star(ch) validate_terminal(ch, STAR, "*") #define validate_vbar(ch) validate_terminal(ch, VBAR, "|") #define validate_doublestar(ch) validate_terminal(ch, DOUBLESTAR, "**") +#define validate_query(ch) validate_terminal(ch, QUERY, "?") #define validate_dot(ch) validate_terminal(ch, DOT, ".") #define validate_name(ch, str) validate_terminal(ch, NAME, str) @@ -963,7 +964,8 @@ VALIDATER(exec_stmt); VALIDATER(compound_stmt); VALIDATER(while); VALIDATER(for); VALIDATER(try); VALIDATER(except_clause); -VALIDATER(test); VALIDATER(and_test); +VALIDATER(test); +VALIDATER(bool_test); VALIDATER(and_test); VALIDATER(not_test); VALIDATER(comparison); VALIDATER(comp_op); VALIDATER(expr); VALIDATER(xor_expr); VALIDATER(and_expr); @@ -1829,12 +1831,34 @@ } /* validate_except_clause() */ +/* bool_test ( | bool_test ? bool_test ) + * + */ static int validate_test(tree) node *tree; { + if (!validate_ntype(tree, test)) + return 0; + else if (NCH(tree) == 1) + return(validate_bool_test(CHILD(tree, 0))); + else if (validate_numnodes(tree, 5, "expr")) + { + return validate_bool_test(CHILD(tree, 0)) + && validate_query(CHILD(tree, 1)) + && validate_bool_test(CHILD(tree, 2)) + && validate_colon(CHILD(tree, 3)) + && validate_bool_test(CHILD(tree, 4)); + } +} /* validate_test() */ + + +static int +validate_bool_test(tree) + node *tree; +{ int nch = NCH(tree); - int res = validate_ntype(tree, test) && is_odd(nch); + int res = validate_ntype(tree, bool_test) && is_odd(nch); if (res && (TYPE(CHILD(tree, 0)) == lambdef)) res = ((nch == 1) @@ -1848,7 +1872,7 @@ } return (res); -} /* validate_test() */ +} /* validate_bool_test() */ static int --- Parser/tokenizer.c 2000/01/28 17:37:48 1.1 +++ Parser/tokenizer.c 2000/01/29 01:27:26 @@ -99,6 +99,7 @@ "LEFTSHIFT", "RIGHTSHIFT", "DOUBLESTAR", + "QUERY", /* This table must match the #defines in token.h! */ "OP", "", @@ -384,6 +385,7 @@ case '}': return RBRACE; case '^': return CIRCUMFLEX; case '~': return TILDE; + case '?': return QUERY; default: return OP; } } --- Python/compile.c 2000/01/28 23:17:19 1.1 +++ Python/compile.c 2000/01/29 22:19:29 @@ -1698,11 +1698,11 @@ } static void -com_test(c, n) +com_bool_test(c, n) struct compiling *c; node *n; { - REQ(n, test); /* and_test ('or' and_test)* | lambdef */ + REQ(n, bool_test); /* and_test ('or' and_test)* | lambdef */ if (NCH(n) == 1 && TYPE(CHILD(n, 0)) == lambdef) { PyObject *v; int i; @@ -1738,6 +1738,32 @@ } static void +com_test(c, n) + struct compiling *c; + node *n; +{ + int op; + REQ(n, test); + com_bool_test(c, CHILD(n, 0)); + + /* is there a following ternary operator? */ + /* XXX optimize the compilation when the guard is a constant */ + if (NCH(n) == 5) + { + int anchor1 = 0, anchor2 = 0; + com_addfwref(c, JUMP_IF_FALSE, &anchor2); + com_addbyte(c, POP_TOP); + com_pop(c, 1); + com_node(c, CHILD(n, 2)); + com_addfwref(c, JUMP_FORWARD, &anchor1); + com_backpatch(c, anchor2); + com_addbyte(c, POP_TOP); + com_node(c, CHILD(n, 4)); + com_backpatch(c, anchor1); + } +} + +static void com_list(c, n, toplevel) struct compiling *c; node *n; @@ -2931,6 +2957,9 @@ break; case test: com_test(c, n); + break; + case bool_test: + com_bool_test(c, n); break; case and_test: com_and_test(c, n); --- Doc/ref/ref5.tex 2000/01/29 21:28:13 1.1 +++ Doc/ref/ref5.tex 2000/01/29 22:00:02 @@ -764,7 +764,7 @@ \section{Boolean operations\label{Booleans}} \indexii{Boolean}{operation} -Boolean operations have the lowest priority of all Python operations: +Boolean operations have the lowest priority of all Python binary operations: \begin{verbatim} expression: or_test | lambda_form @@ -832,6 +832,24 @@ def make_incrementor(increment): return lambda x, n=increment: x+n \end{verbatim} + +\section{Select\label{select}} +\index{select} + +The select operator is a ternary operator with lower priority than +boolean operations (and thus lower priority than all other binary and +unary operators). + +\begin{verbatim} +select_expr: xor_expr | xor_expr "?" xor_expr ":" xor_expr +\end{verbatim} + +If its first operand is nonempty, the value of a select operation is +its second operand; otherwise the value is the third operand. + +(The semantics and precedence level of select are intended to be +unsurprising to programmers familiar with \C's ternary select +operator.) \section{Expression lists\label{exprlists}} \indexii{expression}{list} End of diffs. -- Eric S. Raymond You know why there's a Second Amendment? In case the government fails to follow the first one. -- Rush Limbaugh, in a moment of unaccustomed profundity 17 Aug 1993 From jim at digicool.com Sun Jan 30 14:52:32 2000 From: jim at digicool.com (Jim Fulton) Date: Sun, 30 Jan 2000 08:52:32 -0500 Subject: [Python-Dev] Adding C ternary select (a?b:c) to Python? References: <200001301332.IAA12252@eric.cnri.reston.va.us> Message-ID: <38944220.3177B402@digicool.com> Guido van Rossum wrote: > > Dear developers, > > Eric Raymond has sent me the following patch, which adds conditional > expressions to Python. I'd like to hear opinions on whether this is a > good thing to add to Python, and whether this is the right syntax. Yee ha! I think that this is a great idea. I'm surprised that using the colon doesn't cause problems. I'm not a grammer lawyer, and don't care that much. I very much would like to see a conditional expression. I wouldn't object if it was spelled differently than C's. > I am a bit skeptical about whether this is sufficiently Pythonic, but > on the other hand there have always been requests for such a feature, > and the existing solutions are ugly: > > a and b or c > > only works when you know for sure that b will never be false, and > > (a and [b] or [c])[0] > > is dead ugly... Yup. (a and (b,) or (c,))[0] is even worse. ;) Jim -- Jim Fulton mailto:jim at digicool.com Technical Director (888) 344-4332 Python Powered! Digital Creations http://www.digicool.com http://www.python.org Under US Code Title 47, Sec.227(b)(1)(C), Sec.227(a)(2)(B) This email address may not be added to any commercial mail list with out my permission. Violation of my privacy with advertising or SPAM will result in a suit for a MINIMUM of $500 damages/incident, $1500 for repeats. From esr at thyrsus.com Sun Jan 30 16:59:42 2000 From: esr at thyrsus.com (Eric S. Raymond) Date: Sun, 30 Jan 2000 10:59:42 -0500 Subject: [Python-Dev] Adding C ternary select (a?b:c) to Python? In-Reply-To: <38944220.3177B402@digicool.com>; from Jim Fulton on Sun, Jan 30, 2000 at 08:52:32AM -0500 References: <200001301332.IAA12252@eric.cnri.reston.va.us> <38944220.3177B402@digicool.com> Message-ID: <20000130105941.A10861@thyrsus.com> Jim Fulton : > I'm surprised that using the colon doesn't cause problems. Pgen doesn't tag this ambiguous. The LL(1) traversal actually helps here; by the time you see a colon, you already know whether or not you're parsing a ternary telect. -- Eric S. Raymond Don't think of it as `gun control', think of it as `victim disarmament'. If we make enough laws, we can all be criminals. From guido at CNRI.Reston.VA.US Sun Jan 30 17:40:32 2000 From: guido at CNRI.Reston.VA.US (Guido van Rossum) Date: Sun, 30 Jan 2000 11:40:32 -0500 Subject: [Python-Dev] Adding C ternary select (a?b:c) to Python? In-Reply-To: Your message of "Sun, 30 Jan 2000 10:59:42 EST." <20000130105941.A10861@thyrsus.com> References: <200001301332.IAA12252@eric.cnri.reston.va.us> <38944220.3177B402@digicool.com> <20000130105941.A10861@thyrsus.com> Message-ID: <200001301640.LAA12598@eric.cnri.reston.va.us> > Jim Fulton : > > I'm surprised that using the colon doesn't cause problems. [ESR] > Pgen doesn't tag this ambiguous. The LL(1) traversal actually helps > here; by the time you see a colon, you already know whether or not you're > parsing a ternary telect. Interestingly, the very ad-hoc parsing that I described in the compiling/parsing session on devday would be hit by this... I was looking for a colon at nesting level zero. Serves me right for not using a real parse :-) --Guido van Rossum (home page: http://www.python.org/~guido/) From da at ski.org Sun Jan 30 19:07:51 2000 From: da at ski.org (David Ascher) Date: Sun, 30 Jan 2000 10:07:51 -0800 Subject: [Python-Dev] Adding C ternary select (a?b:c) to Python? References: <200001301332.IAA12252@eric.cnri.reston.va.us> <38944220.3177B402@digicool.com> <20000130105941.A10861@thyrsus.com> <200001301640.LAA12598@eric.cnri.reston.va.us> Message-ID: <004101bf6b4c$ed2ab9b0$0100000a@ski.org> FWIW, the lack of a ternary select is one of the frequently asked questions in my Python courses. It would make TomC happier as well. I'm not sure the latter is a feature. =) On the topic of aesthetics, the C syntax doesn't strike me as the ultimate in pythonicity but it's not too bad either. I can't think of an alternative that doesn't involve a new reserved word. --david From gvwilson at nevex.com Sun Jan 30 21:22:21 2000 From: gvwilson at nevex.com (gvwilson at nevex.com) Date: Sun, 30 Jan 2000 15:22:21 -0500 (EST) Subject: [Python-Dev] Eight suggestions for Python books Message-ID: I realize this is a bit off-topic, but based on discussions with various publishers over the last couple of years, and on conversations at the conference last week, I wrote up some notes on books that I think would help Python succeed, and posted them to comp.lang.python under the heading "Eight suggestions for Python books". Some of the books are specificially about Python, while others try to use Python to fill holes in the curriculum, and thereby get Python into colleges through the side door (in the same way that networking and computer graphics texts helped C become more popular). Hope it's useful... Greg From mal at lemburg.com Sun Jan 30 22:34:51 2000 From: mal at lemburg.com (M.-A. Lemburg) Date: Sun, 30 Jan 2000 22:34:51 +0100 Subject: [Python-Dev] Adding C ternary select (a?b:c) to Python? References: <200001301332.IAA12252@eric.cnri.reston.va.us> Message-ID: <3894AE7A.BE89D9B4@lemburg.com> > --- Include/token.h 2000/01/28 17:38:55 1.1 > +++ Include/token.h 2000/01/29 01:27:00 > @@ -74,10 +74,11 @@ > #define LEFTSHIFT 34 > #define RIGHTSHIFT 35 > #define DOUBLESTAR 36 > +#define QUERY 37 > /* Don't forget to update the table _PyParser_TokenNames in tokenizer.c! */ > -#define OP 37 > -#define ERRORTOKEN 38 > -#define N_TOKENS 39 > +#define OP 38 > +#define ERRORTOKEN 39 > +#define N_TOKENS 34 Shouldn't this read #define N_TOKENS 40 ?! Apart from that I wouldn't mind having this patch in the core :-) -- Marc-Andre Lemburg ______________________________________________________________________ Business: http://www.lemburg.com/ Python Pages: http://www.lemburg.com/python/ From tim_one at email.msn.com Mon Jan 31 00:25:30 2000 From: tim_one at email.msn.com (Tim Peters) Date: Sun, 30 Jan 2000 18:25:30 -0500 Subject: [Python-Dev] Adding C ternary select (a?b:c) to Python? In-Reply-To: <200001301332.IAA12252@eric.cnri.reston.va.us> Message-ID: <000301bf6b79$4f0c8a60$482d153f@tim> [Guido van Rossum] > Eric Raymond has sent me the following patch, which adds conditional > expressions to Python. I'd like to hear opinions on whether this > is a good thing to add to Python, Marginal; not evil, but of minor utility. > and whether this is the right syntax. If and only if you were a C programmer first. BTW, insert s where needed throughout . > I am a bit skeptical about whether this is sufficiently Pythonic, > but on the other hand there have always been requests for such a > feature, There have always been requests for the union of all features from all other languages. > and the existing solutions are ugly: > > a and b or c > > only works when you know for sure that b will never be false, Too error prone. > and > > (a and [b] or [c])[0] > > is dead ugly... Well, I'm the guy who invented that one! The thread that spawned it was just playfully wondering whether it was *possible* -- and if I didn't solve it, Majewski would have using even uglier __xxx__ trickery. I've never used it in a real program, and shoot people who do. So there is no reasonable way to spell ?: as a one-liner today, period. The question is whether that's "a lack" worth doing something about. I can live without it. Surprised that Jim (Fulton) seems so keen on it: his cPickle.c uses ?: exactly once in 4400 lines of C, and in a line that would have been clearer if C had a max function (or is it min? it can take a while to reverse-engineer the intent of a ?:! ... not good when it happens; and I recall one of the contributed patches that went into 1.5.2 longobject.c, that had Guido & I both cracking a C manual just to figure out how C would *parse* a particularly nutso blob of nested ?: thingies). If this goes in (I'm not deadly opposed, just more opposed than in favor), I'd like to see "else" used instead of the colon (cond "?" true "else" false). The question mark is reasonably mnemonic, but a colon makes no sense here. Now let's see whether people really want the functionality or are just addicted to C syntax . BTW, a number of other changes would be needed to the Lang Ref manual (e.g., section 2.6 (Delimeters) explicitly says that "?" isn't used in Python today, and that its appeareance outside a string literal or comment is "an unconditional error"; etc). crabby-old-man-ly y'rs - tim From esr at thyrsus.com Mon Jan 31 00:43:17 2000 From: esr at thyrsus.com (Eric S. Raymond) Date: Sun, 30 Jan 2000 18:43:17 -0500 Subject: [Python-Dev] Adding C ternary select (a?b:c) to Python? In-Reply-To: <000301bf6b79$4f0c8a60$482d153f@tim>; from Tim Peters on Sun, Jan 30, 2000 at 06:25:30PM -0500 References: <200001301332.IAA12252@eric.cnri.reston.va.us> <000301bf6b79$4f0c8a60$482d153f@tim> Message-ID: <20000130184317.A12833@thyrsus.com> Tim Peters : > If this goes in (I'm not deadly opposed, just more opposed than in favor), > I'd like to see "else" used instead of the colon (cond "?" true "else" > false). The question mark is reasonably mnemonic, but a colon makes no > sense here. I have to say that I think any ternary syntax that mixes a single-character operator with a keyword would be intolerably ugly. > Now let's see whether people really want the functionality or are just > addicted to C syntax . It's not that simple. People clearly want the functionality; we've seen ample evidence of that. Given that, I think the presumption has to be in favor of using the familiar C syntax rather than an invention that would necessarily be more obscure. > BTW, a number of other changes would be needed to the Lang Ref manual (e.g., > section 2.6 (Delimeters) explicitly says that "?" isn't used in Python > today, and that its appeareance outside a string literal or comment is "an > unconditional error"; etc). I'm certainly willing to fix that. -- Eric S. Raymond [The disarming of citizens] has a double effect, it palsies the hand and brutalizes the mind: a habitual disuse of physical forces totally destroys the moral [force]; and men lose at once the power of protecting themselves, and of discerning the cause of their oppression. -- Joel Barlow, "Advice to the Privileged Orders", 1792-93 From dascher at mindspring.com Mon Jan 31 01:09:39 2000 From: dascher at mindspring.com (David Ascher) Date: Sun, 30 Jan 2000 16:09:39 -0800 Subject: [Python-Dev] Adding C ternary select (a?b:c) to Python? References: <200001301332.IAA12252@eric.cnri.reston.va.us> <000301bf6b79$4f0c8a60$482d153f@tim> <20000130184317.A12833@thyrsus.com> Message-ID: <005c01bf6b7f$7a3a8f60$0100000a@ski.org> > > Now let's see whether people really want the functionality or are just > > addicted to C syntax . > > It's not that simple. People clearly want the functionality; we've > seen ample evidence of that. I personally haven't been stunned by the ample evidence you mention. While folks do ask about the ternary select periodically in classes and on the net, none of my students at least are especially upset when I point out the readability of: if a: b = c else: b = d > Given that, I think the presumption has > to be in favor of using the familiar C syntax rather than an invention > that would necessarily be more obscure. The presumption from the language design point of view is to do what's right regardless of language background, not what's in C -- when Guido remembered that, he chose 'and' and 'or' over '&&' and '||'. When Guido forgot that, he chose integer division =). While all of the folks on this list are comfortable with C, I can point out that a (possibly surprisingly) large proportion of the Python programmers I have taught have never used C or never felt comfortable with it. If CP4E succeeds, that proportion will grow, not shrink. I do think that taking a page from Randy Pausch would be a good idea in this case. My guess is that english words would emerge from trying to teach non-programmers the concept, but I of course don't have data on the topic. I wonder how high-school teachers teach the hook-colon in C intro classes, specifically what _words_ they use. Those words might lead to alternative syntaxes. Finally, something at the edge of my brain is trying to combine the logic of the ternary select (which is clearly related to control flow) and a more generalized switch statement. But I'm not seeing anything syntactically appealing at present. That said, the hook-colon syntax is appealing from a release management perspective because it fits within the current set of reserved words and clearly isn't the hardest concept to teach. --david From petrilli at amber.org Mon Jan 31 01:54:06 2000 From: petrilli at amber.org (Christopher Petrilli) Date: Sun, 30 Jan 2000 19:54:06 -0500 Subject: [Python-Dev] Adding C ternary select (a?b:c) to Python? In-Reply-To: <005c01bf6b7f$7a3a8f60$0100000a@ski.org>; from dascher@mindspring.com on Sun, Jan 30, 2000 at 04:09:39PM -0800 References: <200001301332.IAA12252@eric.cnri.reston.va.us> <000301bf6b79$4f0c8a60$482d153f@tim> <20000130184317.A12833@thyrsus.com> <005c01bf6b7f$7a3a8f60$0100000a@ski.org> Message-ID: <20000130195406.A25682@trump.amber.org> The question comes from what "problem" you're trying to solve. The ?: syntax does not introduce any new "functionality" to the language, nor does it make it capable of solving problems or requirements that it can not do at the current time. The second qustion I'd ask is, who is this aimed at? It's certainly not aimed at first-time programmers, as I know from experience that the ?: is one of the hardest things to teach people in C (after pointers), and often I leave it out of training when I did it. It's simply a "shorthand" not a new functionality. If its aimed at experienced programmers, I'd argue that it's at best "non-pythonic" and at worst a hack, taken from a language in which it exposes the "macro assembler" approach. Python is not a language that has been optimized for "minimal typing", it's much more verbose than most languages, and so that argument shouldn' be applied. Perhaps it's for optimization? That was I believe the original argument made for it in K&R, in that optimizers in that day were rather antiquated, wheras today, I believe that any C compiler would get it right if it were expressed in its full form. (Timbot?) So, it comes down to a few questions for me: Does it solve a new problem? No Is it pythonic? No Does it make it faster? No Given Pyton's CP4E goals, and its general place as an easy to use language, I'd argue this patch would be counter to all of those goals. Sorry if I pushed someone's buton, but... I saw a lot of hints at making Python MUCH more complex, which is counter to why I changed and dropped many other languags. Chris -- | Christopher Petrilli | petrilli at amber.org From tim_one at email.msn.com Mon Jan 31 01:44:34 2000 From: tim_one at email.msn.com (Tim Peters) Date: Sun, 30 Jan 2000 19:44:34 -0500 Subject: [Python-Dev] Adding C ternary select (a?b:c) to Python? In-Reply-To: <20000130184317.A12833@thyrsus.com> Message-ID: <000801bf6b84$588c2d60$482d153f@tim> [Tim, tosses off cond "?" true "else" false in apparent hatred of colons] [Eric S. Raymond] > I have to say that I think any ternary syntax that mixes a > single-character operator with a keyword would be intolerably ugly. It's certainly not attractive . Guido is the Master of Syntax; if he decides the functionality is Pythonic, he'll dream up a good Pythonic syntax. I'll refrain from suggesting "if" cond "lambda" true "else" false . >> Now let's see whether people really want the functionality or are just >> addicted to C syntax . > It's not that simple. People clearly want the functionality; we've > seen ample evidence of that. I have not. Really! This has been debated for nearly a decade, with no consensus (the invention of the (a and [b] or [c])[0] atrocity predates c.l.py!). *Some* people certainly want ?: (or equivalent) a lot; but others are equally opposed. Note that lack of ?: didn't have enough of a constituency in Andrew Kuchling's eyes either to make his original "Python Warts" paper, or its revisions: http://starship.python.net/crew/amk/python/writing/warts.html No change ever proposed has failed to attract vocal & persistent supporters, so it's not as simple as *that* either <0.5 wink>. > Given that, I think the presumption has to be in favor of using the > familiar C syntax rather than an invention that would necessarily be > more obscure. By count, I'm sure many more languages (from virtually all functional languages to Icon) use "if cond then true else false" for this purpose; obscurity is relative to your background. At least "if x then y else z" is clear on the face of it (which may betray my background ). "then" has no chance of getting into Python1, though. My core objection is that ?: doesn't "look pretty": it's not at all suggestive of what it means, and the effects on precedence and associativity are unattractive ("see C, copy C" is the only sense there is to it, and rules for ?: are-- as I noted last time --obscure). Good syntax counts for a lot in Python -- which is why it doesn't look like C now. Get a good syntax, and most of my objections vanish; I don't have a good syntax to suggest, though. passing-the-ball-back-to-guido-where-he-always-knew-it- would-land-ly y'rs - tim From esr at thyrsus.com Mon Jan 31 02:07:11 2000 From: esr at thyrsus.com (Eric S. Raymond) Date: Sun, 30 Jan 2000 20:07:11 -0500 Subject: [Python-Dev] Adding C ternary select (a?b:c) to Python? In-Reply-To: <20000130195406.A25682@trump.amber.org>; from Christopher Petrilli on Sun, Jan 30, 2000 at 07:54:06PM -0500 References: <200001301332.IAA12252@eric.cnri.reston.va.us> <000301bf6b79$4f0c8a60$482d153f@tim> <20000130184317.A12833@thyrsus.com> <005c01bf6b7f$7a3a8f60$0100000a@ski.org> <20000130195406.A25682@trump.amber.org> Message-ID: <20000130200711.A13063@thyrsus.com> Christopher Petrilli : > The question comes from what "problem" you're trying to solve. The ?: syntax > does not introduce any new "functionality" to the language, nor does it > make it capable of solving problems or requirements that it can not do > at the current time. Well, in a theoretical sense, you're right. But then, even troff macros and INTERCAL are Turing-complete . One of the lessons of Python to this old LISPer is that *notation matters*. Theoretically, Python is a subset of Scheme-with-objects using a vaguely C-like surface notation. But even I would rather write a for-loop than the equivalent recursion. That's why I code in Python now instead of trying to rescue LISP from its desuetitude. So while it is *theoretically* true that ?: adds nothing, it is *practically* true that it enables a large class of idioms that can't otherwise be comfortably expressed. That matters. Now, you can argue that the complexity ?: adds to language is not paid for by the additional convenience; I disagree, but that's at least a defensible argument. But simply saying it "adds nothing to the language" is a red herring -- neither do many of the other base language features. Why, for example, do we have more than one kind of loop construct? Unecessary. Wasteful. Clearly either "for" or "while" must go. As an exercise, try editing your complaint so that it refers to "for" everywhere it now refers to ?:. Contemplate the edited version until you achieve enlightenment ;-). -- Eric S. Raymond The same applies for other kinds of long-lasting low-level pain. [...] The body's response to being jabbed, pierced, and cut is to produce endorphins. [...] So here's my programme for breaking that cycle of dependency on Windows: get left arm tattooed with dragon motif, buy a crate of Jamaican Hot! Pepper Sauce, get nipples pierced. With any luck that will produce enough endorphins to make Windows completely redundant, and I can then upgrade to Linux and get on with things. -- Pieter Hintjens From ping at lfw.org Mon Jan 31 02:29:43 2000 From: ping at lfw.org (Ka-Ping Yee) Date: Sun, 30 Jan 2000 19:29:43 -0600 (EST) Subject: [Python-Dev] Adding C ternary select (a?b:c) to Python? In-Reply-To: <000301bf6b79$4f0c8a60$482d153f@tim> Message-ID: On Sun, 30 Jan 2000, Tim Peters wrote: > If this goes in (I'm not deadly opposed, just more opposed than in favor), > I'd like to see "else" used instead of the colon (cond "?" true "else" > false). The question mark is reasonably mnemonic, but a colon makes no > sense here. I agree with that sentiment (along the lines of the philosophy that chose "and" over "&&"), and it seems to me that it makes the most sense to use words for both: a = x > 0 then x else -x I don't have the time to do it right this second, but i suggest that a scan through a decent chunk of Python would be useful to find out how often this construct (in its "and"/"or" incarnation) actually gets used. I promise to give it a try as soon as i get my notebook battery charged up again. -- ?!ng From tim_one at email.msn.com Mon Jan 31 03:41:59 2000 From: tim_one at email.msn.com (Tim Peters) Date: Sun, 30 Jan 2000 21:41:59 -0500 Subject: [Python-Dev] Adding C ternary select (a?b:c) to Python? In-Reply-To: <20000130195406.A25682@trump.amber.org> Message-ID: <000201bf6b94$bfabc360$ee2d153f@tim> [Christopher Petrilli] > ... > Python is not a language that has been optimized for "minimal > typing", it's much more verbose than most languages, and so that > argument shouldn't be applied. Concise expression of common concepts is a Good Thing, though, and there's nothing inherently evil about wanting one of two outcomes . My impression is that the people historically most in favor of ?: ("or something like it") are also the ones most strongly in favor of embedded assignment ("or something like it"), and I can't *dismiss* either gripe. The Python while 1: x = something_or_other() if not x: break consume(x) idiom is truly grating at first -- more so than the multi-line ?: alternatives, in my eyes. > Perhaps it's for optimization? That was I believe the original > argument made for it in K&R, in that optimizers in that day were rather > antiquated, wheras today, I believe that any C compiler would get it > right if it were expressed in its full form. (Timbot?) Indeed, a couple weeks ago we tracked down a "mysterious slowdown" of our core speech recognizer to a particular compiler failing to optimize *unless* we changed a ?: into a long winded if/else! There's really nothing you can say about "any C compiler" -- optimization is much more a black art than anyone in that business will admit to in public <0.9 wink>. C was definitely designed with "by hand" optimization in mind, and, ironically, it's those features (particularly pointer aliasing) that make it harder for compilers to optimize than is, say, Fortran. But regardless of origin, ?: stands or falls on its other merits now. Python's own implementation uses it often enough, and to good effect. So it can't be that Guido hates the idea . It's just hard to love the syntax. > So, it comes down to a few questions for me: > > Does it solve a new problem? No > Is it pythonic? No > Does it make it faster? No Would a nice syntax allow clearer expression of some common computations? Probably yes. That's the same basis on which, e.g., list.pop and list.extend and dict.get and 3-argument getattr and ... were adopted. "Faster" applied to those too, but nobody pushed for 'em on that basis. Clearer! That's what really matters. It's the same argument for list comprehensions too. > ... > Sorry if I pushed someone's buton, but... I saw a lot of hints at making > Python MUCH more complex, which is counter to why I changed and dropped > many other languags. A good antitode to feature panic is reviewing Misc/HISTORY: Guido's willingness to entertain suggestions far exceeds his willingness to adopt them . it-would-be-different-if-features-were-just-as-easy-to- take-out-ly y'rs - tim From tismer at tismer.com Mon Jan 31 12:46:50 2000 From: tismer at tismer.com (Christian Tismer) Date: Mon, 31 Jan 2000 12:46:50 +0100 Subject: [Python-Dev] Adding C ternary select (a?b:c) to Python? References: Message-ID: <3895762A.C1706E8@tismer.com> Ka-Ping Yee wrote: > > On Sun, 30 Jan 2000, Tim Peters wrote: > > If this goes in (I'm not deadly opposed, just more opposed than in favor), > > I'd like to see "else" used instead of the colon (cond "?" true "else" > > false). The question mark is reasonably mnemonic, but a colon makes no > > sense here. > > I agree with that sentiment (along the lines of the philosophy that > chose "and" over "&&"), and it seems to me that it makes the most sense > to use words for both: > > a = x > 0 then x else -x I would favorise this as well instead of using ?: . Maybe it would make sense to be even more verbose and use an "if" as well? a = if x > 0 then x else -x sign = lambda x: if x > 0 then 1 elif x then -1 else 0 ciao - chris -- Christian Tismer :^) Applied Biometrics GmbH : Have a break! Take a ride on Python's D?ppelstr. 31 : *Starship* http://starship.python.net 12163 Berlin : PGP key -> http://wwwkeys.pgp.net PGP Fingerprint E182 71C7 1A9D 66E9 9D15 D3CC D4D7 93E2 1FAE F6DF we're tired of banana software - shipped green, ripens at home From gward at cnri.reston.va.us Mon Jan 31 15:15:08 2000 From: gward at cnri.reston.va.us (Greg Ward) Date: Mon, 31 Jan 2000 09:15:08 -0500 Subject: [Python-Dev] Adding C ternary select (a?b:c) to Python? In-Reply-To: ; from ping@lfw.org on Sun, Jan 30, 2000 at 07:29:43PM -0600 References: <000301bf6b79$4f0c8a60$482d153f@tim> Message-ID: <20000131091507.A17073@cnri.reston.va.us> On 30 January 2000, Ka-Ping Yee said: > On Sun, 30 Jan 2000, Tim Peters wrote: > > If this goes in (I'm not deadly opposed, just more opposed than in favor), > > I'd like to see "else" used instead of the colon (cond "?" true "else" > > false). The question mark is reasonably mnemonic, but a colon makes no > > sense here. > > I agree with that sentiment (along the lines of the philosophy that > chose "and" over "&&"), and it seems to me that it makes the most sense > to use words for both: > > a = x > 0 then x else -x Yeah, I agree with Tim: it's a handy feature and I frequently wish I could do simple conditional assignment without resorting to a full-blown if/else. (I think I stumbled across "a and b or c" myself -- either that or it was suggested by *Learning Python*, but lay dormant in my subconscious for several months -- which means that I missed the "b must always be true" subtlety until it bit me. Ouch. I avoid that idiom now.) BUT the C line-noise syntax is not appropriate. It's fine in C, and it's eminently appropriate in Perl -- both languages designed to minimise wear-and-tear of programmers' keyboards. But keyboards are cheap nowadays, so perhaps we can be a bit more profligate with them. I find Ping's proposed syntax intriguing. Personally, I've always been partial to the x = if a then b else c syntax, even though I don't think I've ever used a language that includes it. (Oh wait, the toy ALGOL-knockoff that we used in Intro to Compilers had it, so I *have* written a parser and simplistic code generator for a language that includes it. Perhaps that's why I like it...) But either of these -- ie. elevate "then" to keywordhood, with or without "if", and no colons to be seen -- smell like they would play havoc with Python's grammar. And they turn a statement keyword "if" into an expression keyword. Not being at all familiar with Python's parser, I should just shut up now, but it feels tricky. And of course, any proposed syntax changes nowadays have to take JPython into account. Greg From guido at CNRI.Reston.VA.US Mon Jan 31 15:36:52 2000 From: guido at CNRI.Reston.VA.US (Guido van Rossum) Date: Mon, 31 Jan 2000 09:36:52 -0500 Subject: [Python-Dev] Adding C ternary select (a?b:c) to Python? In-Reply-To: Your message of "Mon, 31 Jan 2000 09:15:08 EST." <20000131091507.A17073@cnri.reston.va.us> References: <000301bf6b79$4f0c8a60$482d153f@tim> <20000131091507.A17073@cnri.reston.va.us> Message-ID: <200001311436.JAA15213@eric.cnri.reston.va.us> > I find Ping's proposed syntax intriguing. Personally, I've always been > partial to the > > x = if a then b else c > > syntax, even though I don't think I've ever used a language that > includes it. (Oh wait, the toy ALGOL-knockoff that we used in Intro to > Compilers had it, so I *have* written a parser and simplistic code > generator for a language that includes it. Perhaps that's why I like > it...) Yes, this was in original Algol 60 and, by magic of a completely different kind, again in Algol 68 (which was a completely different language, and the Mount Everest of languages). > But either of these -- ie. elevate "then" to keywordhood, with or > without "if", and no colons to be seen -- smell like they would play > havoc with Python's grammar. And they turn a statement keyword "if" > into an expression keyword. Not being at all familiar with Python's > parser, I should just shut up now, but it feels tricky. The solution can be the same as what Algol used: 'if' outside parentheses is a statement, and inside parentheses is an expression. It's a bit of a grammar rearrangement, but totally unambiguous. However, the added keyword means it won't be in 1.6. The lively discussion means that Eric's patch will have a hard time getting in too... --Guido van Rossum (home page: http://www.python.org/~guido/) From jim at digicool.com Mon Jan 31 16:04:45 2000 From: jim at digicool.com (Jim Fulton) Date: Mon, 31 Jan 2000 10:04:45 -0500 Subject: [Python-Dev] Adding C ternary select (a?b:c) to Python? References: <200001301332.IAA12252@eric.cnri.reston.va.us> <000301bf6b79$4f0c8a60$482d153f@tim> <20000130184317.A12833@thyrsus.com> <005c01bf6b7f$7a3a8f60$0100000a@ski.org> <20000130195406.A25682@trump.amber.org> Message-ID: <3895A48D.F69B3DFA@digicool.com> Christopher Petrilli wrote: > > The question comes from what "problem" you're trying to solve. It would allow you to incorporate logic into expressions. There are contexts where only expressions are allowed, such as: - lambdas - DTML expr attributes in which I'd very much like to incorporate tests. > The ?: syntax > does not introduce any new "functionality" to the language, Yes it does. > nor does it > make it capable of solving problems or requirements that it can not do > at the current time. Ditto. > The second qustion I'd ask is, who is this aimed at? It's certainly not > aimed at first-time programmers, as I know from experience that the ?: > is one of the hardest things to teach people in C (after pointers), Hm. I can't agree. Smalltalk, came out of an essentially CP4E effort two decades ago at Xerox PARC. Smalltalk *only* had conditional expressions. The message: [condition] ifTrue: [do something ...] ifFalse: [do something else ...] is an expression in Smalltalk. > and > often I leave it out of training when I did it. It's simply a "shorthand" > not a new functionality. No, it allows testing in expressions. > If its aimed at experienced programmers, I'd > argue that it's at best "non-pythonic" and at worst a hack, taken from > a language in which it exposes the "macro assembler" approach. I don't agree. > Python is not a language that has been optimized for "minimal typing", That's not the issue. > it's > much more verbose than most languages, and so that argument shouldn' be > applied. Perhaps it's for optimization? That was I believe the original > argument made for it in K&R, in that optimizers in that day were rather > antiquated, wheras today, I believe that any C compiler would get it > right if it were expressed in its full form. (Timbot?) > > So, it comes down to a few questions for me: > > Does it solve a new problem? No Yes. > Is it pythonic? No Pythonicity is relative. > Does it make it faster? No Who cares? Jim -- Jim Fulton mailto:jim at digicool.com Python Powered! Technical Director (888) 344-4332 http://www.python.org Digital Creations http://www.digicool.com http://www.zope.org Under US Code Title 47, Sec.227(b)(1)(C), Sec.227(a)(2)(B) This email address may not be added to any commercial mail list with out my permission. Violation of my privacy with advertising or SPAM will result in a suit for a MINIMUM of $500 damages/incident, $1500 for repeats. From tismer at tismer.com Mon Jan 31 16:59:15 2000 From: tismer at tismer.com (Christian Tismer) Date: Mon, 31 Jan 2000 16:59:15 +0100 Subject: [Python-Dev] Riskless deletion of nested structures Message-ID: <3895B153.3D2E763D@tismer.com> Howdy, Please review! While implementing Stackless Python, a new problem arose: Nested structures like frame chains and tracebacks can now easily grow somuch that they cause a stack overflow on deallocation. To protect lists, tuples, frames, dicts and tracebacks against this, I wrote a stackless deallocator. At the moment, everything is done in trashcan.c . This gives a slight performance loss of 5% for pystone, most probably due to the double indirection and non-local code reference. It is yet a hack, since I'm grabbing the tp->dealloc pointers of these types and replace them by safe versions. This just in order to try out things quickly. Later I will change this and incorporate the stack checks into the affected modules, after I got some feedback on this. This patch applies to Stackless and standard Python as well: Deallocation of deeply nested structures will never again cause a stack overflow. Installation for the intermediate version: Insert a line _Py_trashcan_install(); at the end of Py_Initialize in pythonrun.c Please try it and check my code wether there is a better solution. cheers - chris -- Christian Tismer :^) Applied Biometrics GmbH : Have a break! Take a ride on Python's D?ppelstr. 31 : *Starship* http://starship.python.net 12163 Berlin : PGP key -> http://wwwkeys.pgp.net PGP Fingerprint E182 71C7 1A9D 66E9 9D15 D3CC D4D7 93E2 1FAE F6DF we're tired of banana software - shipped green, ripens at home -------------- next part -------------- A non-text attachment was scrubbed... Name: trashcan.c Type: application/x-unknown-content-type-cfile Size: 2209 bytes Desc: not available URL: -------------- next part -------------- A non-text attachment was scrubbed... Name: trashcan.h Type: application/x-unknown-content-type-hfile Size: 246 bytes Desc: not available URL: From fdrake at acm.org Mon Jan 31 18:08:11 2000 From: fdrake at acm.org (Fred L. Drake, Jr.) Date: Mon, 31 Jan 2000 12:08:11 -0500 (EST) Subject: [Python-Dev] Adding C ternary select (a?b:c) to Python? In-Reply-To: References: <000301bf6b79$4f0c8a60$482d153f@tim> Message-ID: <14485.49531.600935.643400@weyr.cnri.reston.va.us> Ka-Ping Yee writes: > a scan through a decent chunk of Python would be useful to find out how > often this construct (in its "and"/"or" incarnation) actually gets used. I'm not sure what the survey provides other than a lower bound. I think most Python programmers who want the ?: functionality avoid the and/or approach because of the ugliness. I know I do. But I'd really like to have the functionality if the syntax is reasonable! I could live with something like "if cond then true else false"; the leading "if" is visually important; without it, you have to scan over the test expression to find the "then", and that makes it harder to read. -Fred -- Fred L. Drake, Jr. Corporation for National Research Initiatives From bwarsaw at cnri.reston.va.us Mon Jan 31 18:33:25 2000 From: bwarsaw at cnri.reston.va.us (Barry A. Warsaw) Date: Mon, 31 Jan 2000 12:33:25 -0500 (EST) Subject: [Python-Dev] Adding C ternary select (a?b:c) to Python? References: <000301bf6b79$4f0c8a60$482d153f@tim> <14485.49531.600935.643400@weyr.cnri.reston.va.us> Message-ID: <14485.51045.97448.830202@anthem.cnri.reston.va.us> Put me in the camp of "yeah, occasionally I wish I had it, but I can always hack around it, and the C syntax just blows". I'm sure if it's wedgeable into CPython it would also be in JPython, but I dislike ?: syntax enough to vote strongly against it for CPython 1.6. A Forth-ish syntax might be more acceptable x = y > z if y else z but come on! You'll give ordinarily dandruff-free Python programmers plenty of other reasons to scratch their heads with this one. head-and-shoulders-above-the-rest-ly y'rs, -Barry From gvwilson at nevex.com Mon Jan 31 18:44:53 2000 From: gvwilson at nevex.com (gvwilson at nevex.com) Date: Mon, 31 Jan 2000 12:44:53 -0500 (EST) Subject: [Python-Dev] Adding C ternary select (a?b:c) to Python? In-Reply-To: <3895A48D.F69B3DFA@digicool.com> Message-ID: > It (?:) would allow you to incorporate logic into expressions. > There are contexts where only expressions are allowed, such as: > - lambdas > - DTML expr attributes > in which I'd very much like to incorporate tests. Don't know much about DTML, but believe that being able to put conditionals in lambdas would make the latter much more useful. > > The ?: syntax > > does not introduce any new "functionality" to the language, > Yes it does. Is anything possible with ?: that's impossible without? No --- Python is Turing-equivalent before and after the change. Is anything easier with ?: --- yes. Does this make up for the added complexity? Dunno (see below). > > The second qustion I'd ask is, who is this aimed at? It's certainly not > > aimed at first-time programmers, as I know from experience that the ?: > > is one of the hardest things to teach people in C (after pointers), > Hm. I can't agree. Strongly agree with the first author --- IME, ?: is very hard to teach. Greg From klm at digicool.com Mon Jan 31 18:58:07 2000 From: klm at digicool.com (Ken Manheimer) Date: Mon, 31 Jan 2000 12:58:07 -0500 (EST) Subject: [Python-Dev] Adding C ternary select (a?b:c) to Python? In-Reply-To: <14485.49531.600935.643400@weyr.cnri.reston.va.us> Message-ID: On Mon, 31 Jan 2000, Fred L. Drake, Jr. wrote: > Ka-Ping Yee writes: > > a scan through a decent chunk of Python would be useful to find out how > > often this construct (in its "and"/"or" incarnation) actually gets used. > > I'm not sure what the survey provides other than a lower bound. I > think most Python programmers who want the ?: functionality avoid the > and/or approach because of the ugliness. I know I do. Good point. Just because the workaround is bad doesn't mean the thing being worked-around is unimportant... I should weigh in to say that i have really really wanted, in particular, the ability to have a condition on the right hand side of an assignement. IIR, on some occasions it seemed less clear to have to use separate statements for what was essentially a single assignment that just, eg, differed by a single term. I wanted (want) some reasonable way to express the condition in an expression. I can see how this compactness could lead to regex-style convolution of expressions, but that could be avoided by providing a not-too-terse syntax. (I should admit that may have succumbed to the (a and (b,) or (c,))[0] grotesquerie at some point! Not sure. Wish i could recall what might have justified succumbing - the mere fact that i may have, without compelling justification, might-should disqualify my judgement on the matter, ay? Hey, maybe i didn't, i was just imagining it - now am i not a sterling judge?-) Ken klm at digicool.com From tismer at tismer.com Mon Jan 31 20:55:36 2000 From: tismer at tismer.com (Christian Tismer) Date: Mon, 31 Jan 2000 20:55:36 +0100 Subject: [Python-Dev] Ann: Stackless Python 1.02 Message-ID: <3895E8B8.995CA560@tismer.com> Stackless Python is a Python without C stack usage. It allows for all kinds of non-local control flow. For info see http://www.tismer.com/research/stackless/ Update for Stackless Python V. 1.02: - passes all standard tests - should work with Zope now (try...finally was incorrect) - has a smart object destructor for really deeply nested stuff The "5 percent speedup" is no longer there currently, since the smart object destructor needs to be optimized into the objects. It is not done in this test phase but will come. Please visit the Stackless Python homepage at http://www.tismer.com/research/stackless/ Fact sheet, links to documentation, source and binaries can be found there. cheers - chris

Stackless Python 1.02 + Continuations 0.6 - a version of Python 1.5.2 that does not need space on the C stack, and first-class callable continuation objects for Python. (31-Jan-2000) Christian Tismer Mission Impossible 5oftware Team