Re: Why exception from os.path.exists()?
On 06/07/2018 12:45 AM, Chris Angelico wrote: On Thu, Jun 7, 2018 at 1:55 PM, Steven D'Aprano wrote: On Tue, 05 Jun 2018 23:27:16 +1000, Chris Angelico wrote: And an ASCIIZ string cannot contain a byte value of zero. The parallel is exact. Why should we, as Python programmers, care one whit about ASCIIZ strings? They're not relevant. You might as well say that file names cannot contain the character "π" because ASCIIZ strings don't support it. No they don't, and yet nevertheless file names can and do contain characters outside of the ASCIIZ range. Under Linux, a file name contains bytes, most commonly representing UTF-8 sequences. So... an ASCIIZ string *can* contain that character, or at least a representation of it. Yet it cannot contain "\0". ChrisA This seems like an argument for allowing byte strings to be used as file names, not for altering text strings. If file names are allowed to contain values that are illegal for text strings, then they shouldn't be necessarily considered as text strings. The unicode group sets one set of rules, and their rules should apply in their area. The Linux group sets another set of rules, and their rules should apply in their area. Just because there is a large area of overlap doesn't mean that the two areas are congruent. Byte strings are designed to handle any byte pattern, but text strings are designed to handle a subset of those patterns. Most byte strings are readable as text, but not all of them. -- https://mail.python.org/mailman/listinfo/python-list
possible bug in while loop test
python3 --version Python 3.5.3 Running on Debian stretch In this code s is a string parameter while (j < k and \ (s[j].isalnum()) or \ (s[j] in seps and s[j+1].isalnum()) ): j = j + 1 print ("i = {0}, j = {1}, k = {2}, len[s] = {3}". \ format(i, j, k, len(s) ) ) Yields the result: i = 25, j = 27, k = 31, len[s] = 32 i = 25, j = 28, k = 31, len[s] = 32 i = 25, j = 29, k = 31, len[s] = 32 i = 25, j = 30, k = 31, len[s] = 32 i = 25, j = 31, k = 31, len[s] = 32 Traceback (most recent call last): File "parse1.py", line 40, in print (parse1("The gostack distimms the doshes.")) File "parse1.py", line 21, in parse1 (s[j] in seps and s[j+1].isalnum()) ): IndexError: string index out of range I hesitate to report this, because I've been wrong so often, but it looks to me like the last iteration should not have happened since j is not less than k. -- https://mail.python.org/mailman/listinfo/python-list
Re: Multiprocessing queues receiving from wrong process
On 12/23/2016 01:56 PM, Charles Hixson wrote: I was looking to avoid using a upd connection to transfer messages between processes, so I thought I'd use multiprocessing (which I expect would be faster), but...I sure would appreciate an explanation of this problem. When I run the code (below) instead of messages receiving messages from the correct process I get: (where the first number of a line identifies the index assigned to the process.) waiting for completion The receiving process should be the one sent to. receiving sending sent to ndx process nameprocess name ndx 1=Process-2 received: at time 0.001243: Process-1 says Hi to 0 0=Process-1 received: at time 0.001211: Process-2 says Hi to 1 0=Process-1 received: at time 0.001144: Process-3 says Hi to 2 4=Process-5 received: at time 0.002324: Process-1 says Hi to 0 0=Process-1 received: at time 0.000953: Process-4 says Hi to 3 0=Process-1 received: at time 0.000674: Process-5 says Hi to 4 3=Process-4 received: at time 0.002114: Process-1 says Hi to 0 3=Process-4 received: at time 0.001864: Process-2 says Hi to 1 4=Process-5 received: at time 0.002094: Process-2 says Hi to 1 2=Process-3 received: at time 0.001711: Process-1 says Hi to 0 4=Process-5 received: at time 0.001885: Process-3 says Hi to 2 4=Process-5 received: at time 0.001586: Process-4 says Hi to 3 1=Process-2 received: at time 0.001456: Process-3 says Hi to 2 3=Process-4 received: at time 0.001734: Process-3 says Hi to 2 2=Process-3 received: at time 0.00158: Process-2 says Hi to 1 2=Process-3 received: at time 0.001444: Process-4 says Hi to 3 2=Process-3 received: at time 0.001088: Process-5 says Hi to 4 3=Process-4 received: at time 0.001221: Process-5 says Hi to 4 1=Process-2 received: at time 0.001212: Process-4 says Hi to 3 1=Process-2 received: at time 0.000885: Process-5 says Hi to 4 ##Test multiprocessing queues importmultiprocessingasmp importtime frommultiprocessingimportProcess frommultiprocessingimportQueue fromqueueimportEmpty fromqueueimportFull fromrandomimportrandom class TestMPQ: """ Class doc """ def __init__ (self, ndx): """ Class initialiser """ self.name=mp.current_process().name self.ndx=ndx defsendHi (self): for i in range(5): if i != self.ndx: qs[i].put ("{} says Hi to {}".format(self.name, self.ndx)) defprocessHi (self): while (True): time.sleep(random() + 0.001) try: msg=qs[self.ndx].get_nowait() print ("{}={} received: {}".format(self.ndx, self.name, msg) ) exceptEmpty: break except Exception as ex: print ("Exception: ", repr(ex)) break defprocHandler (ndx, qs): p=TestMPQ(ndx) p.sendHi() p.processHi() if "__main__" == __name__: qs=[] for i in range(5): qs.append(Queue()) ps=[] for i in range(5): ps.append(Process(target = procHandler, args = (i, qs) ) ) ps[i].start() print ("waiting for completion") for i in range(5): ps[i].join() -- https://mail.python.org/mailman/listinfo/python-list
Multiprocessing queues receiving from wrong process
I was looking to avoid using a upd connection to transfer messages between processes, so I thought I'd use multiprocessing (which I expect would be faster), but...I sure would appreciate an explanation of this problem. When I run the code (below) instead of messages receiving messages from the correct process I get: (where the first number of a line identifies the index assigned to the process.) waiting for completion 1=Process-2 received: at time 0.001243: Process-1 says Hi to 0 0=Process-1 received: at time 0.001211: Process-2 says Hi to 1 0=Process-1 received: at time 0.001144: Process-3 says Hi to 2 4=Process-5 received: at time 0.002324: Process-1 says Hi to 0 0=Process-1 received: at time 0.000953: Process-4 says Hi to 3 0=Process-1 received: at time 0.000674: Process-5 says Hi to 4 3=Process-4 received: at time 0.002114: Process-1 says Hi to 0 3=Process-4 received: at time 0.001864: Process-2 says Hi to 1 4=Process-5 received: at time 0.002094: Process-2 says Hi to 1 2=Process-3 received: at time 0.001711: Process-1 says Hi to 0 4=Process-5 received: at time 0.001885: Process-3 says Hi to 2 4=Process-5 received: at time 0.001586: Process-4 says Hi to 3 1=Process-2 received: at time 0.001456: Process-3 says Hi to 2 3=Process-4 received: at time 0.001734: Process-3 says Hi to 2 2=Process-3 received: at time 0.00158: Process-2 says Hi to 1 2=Process-3 received: at time 0.001444: Process-4 says Hi to 3 2=Process-3 received: at time 0.001088: Process-5 says Hi to 4 3=Process-4 received: at time 0.001221: Process-5 says Hi to 4 1=Process-2 received: at time 0.001212: Process-4 says Hi to 3 1=Process-2 received: at time 0.000885: Process-5 says Hi to 4 ##Test multiprocessing queues importmultiprocessingasmp importtime frommultiprocessingimportProcess frommultiprocessingimportQueue fromqueueimportEmpty fromqueueimportFull fromrandomimportrandom class TestMPQ: """ Class doc """ def __init__ (self, ndx): """ Class initialiser """ self.name=mp.current_process().name self.ndx=ndx defsendHi (self): for i in range(5): if i != self.ndx: qs[i].put ("{} says Hi to {}".format(self.name, self.ndx)) defprocessHi (self): while (True): time.sleep(random() + 0.001) try: msg=qs[self.ndx].get_nowait() print ("{}={} received: {}".format(self.ndx, self.name, msg) ) exceptEmpty: break except Exception as ex: print ("Exception: ", repr(ex)) break defprocHandler (ndx, qs): p=TestMPQ(ndx) p.sendHi() p.processHi() if "__main__" == __name__: qs=[] for i in range(5): qs.append(Queue()) ps=[] for i in range(5): ps.append(Process(target = procHandler, args = (i, qs) ) ) ps[i].start() print ("waiting for completion") for i in range(5): ps[i].join() -- https://mail.python.org/mailman/listinfo/python-list
Multiprocessing interactive processes with connections
I want to process a bunch of processes that all talk to each other. I've figured out how to do this using queues with the main process as the mail handler, but I'd rather have them talk directly. If I use connections, then I can pass the pipes to the processes, but there doesn't seem to be anything analogous to queue, so it looks like I need to divide each process into two threads, one of which does nothing but mail handling. Is this correct? FWIW, a small, unoptimized, test of the working "mailhandler" approach is: ## Multiprocessing: main thread as post office. # This is a bit clumsy, but it works. from multiprocessing import Process, Queue from queue import Empty def f(i, lim, q_rcv, q_snd): for j in range(lim): if i != j: q_snd.put([i, "message from process {0} to proess {1}".format(i, j), j]) if not q_rcv.empty(): val = q_rcv.get() print (val) q_snd.put([i, "done"]) while (not q_recv.empty()): val = q_rcv.get() print (val, " :: ", i) if val == "done": return if __name__ == '__main__': ps = [] qs = [] q_recv = Queue() for i in range(3): q = Queue() qs.append (q) ps.append (Process(target=f, args=(i, 3, q, q_recv)) ) for p in ps: p.start() dones = 0 try: v = q_recv.get(True, 1) while (v): print ("v = ", v) if v[1] == "done": dones = dones + 1 else: if len(v) == 3: assert v[2] < len(qs), "unexpected value" qs[v[2]].put(v[1]) else: print ("error: ", v, " was an unexpected value.") v = q_recv.get(True, 1) except Empty: print ("1: Timeout of maine receive queue") for q in qs: q.put("done") try: v = q_recv.get(True, 1) while (v): print ("2: v = ", v) if v[1] == "done": dones = dones + 1 else: if len(v) == 3: assert v[3] < len(qs), "2: unexpected value" qs[v[3]].put(v[2]) else: print ("2: error: ", v, " was an unexpected value.") v = q_recv.get(True, 1) except Empty: print ("2: Timeout of maine receive queue") for i in range(len(qs)): qs[i].close(); qs[i] = None -- https://mail.python.org/mailman/listinfo/python-list
Multiprocessing interactive processes with connections
I want to process a bunch of processes that all talk to each other. I've figured out how to do this using queues with the main process as the mail handler, but I'd rather have them talk directly. If I use connections, then I can pass the pipes to the processes, but there doesn't seem to be anything analogous to queue, so it looks like I need to divide each process into two threads, one of which does nothing but mail handling. Is this correct? FWIW, a small, unoptimized, test of the working "mailhandler" approach is: ## Multiprocessing: main thread as post office. # This is a bit clumsy, but it works. from multiprocessing import Process, Queue from queue import Empty def f(i, lim, q_rcv, q_snd): for j in range(lim): if i != j: q_snd.put([i, "message from process {0} to proess {1}".format(i, j), j]) if not q_rcv.empty(): val = q_rcv.get() print (val) q_snd.put([i, "done"]) while (not q_recv.empty()): val = q_rcv.get() print (val, " :: ", i) if val == "done": return if __name__ == '__main__': ps = [] qs = [] q_recv = Queue() for i in range(3): q = Queue() qs.append (q) ps.append (Process(target=f, args=(i, 3, q, q_recv)) ) for p in ps: p.start() dones = 0 try: v = q_recv.get(True, 1) while (v): print ("v = ", v) if v[1] == "done": dones = dones + 1 else: if len(v) == 3: assert v[2] < len(qs), "unexpected value" qs[v[2]].put(v[1]) else: print ("error: ", v, " was an unexpected value.") v = q_recv.get(True, 1) except Empty: print ("1: Timeout of maine receive queue") for q in qs: q.put("done") try: v = q_recv.get(True, 1) while (v): print ("2: v = ", v) if v[1] == "done": dones = dones + 1 else: if len(v) == 3: assert v[3] < len(qs), "2: unexpected value" qs[v[3]].put(v[2]) else: print ("2: error: ", v, " was an unexpected value.") v = q_recv.get(True, 1) except Empty: print ("2: Timeout of maine receive queue") for i in range(len(qs)): qs[i].close(); qs[i] = None -- https://mail.python.org/mailman/listinfo/python-list
asyncio, coroutines, etc. and simultaneous execution
If I understand correctly asyncio, coroutines, etc. (and, of course, Threads) are not simultaneously executed, and that if one wants that one must still use multiprocessing. But I'm not sure. The note is still there at the start of threading, so I'm pretty sure about that one. The requirement that coroutines always be awaited seems to confirm this, but doesn't really say so explicitly. And the concurrent.futures can clearly be either, depending on your choices, but the chart in 18.5.3.1.3 Example: Chain coroutines is of a kind that I am more familiar with in the context of multiprocessing. (E.g., the only gap in the chart, which extends across all headings is when a result is being waited for during a sleep.) For threaded execution I would expect there to be a gap whenever processing is shifted from one column to another. If someone has authority to edit the documentation a comment like: If you want your application to make better use of the computational resources of multi-core machines, you are advised to use multiprocessing https://docs.python.org/3.5/library/multiprocessing.html#module-multiprocessing or concurrent.futures.ProcessPoolExecutor https://docs.python.org/3.5/library/concurrent.futures.html#concurrent.futures.ProcessPoolExecutor. However, threading is still an appropriate model if you want to run multiple I/O-bound tasks simultaneously. (to quote from the threading documentation) would be helpful at or very near the top of each of the appropriate modules. It would also be useful if the modules that were definitely intended to result in simultaneous execution, when feasible, were so marked quite near the top. OTOH, I may be mistaken about coroutines. I haven't been able to tell. P.S.: I do note that the threading comment was a *CPython implementation detail:*, and not a part of the Python specifications. But CPython is, I believe, a sufficiently dominant implementation that such details are quite important. -- https://mail.python.org/mailman/listinfo/python-list
Re: __next__ and StopIteration
On 02/09/2015 08:46 PM, Chris Angelico wrote: On Tue, Feb 10, 2015 at 3:33 PM, Charles Hixson charleshi...@earthlink.net wrote: The proper version of the hard way is: 1) The __iter__ method of the iterable constructs a new iterator instance and returns it. 2) The __iter__ method of the *iterator* simply returns itself. 3) The __next__ method of the iterator tracks the current value and returns the next value. Note that the iterator should never store the iterable's data internally, unless the iterable is immutable and the calculation is trivial (e.g. a range object). Instead, it should determine the next value by referring to its source iterable. So if I'm understanding this correctly, I should implement as an internal class within Grid something like: class GridIter(Iterator): Apart from the fact that you shouldn't have to explicitly subclass Iterator, yes. But this is the hard way to do things. The easy way is to simply define an __iter__ method on your Grid which returns an iterator - and one excellent form of iterator, for custom classes like this, is a generator object. Your original code can slot happily in, with one tiny change: class Grid: blah blah def __iter__(self): for row in range(self._rows): for col in range(self._cols): if self._grid[row][col]: yield self._grid[row][col] The only change is to remove the explicit StopIteration at the end; once your generator function terminates, the generator object will raise StopIteration forever afterward, without any help from you. (Also, post-PEP479, the explicit raise will actually cause RuntimeError, so it's not just superfluous, but actually a problem.) But I'm guessing that your grid and rows are actually iterable themselves. If they are, you can cut the code down to this: def __iter__(self): for row in self._grid: for cell in row: if cell: yield cell or a generator expression: def __iter__(self): return (cell for row in self._grid for cell in row if cell) or itertools.chain and filter, if you so desired. As long as you return an iterator, you're fine. This is far and away the easiest way to make a class iterable. ChrisA Yes, rows and cols are lists, but I'm going to need to iterate through them more than once. I'd rather do without a included class, but if a properly formed iterator can only be cycled through once, and if I understand properly that means I can't use the class instance is it's own iterator form. -- https://mail.python.org/mailman/listinfo/python-list
__next__ and StopIteration
I'm trying to write a correct iteration over a doubly indexed container, and what I've got so far is:def __next__ (self): for rowinrange(self._rows): for col in range(self._cols): if self._grid[row][col]: yieldself._grid[row][col] #endif #endfor col #endfor row raiseStopIteration What bothers me is that it doesn't look like it would continue to raise StopIteration if it were called again, which is what https://docs.python.org/3/library/stdtypes.html#iterator.__next__ says is correct. How should this be fixed? -- https://mail.python.org/mailman/listinfo/python-list
Re: __next__ and StopIteration
On 02/09/2015 03:56 PM, Ian Kelly wrote: On Mon, Feb 9, 2015 at 4:30 PM, Steven D'Aprano steve+comp.lang.pyt...@pearwood.info wrote: The way you write iterators is like this: Method 1 (the hard way): - Give your class an __iter__ method which simply returns self: def __iter__(self): return self - Give your class a __next__ method (`next` in Python 2) which *returns* a value. You will need to track which value to return yourself. It must raise StopIteration when there are no more values to return. Don't use yield. def __next__(self): value = self.value if value is None: raise StopIteration self.value = self.calculate_the_next_value() return value Your class is itself an iterator. This is an anti-pattern, so don't even suggest it. Iterables should never be their own iterators. Otherwise, your iterable can only be iterated over once! The proper version of the hard way is: 1) The __iter__ method of the iterable constructs a new iterator instance and returns it. 2) The __iter__ method of the *iterator* simply returns itself. 3) The __next__ method of the iterator tracks the current value and returns the next value. Note that the iterator should never store the iterable's data internally, unless the iterable is immutable and the calculation is trivial (e.g. a range object). Instead, it should determine the next value by referring to its source iterable. So if I'm understanding this correctly, I should implement as an internal class within Grid something like: class GridIter(Iterator): A class to iterate over the cells of a Grid instance Vars: row :: The row currently being iterated over. col :: Yhe column currently being iterated over. grid :: The grid instance being iterated over. def __init__ (self, grid): Params: grid :: The instance of the grid to iterate over. self.row=-1 self.col=-1 self.grid=grid #end__init__ def __iter__ (self): returnself def __next__ (self): if self.row == -1 and self.col == -1: self.row=0 self.col=0 elif self.col = grid.cols(): self.row=self.row + 1 self.col=0 if self.row grid.rows(): raiseStopIteration if not[row, col] in self.grid: returnself.__next__() returngrid(row, col) -- https://mail.python.org/mailman/listinfo/python-list
Multiprocessing process termination
In order to allow multiple processes to access a database (currently SQLite) I want to run the process in a separate thread. Because it will be accessed from multiple processes I intent to use Queues for shifting messages back and forth. But none of the individuals processes will know when all of the others are through. It there a way to properly close the database, or does it need to be done from the parent process? What I want to do is detect that a request to shutdown the Process has been received, and then execute a close procedure that cleans things up and shutdown. Terminate is the obvious procedure to use, but that comes with a warning not to use it if there is an queue attached (and without defining attached). OTOH, since the queue will never be read after the process has been shutdown, perhaps rendering it unusable is the proper thing. Could someone comment on this step of the design? The basic idea is: class handledb(Process): def __init__(self, q, otherstuff): self.q = q def run(self, msg): while (true): if self.q.empty(): sleep(someamountoftime) else: while (not self.q.empty()): read and parse message if message says to shutdown: self.shutdown() def shutdown(self): close things down ?? terminate ??-- should this be done while q is live? -- https://mail.python.org/mailman/listinfo/python-list
Re: Multiprocessing process termination
On 12/31/2014 01:18 PM, MRAB wrote: On 2014-12-31 19:33, Charles Hixson wrote: In order to allow multiple processes to access a database (currently SQLite) I want to run the process in a separate thread. Because it will be accessed from multiple processes I intent to use Queues for shifting messages back and forth. But none of the individuals processes will know when all of the others are through. It there a way to properly close the database, or does it need to be done from the parent process? What I want to do is detect that a request to shutdown the Process has been received, and then execute a close procedure that cleans things up and shutdown. Terminate is the obvious procedure to use, but that comes with a warning not to use it if there is an queue attached (and without defining attached). OTOH, since the queue will never be read after the process has been shutdown, perhaps rendering it unusable is the proper thing. Could someone comment on this step of the design? The basic idea is: class handledb(Process): def __init__(self, q, otherstuff): self.q = q def run(self, msg): while (true): if self.q.empty(): sleep(someamountoftime) else: while (not self.q.empty()): read and parse message if message says to shutdown: self.shutdown() def shutdown(self): close things down ?? terminate ??-- should this be done while q is live? The parent process could tell the db process to shutdown (by putting a message in the queue) when the child processes have terminated. Alternatively, the parent process could tell the db process how many child processes there are and then shutdown when it has received that many notifications from child processes that they have finished. BTW, it's better to let the queue read block until a message arrives than to keep polling and sleeping if it's empty. Thanks. This design already depends on the parent process telling the db process when to shut down, but this depends on the queue (which is, I think, attached to the process) and so I am uncertain about calling terminate, as the docs say this can be expected to corrupt the queue. I'm hoping that this isn't a problem if the db process is the only reader of the queue, and this shouldn't happen until after all other writers to the queue have finished. But the documentation has made me uneasy on this point. A blocking read is better? OK, that's an easy change, and seems quite reasonable. But its the termination that I was worried about. (This is only one use out of several similar cases, and I'd like to use the same pattern throughout, so I'd really rather get it right the first time. Particularly as MP programs won't necessarily throw the error predictably.) -- https://mail.python.org/mailman/listinfo/python-list
multiprocessing vs. asyncio.SubprocessProtocol
What are the tradeoffs between using multiprocessing vs. using asyncio.SubprocessProtocol? This only one that I've noticed is that asyncio seems to require much more hands-on management of message queueing. OTOH, I'm no expert in either of them, and I might be missing something that will bite me later. OTOH, I could do the whole thing with a TCP/IP peer-to-peer setup on localhost. And that's much easier to figure out. (Each process has one input queue, and runs until it receives a message telling it to die. JSON is all I need for serialization...though ast.literal_eval would work as well.) So I guess I also want to know whether there's any advantage in using multiprocessing vs using a datagram transmission over localhost. (That clearly has the advantage that it makes it easier to grow to multiple machines.) -- https://mail.python.org/mailman/listinfo/python-list
multiprocessing problem: queue.get() not finding pushed values
I don't think I can reduce it much beyond this. I'm trying to run Sqlite in a separate process, but I'm running into problems. *The code:* from collectionsimportnamedtuple from multiprocessing import Process, Queue, current_process from queue import Empty, Full Msg=namedtuple (Msg, ['act', 'id', 'vals']) DBW_to=Queue() DBW_from=Queue() class DBW (Process): def __init__ (self, qin, qout): self.qin=qin self.qout=qout super (DBW, self).__init__() def run (self): msg=self.qin.get(True, 3) print (msg = {0}.format(repr(msg) ) ) if __name__ == __main__: dbw=DBW(DBW_to, DBW_from) dbw.run() DBW_to.put(Msg(a, 1, wrd) ) DBW_to.put(Msg(b, 2, wrd) ) DBW_to.put(Msg(c, 0, None) ) *The result:* Traceback (most recent call last): File test7a.py, line 23, in module dbw.run() File test7a.py, line 18, in run msg=self.qin.get(True, 3) File /usr/lib/python3.4/multiprocessing/queues.py, line 107, in get raise Empty queue.Empty *$ python3 --version* Python 3.4.1 *The system:* Linux 3.14-1-amd64 -- https://mail.python.org/mailman/listinfo/python-list
Re: Proper deletion of selected items during map iteration in for loop: Thanks to all
On 04/25/2014 10:53 AM, Charles Hixson wrote: What is the proper way to delete selected items during iteration of a map? What I want to do is: for (k, v) in m.items(): if f(k): # do some processing of v and save result elsewhere del m[k] But this gives (as should be expected): RuntimeError: dictionary changed size during iteration In the past I've accumulated the keys to be deleted in a separate list, but this time there are likely to be a large number of them, so is there some better way? Going over the various responses, it looks like saving the to be deleted keys to a list, and then iterating over that to delete is the best answer. I expect that I'll be deleting around 1/3 during each iteration of the process...and then adding new ones back in. There shouldn't be a really huge number of deletions on any particular pass, but it will be looped through many times...so if there were any better way to do this, it would speed things up considerably...but it's not really surprising that there doesn't appear to be. So now it translates into (approximately, not yet tested): toDel = [] for (k, v) in m.items(): if f(k): # do some processing of v and save result elsewhere toDel.append(k) else: # do something else for k in toDel: del m[k] toDel = None -- Charles Hixson -- https://mail.python.org/mailman/listinfo/python-list
Proper deletion of selected items during map iteration in for loop
What is the proper way to delete selected items during iteration of a map? What I want to do is: for (k, v) in m.items(): if f(k): # do some processing of v and save result elsewhere del m[k] But this gives (as should be expected): RuntimeError: dictionary changed size during iteration In the past I've accumulated the keys to be deleted in a separate list, but this time there are likely to be a large number of them, so is there some better way? -- Charles Hixson -- https://mail.python.org/mailman/listinfo/python-list
http://bugs.python.org/user?@template=rego_progress broken?
I have tried to register at http://bugs.python.org, and got as far as this page, where I am told: You will shortly receive an email to confirm your registration. To complete the registration process, visit the link indicated in the email. But it hasn't arrived after over a day. This case isn't too important, as I was just going to request a documentation change, but it happening may be more important than what I would have entered. -- Charles Hixson -- https://mail.python.org/mailman/listinfo/python-list
1st Sketch at at ReadOnly dict
This is just a first sketch, and I haven't yet attempted to test it, so what I'm hoping for is criticisms on the general approach. ##Read Only dict class. #@note Instances can be created only from existing dicts. #@warningvalues within the RODict can be accessed, so if they hold #references to other items, they can be altered. class RODict: #Instance Variable Doc ##@var_ddict #This variable holds the reference to the dict. ##Class initializer. #@paramddictThe data dictionary to which this is a read only #access. #@throwsTypeError if ddict is not a dict. def __init__ (self, ddict = {}): if not isinstance(ddict, dict): raiseTypeError(ddict must be a dict. It is + repr(ddict)) self._ddict=ddict ##Test for containment. #@paramkeyThe item to be found. #@returnTrueIf key is in the instance, otherwise False. def __contains__(self, key): returnkey in self._ddict ##Pass along the __getitem call. def __getitem__(self, key): returnself._ddict.__getitem__(key) ##Pass along the get call. def get (self, key, default = None): returnself._ddict.get(key, default) ##Return a DictView of the items of the instance. def items(self): returnself._ddict.items() ##Return a DictView of the keys of the instance. def keys(self): returnself._ddict.keys() ##Return a DictView of the values of the instance. def values(self): returnself._ddict.values() ##Return the length of the dict. def __len__(self): returnlen(self._ddict) -- Charles Hixson -- https://mail.python.org/mailman/listinfo/python-list
Re: 1st Sketch at at ReadOnly dict
On 01/20/2014 12:52 PM, Peter Otten wrote: Charles Hixson wrote: This is just a first sketch, and I haven't yet attempted to test it, so what I'm hoping for is criticisms on the general approach. class RODict: def __init__ (self, ddict = {}): Default values are evaluted just once when the method is created. Mutable default values mean trouble: class D: ... def __init__(self, dict={}): ... self.dict = dict ... def __setitem__(self, key, value): ... self.dict[key] = value ... def __repr__(self): return repr(self.dict) ... d1 = D() d2 = D() d1[1] = 42 d2[2] = 42 d1 {1: 42, 2: 42} d2 {1: 42, 2: 42} if not isinstance(ddict, dict): raiseTypeError(ddict must be a dict. It is + repr(ddict)) self._ddict=ddict I think instead of the type check I would build a new dict from the argument. The usual initializers dict({1:2, 3:4}) dict([(1,2), (3,4)]) dict(a=1, b=2) should work with your read-only dict. ##Test for containment. #@paramkeyThe item to be found. #@returnTrueIf key is in the instance, otherwise False. Docstrings are usually prefered over comments like the above. def __contains__(self, key): returnkey in self._ddict Did you know http://docs.python.org/dev/library/collections.abc.html#collections.abc.Mapping Subclass from it to ensure that all the usuall methods are defined. That link, http://docs.python.org/dev/library/collections.abc.html#collections.abc.Mapping , is a very good one. I hadn't realized that it separated Mapping from MutableMapping. It would be nice if there were some examples of it's usage around, though. I can't really tell how to use it. (E.g., it mixes in __contains__, but it doesn't show how to specify what you are testing for cotainment in. So it looks as if I need to specify everything anyway because I can't tell what might be implemented in some inappropriate way.) OTOH, it's a good list of what needs to be implemented. (I see that I left out implementation of eq and ne, which is pretty straightfoward, but apparently needed (unless it's automatically being handled by the mixin...which I can't tell). -- Charles Hixson -- https://mail.python.org/mailman/listinfo/python-list
Re: 1st Sketch at at ReadOnly dict
On 01/20/2014 04:08 PM, Chris Angelico wrote: On Tue, Jan 21, 2014 at 7:09 AM, Charles Hixson charleshi...@earthlink.net wrote: #@note Instances can be created only from existing dicts. ##Class initializer. #@paramddictThe data dictionary to which this is a read only #access. #@throwsTypeError if ddict is not a dict. def __init__ (self, ddict = {}): if not isinstance(ddict, dict): raiseTypeError(ddict must be a dict. It is + repr(ddict)) self._ddict=ddict Instead of demanding that a dict (or dict subclass) be passed, why not simply pass all args on to dict() itself? Is there a reason this won't work? def __init__(self, *args, **kwargs): self._ddict = dict(*args, **kwargs) ChrisA It would work, as long as it would work for dict(), but I have been expecting to use it in situations where it would be useful to have a different access to the dict that would be writeable. So I didn't bother. (Well, and took steps to ensure that it was being used in the manner that I expected. So I'd know to change it if it were appropriate.) It *would* make it more difficult for the class to test it's creation arguments for sanity, though. (One could argue that allowing read only access to an empty dict is violating sanity, but I don't think in any dangerous way.) I do sometimes worry that using isinstance excessively is overly expensive. Perhaps I should wrap them with a test for debug mode. -- Charles Hixson -- https://mail.python.org/mailman/listinfo/python-list
Re: 1st Sketch at at ReadOnly dict
On 01/20/2014 08:14 PM, Dan Stromberg wrote: On Mon, Jan 20, 2014 at 12:09 PM, Charles Hixson charleshi...@earthlink.net wrote: class RODict: #Instance Variable Doc ##@var_ddict #This variable holds the reference to the dict. ##Class initializer. #@paramddictThe data dictionary to which this is a read only #access. #@throwsTypeError if ddict is not a dict. def __init__ (self, ddict = {}): if not isinstance(ddict, dict): raiseTypeError(ddict must be a dict. It is + repr(ddict)) self._ddict=ddict When I see this isinstance, I think Gee, that means none of the dict-like-objects I recently compared would work with this class. The comparison is at the URL below; all the things compared are trees that provide a dictionary-like interface, but also find_min, find_max and can iterate in key order. I don't think any of them inherit from dict, but they are all dict-like in a duck-typed sense: http://stromberg.dnsalias.org/~strombrg/python-tree-and-heap-comparison/2014-01/ HTH Well, it would mean you couldn't create instances of this class from them. I haven't yet specified the eq and ne methods, but they'd probably be something like: def ne(self, key): return self._ddict.ne(key) (I'd need to look up the precise names of the comparison routines. Perhaps it would be __ne__ rather than ne.) So if they'd work with a normal dict, they should work with this, for comparison. Note that this is a dict-alike, and therefore not in a predictable order. If the items were to be ordered, however, they would be in order by the value rather than by the key, as my use-case is most likely to want to access the items with the highest value most often. I may even decide to use a list of lists, but a dict yields simpler code, even if I suspect that lists might be more efficient. But the choice of list would mean I could use a tuple, which because it is standard would also tend to make things simpler. (It wouldn't, however, allow background updating, as dictviews do, and also RODict does, so I'd need to find some way to manage that...probably meaning that I'd need to regenerate them more often.) -- Charles Hixson -- https://mail.python.org/mailman/listinfo/python-list
Documentation of dict views change request
Could it please be clearly documented that keys(), values(), and items() are not writeable. I agree that this is how they should be, but it would be still better if they were clearly documented as such. The labeling of them as dynamic, while true, was a bit confusing here. (I.e., it was talking about changing their value through other means of access rather than directly through the returned values.) P.S.: Is it reasonable to return the items() of a dict in order to pass a read only copy of the values? -- Charles Hixson -- https://mail.python.org/mailman/listinfo/python-list
Re: converting letters to numbers
On 10/13/2013 10:02 PM, Steven D'Aprano wrote: On Sun, 13 Oct 2013 20:13:32 -0700, Tim Roberts wrote: def add(c1, c2): % Decode c1 = ord(c1) - 65 c2 = ord(c2) - 65 % Process i1 = (c1 + c2) % 26 % Encode return chr(i1+65) Python uses # for comments, not %, as I'm sure you know. What language were you thinking off when you wrote the above? IIRC Lisp uses % for comments, but it may need to be doubled. (It's been doubled in the examples I've seen, and I don't remember the syntax.) Perhaps Scheme has the same convention, but Scheme could be considered a part of the Lisp clade. -- Charles Hixson -- https://mail.python.org/mailman/listinfo/python-list
Re: class-private names and the Zen of Python
On 10/08/2013 06:24 AM, Steven D'Aprano wrote: On Tue, 08 Oct 2013 12:13:48 +0200, Marco Buttu wrote: In the following case: class Foo: ... _Foo__a = 100 ... __a = 33 ... Foo._Foo__a 33 I think this behavior, for a user who does not know the convention, could be a surprise. Yes, you are correct. It surprised me, and I've been using Python for more than 15 years, and I know the convention of double-underscore name- mangling. Should be raising an exception (in order to inform the user the transformation of the name __a have been replaced an existing name) a possible --explicit-- alternative? No, I don't think so. That would slow down class creation, for no real benefit. Except for the name-mangling part, this is no different from: class Spam: x = 23 x = 42 If anything, something like PyLint or PyChecker could warn about it. But the language itself is fine like it is. Another question is: where is the place in which this transformation occurs? Is it at the parser level, before the dictionary attribute is gave as argument to the metaclass? Good question! I don't have a full answer, but I have a part answer: it occurs before the metaclass sees the namespace: py class Meta(type): ... def __new__(meta, name, bases, namespace): ... print(namespace) ... return super().__new__(meta, name, bases, namespace) ... py py class Test(metaclass=Meta): ... __test = 'foo' ... {'__module__': '__main__', '_Test__test': 'foo', '__qualname__': 'Test'} so I think it is done by the parser. Unless one wanted to add an error checking mode to the interpreter, not a totally bad idea, I agree that this is a job for external tools. But perhaps that same external tool should be referenced in the documentation. As it is I'm not clear that PyLint and/or PyChecker are kept current with the compiler/interpreter version, and I rather suspect that they aren't. (This won't normally show up, as changes that they would catch happen quite rarely, but...) OTOH, neither one really fits in as, say, an included module...they're more like idle, which now that I look does have a check module run option. Perhaps that invokes one of them. I note that Idle, itself, is barely mentioned in the documentation. Perhaps there needs to be a tools section. -- Charles Hixson -- https://mail.python.org/mailman/listinfo/python-list
Re: Tail recursion to while iteration in 2 easy steps
is to be used. As such, there can be no single mapping from English into the machine, which is why there are so many different languages and experiments that map your [English] concepts into source code. And there is no single mapping from INSERT **ANY** HIGH-LEVEL PROGRAMMING LANGUAGE HERE source code to machine code either. I would assert that Python is not inherently a virtual machine language. Originally, IIRC, it was believed that LISP couldn't be compiled. Also, you could implement that virtual machine as a hardware machine. (Also, of course, on modern hardware assembly language is run on a virtual machine, implemented by an underneath microcode layer.) You can reasonably say that an implementation of Python is done in terms of a virtual machine. (Usually I don't bother about this kind of nit-pick, but in this discussion it seems apropos.) -- Charles Hixson -- https://mail.python.org/mailman/listinfo/python-list
Re: Threadpool item mailboxes design problem
On 04/14/2013 07:32 PM, Chris Rebert wrote: On Apr 14, 2013 4:27 PM, Charles Hixson charleshi...@earthlink.net mailto:charleshi...@earthlink.net wrote: What is the best approach to implementing actors that accept and post messages (and have no other external contacts). You might look at how some of the existing Python actor libraries are implemented (perhaps one of these might even save you from reinventing the wheel): http://www.pykka.org/en/latest/ http://www.kamaelia.org/Docs/Axon/Axon.html https://pypi.python.org/pypi/pulsar Kinda old: http://candygram.sourceforge.net/contents.html http://osl.cs.uiuc.edu/parley/ Candygram looks interesting. I'd forgotten about it. The others look either a bit limited (in different ways), or overly general, with the costs that that brings. I'll need to study Candygram a bit more. However, even Candygram seems to have a RAM centric model that I'd need to work around. (Well, the mailbox synchronization must clearly be RAM centric, but the storage shouldn't be.) So far what I've come up with is something like: actors = {} mailboxs = {} Stuff actors with actor instances, mailboxes with multiprocessing.queue instances. (Actors and mailboxes will have identical keys, which are id#, but it's got to be a dict rather than a list, because too many are rolled out to disk.) And I'm planning of having the actors running simultaneously and continually in a threadpool that just loops through the actors that are assigned to each thread of the pool. snip It would, however, be better if the mailbox could be specific to the threadpool instance, so less space would be wasted. Or if the queues could dynamically resize. Or if there was a threadsafe dict. Or... But I don't know that any of these are feasible. (I mean, yes, I could write all the mail to a database, but is that a better answer, or even a good one?) My recollection is that the built-in collection types are threadsafe at least to the limited extent that the operations exposed by their APIs (e.g. dict.setdefault) are atomic. Perhaps someone will be able to chime in with more details. If list operations were threadsafe, why would multiprocessing.queue have been created? I don't recall any claim that they were. Still, I've found an assertion on StackOverflow that they are...at least for simple assignment and reading. And the same would appear to be true of dicts from that post. This *does* require that either the index be constant, and the stored value be constant, or that the code section be locked during the access. Fortunately I'm intending to have id#s be unchangable, and the messages to be tuples, and thus constant. OTOH, to use this approach I'll need to find some way to guarantee that removing messages and posting messages don't occur at the same time. So that still means I'll need to lock each access. The answer that seems best is for each thread to have a mailbox that cells within the thread post and read messages from. This will automatically deal with internal to thread synchronization. Then I'll need a mailman thread that... This seems a promising approach, that avoids the problem of fixed length queues, but I'll still need to do a lot of synchronization. Still, it's a lot less, and each thread would be locked for shorter amounts of time. -- Charles Hixson -- http://mail.python.org/mailman/listinfo/python-list
Re: Threadpool item mailboxes design problem
On 04/15/2013 10:14 AM, Charles Hixson wrote: On 04/14/2013 07:32 PM, Chris Rebert wrote: On Apr 14, 2013 4:27 PM, Charles Hixson charleshi...@earthlink.net mailto:charleshi...@earthlink.net wrote: What is the best approach to implementing actors that accept and post messages (and have no other external contacts). You might look at how some of the existing Python actor libraries are implemented (perhaps one of these might even save you from reinventing the wheel): http://www.pykka.org/en/latest/ http://www.kamaelia.org/Docs/Axon/Axon.html https://pypi.python.org/pypi/pulsar Kinda old: http://candygram.sourceforge.net/contents.html http://osl.cs.uiuc.edu/parley/ Candygram looks interesting. I'd forgotten about it. The others look either a bit limited (in different ways), or overly general, with the costs that that brings. I'll need to study Candygram a bit more. However, even Candygram seems to have a RAM centric model that I'd need to work around. (Well, the mailbox synchronization must clearly be RAM centric, but the storage shouldn't be.) So far what I've come up with is something like: actors = {} mailboxs = {} Stuff actors with actor instances, mailboxes with multiprocessing.queue instances. (Actors and mailboxes will have identical keys, which are id#, but it's got to be a dict rather than a list, because too many are rolled out to disk.) And I'm planning of having the actors running simultaneously and continually in a threadpool that just loops through the actors that are assigned to each thread of the pool. snip It would, however, be better if the mailbox could be specific to the threadpool instance, so less space would be wasted. Or if the queues could dynamically resize. Or if there was a threadsafe dict. Or... But I don't know that any of these are feasible. (I mean, yes, I could write all the mail to a database, but is that a better answer, or even a good one?) My recollection is that the built-in collection types are threadsafe at least to the limited extent that the operations exposed by their APIs (e.g. dict.setdefault) are atomic. Perhaps someone will be able to chime in with more details. If list operations were threadsafe, why would multiprocessing.queue have been created? I don't recall any claim that they were. Still, I've found an assertion on StackOverflow that they are...at least for simple assignment and reading. And the same would appear to be true of dicts from that post. This *does* require that either the index be constant, and the stored value be constant, or that the code section be locked during the access. Fortunately I'm intending to have id#s be unchangable, and the messages to be tuples, and thus constant. OTOH, to use this approach I'll need to find some way to guarantee that removing messages and posting messages don't occur at the same time. So that still means I'll need to lock each access. The answer that seems best is for each thread to have a mailbox that cells within the thread post and read messages from. This will automatically deal with internal to thread synchronization. Then I'll need a mailman thread that... This seems a promising approach, that avoids the problem of fixed length queues, but I'll still need to do a lot of synchronization. Still, it's a lot less, and each thread would be locked for shorter amounts of time. -- Charles Hixson Currently it looks as if Pyro is the best option. It appears that Python threads are very contentious, so I'll need to run in processes rather than in threads, but I'll still need to transfer messages back and forth. I'll probably use UnixSockets rather than IP, but this could change...and using Pyro would make changing it easy. Still, pickle is used in code transmission, and that makes IP a questionable choice. -- Charles Hixson -- http://mail.python.org/mailman/listinfo/python-list
Threadpool item mailboxes design problem
What is the best approach to implementing actors that accept and post messages (and have no other external contacts). So far what I've come up with is something like: actors = {} mailboxs = {} Stuff actors with actor instances, mailboxes with multiprocessing.queue instances. (Actors and mailboxes will have identical keys, which are id#, but it's got to be a dict rather than a list, because too many are rolled out to disk.) And I'm planning of having the actors running simultaneously and continually in a threadpool that just loops through the actors that are assigned to each thread of the pool. This lets any actor post messages to the mailbox of any other actor that it has the id of, and lets him read his own mail without multi-processing clashes. But I'm quite uncertain that this is the best way, because, if nothing else, it means that each mailbox needs to be allocated large enough to handle the maximum amount of mail it could possibly receive. (I suppose I could implement some sort of wait awhile and try again method.) It would, however, be better if the mailbox could be specific to the threadpool instance, so less space would be wasted. Or if the queues could dynamically resize. Or if there was a threadsafe dict. Or... But I don't know that any of these are feasible. (I mean, yes, I could write all the mail to a database, but is that a better answer, or even a good one?) -- Charles Hixson -- http://mail.python.org/mailman/listinfo/python-list
Sphinx highlighting
What controls the yellow highlight bar that Sphinx sometimes puts in the documentation? E.g.: .. py:function:: basic_parseStrTest () generates bold-face text, where .. py:function:: basicParseStrTest () generates text with a yellow bar highlight. I actually rather like the yellow bar highlight, but I can't stand having it appear for some of my functions, and not for others, and I haven't been able to figure out what turns it on or off. -- Charles Hixson -- http://mail.python.org/mailman/listinfo/python-list
Re: bit count or bit set Python3
cas...@gmail.com wrote: On Thursday, October 25, 2012 7:56:25 AM UTC-7, Charles Hixson wrote: In Python3 is there any good way to count the number of on bits in an integer (after an operation)? You may want to look at gmpy2[1] and the popcount() function. Alternatively, is there any VERY light-weight implementation of a bit set? I'd prefer to use integers, as I'm probably going to need thousands of these, if the tests work out. But before I can test, I need a decent bit counter. (shift, xor,, and | are already present for integer values, but I also need to count the number of true items after the logical operation. So if a bitset is the correct approach, Whether or not gmpy2 is considered light-weight is debateable. :) I'll need it to implement those operations, or their equivalents in terms of union and intersection.) Or do I need to drop into C for this? [1] http://code.google.com/p/gmpy/ -- Charles Hixson I can see many times when that would be useful, but for this particular case I think that bin(val).count(1) is probably the better solution. The other options that I need are already available directly in integer numbers, and I will be surprised if I need more than a 32-bit set, so integers should be a reasonable approach. It doesn't seem to have the overhead that I feared a string conversion would have (possibly because converting an integer to a bit string is trivial), so I don't think that gmpy would add value to this program. Next I need to decide about weak pointers, and then shelve vs. tokyocabinet. (I sort of don't like shelve, because of its use of pickle, with the attendent security risks. OTOH, the file will be local to the computer, not going over the net, which minimizes that. Still, I may decide to reimplement it using ast.literal_eval, as I'm not intending to store anything that it won't handle. -- http://mail.python.org/mailman/listinfo/python-list
bit count or bit set Python3
In Python3 is there any good way to count the number of on bits in an integer (after an operation)? Alternatively, is there any VERY light-weight implementation of a bit set? I'd prefer to use integers, as I'm probably going to need thousands of these, if the tests work out. But before I can test, I need a decent bit counter. (shift, xor, , and | are already present for integer values, but I also need to count the number of true items after the logical operation. So if a bitset is the correct approach, I'll need it to implement those operations, or their equivalents in terms of union and intersection.) Or do I need to drop into C for this? -- Charles Hixson -- http://mail.python.org/mailman/listinfo/python-list
bit count or bit set Python3
In Python3 is there any good way to count the number of on bits in an integer (after an operation)? Alternatively, is there any VERY light-weight implementation of a bit set? I'd prefer to use integers, as I'm probably going to need thousands of these, if the tests work out. But before I can test, I need a decent bit counter. (shift, xor, , and | are already present for integer values, but I also need to count the number of true items after the logical operation. So if a bitset is the correct approach, I'll need it to implement those operations, or their equivalents in terms of union and intersection.) Or do I need to drop into C for this? -- Charles Hixson -- http://mail.python.org/mailman/listinfo/python-list
Re: bit count or bit set Python3
On 10/25/2012 08:57 AM, Steven D'Aprano wrote: On Fri, 26 Oct 2012 02:31:53 +1100, Chris Angelico wrote: On Fri, Oct 26, 2012 at 2:25 AM, Christian Heimeschrist...@python.org wrote: Simple, easy, faster than a Python loop but not very elegant: bin(number).count(1) Unlikely to be fast. Oh I don't know about that. Here's some timing results using Python 2.7: py from timeit import Timer py t = Timer('bin(number).count(1)', setup='number=2**10001-1') py min(t.repeat(number=1, repeat=7)) 0.6819710731506348 Compare to MRAB's suggestion: def count_set_bits(number): count = 0 while number: count += 1 number= number - 1 return count py t = Timer('count_set_bits(number)', ... setup='from __main__ import count_set_bits; number=2**10001-1') py min(t.repeat(number=100, repeat=7)) 4.141788959503174 That makes the inelegant solution using bin() and count() about 600 times faster than the mathematically clever solution using bitwise operations. On the other hand, I'm guessing that PyPy would speed up MRAB's version significantly. Really nice and good to know. I had guessed the other way. (As you point out this is compiler dependent, and I'll be using Python3, but...conversion from an int to a bit string must be a *lot* faster than I had thought.) -- Charles Hixson -- http://mail.python.org/mailman/listinfo/python-list
bit count or bit set Python3
In Python3 is there any good way to count the number of on bits in an integer (after an operation)? Alternatively, is there any VERY light-weight implementation of a bit set? I'd prefer to use integers, as I'm probably going to need thousands of these, if the tests work out. But before I can test, I need a decent bit counter. (shift, xor, , and | are already present for integer values, but I also need to count the number of true items after the logical operation. So if a bitset is the correct approach, I'll need it to implement those operations, or their equivalents in terms of union and intersection.) Or do I need to drop into C for this? -- Charles Hixson -- http://mail.python.org/mailman/listinfo/python-list
'generator ignored GeneratorExit''
If I run the following code in the same module, it works correctly, but if I import it I get the message: Exception RuntimeError: 'generator ignored GeneratorExit' in generator object getNxtFile at 0x7f932f884f50 ignored def getNxtFile (startDir, exts = [txt, utf8]): try: forpathingetNxtPath (startDir, exts): try: fil=open (path, encoding = utf-8-sig) yieldfil except: print (Could not read: , path) exceptGeneratorExit: raiseStopIteration The message appears to be purely informational, but I *would* like to fix whatever problem it's reporting, and none of the changes that I've tried have worked. What *should* I be doing? -- Charles Hixson -- http://mail.python.org/mailman/listinfo/python-list
Re: 'generator ignored GeneratorExit''
On 10/20/2012 04:28 PM, Ian Kelly wrote: On Sat, Oct 20, 2012 at 2:03 PM, Charles Hixson charleshi...@earthlink.net wrote: If I run the following code in the same module, it works correctly, but if I import it I get the message: Exception RuntimeError: 'generator ignored GeneratorExit' ingenerator object getNxtFile at 0x7f932f884f50 ignored def getNxtFile (startDir, exts = [txt, utf8]): try: forpathingetNxtPath (startDir, exts): try: fil=open (path, encoding = utf-8-sig) yieldfil except: print (Could not read: , path) exceptGeneratorExit: raiseStopIteration The message appears to be purely informational, but I *would* like to fix whatever problem it's reporting, and none of the changes that I've tried have worked. What *should* I be doing? The bare except is probably catching the GeneratorExit exception and swallowing it. Try catching a more specific exception like OSError or even just Exception instead. Also, you don't need to explicitly catch GeneratorExit just to raise StopIteration. The generator will normally stop on GeneratorExit, provided the exception is actually able to propagate up. Thank you. That was, indeed the problem. Removing all the try ... excepts made it work on my test case. Now I've got to figure out what to catch in case it's not a utf8 file. I guess that I'll hope that IOError will work, as nothing else sounds reasonable. It's general enough that it ought to work. -- Charles Hixson -- http://mail.python.org/mailman/listinfo/python-list
Re: exception problem
On 06/25/2012 12:48 AM, Steven D'Aprano wrote: On Sun, 24 Jun 2012 16:16:25 -0700, Charles Hixson wrote: But what I wanted was to catch any exception. Be careful of what you ask for, since you might get it. Catch any exception is almost certainly the wrong thing to do, almost always. The one good reason I've seen for a bare except is to wrap the top level of an application in order to redirect uncaught exceptions to something other than the console (such as a GUI error dialog box). And even then, you probably don't want to catch *all* exceptions, but only those that inherit from Exception: try: main() # run my application except Exception as err: display_error_dialog(err) # or log to a file, or something... This time it was the right thing, as I suspected that *SOME* exception was being thrown, but had no idea what one. The problem was I didn't know how to print the result when I caught the exception. This has since been cleared up, but first I found it on Google, and then I was told about it on the list. The documentation left me totally ... well, not uninformed, but confused. As I said it turned out to be a method call on an uninitialized variable, as I found out once I figured out how to list the result of catching the exception. Which is what I expected the documentation to show me how to do. The comments on the list have been vastly helpful, even if they still tend to assume that I know more than I do. (And even if some of them seem to be a bit ... off. E.g., suggesting that I generate the exception on purpose so I can find out what it is, when I started off with no idea as to WHAT the problem was.) What really annoys me is the way the documentation has worsened since python 2.5, but if you know what it is trying to tell you, then I guess you aren't bothered by undefined terms and lack of examples. I went away from programming in Python for a couple of years though, and I guess I missed the transition, or something. -- Charles Hixson -- http://mail.python.org/mailman/listinfo/python-list
Re: exception problem
On 06/24/2012 11:23 PM, Andrew Berg wrote: On 6/25/2012 12:27 AM, Charles Hixson wrote: The documentation section covering the except statement could stand to be a *LOT* clearer. I read the sections on the except statement and exception handlers several times and couldn't figure out was the as argument of the except statement was for. I agree that the tutorial doesn't explain the use of as very well, but it does cover that a bare except is not normally good to use: The last except clause may omit the exception name(s), to serve as a wildcard. Use this with extreme caution, since it is easy to mask a real programming error in this way! I still don't really know what as means, except that if you use it, and you print out the target, you'll get some kind of informative message. as lets you refer to the exception object that was caught. I find this useful mainly for exceptions that have attributes (most built-in exceptions don't, but many user-defined exceptions do). A full traceback is much more useful for debugging than what a simple print(exc) will give. There are a few different ways to get traceback information without letting the exception simply propagate and terminate the program. You can get some simple information from sys.exc_info() (and you can feed the traceback object to a function in the traceback module), or you can log it with the logging.exception() function or the exception() method of a Logger from the same module. I recommend using logging. However, it's generally best to just let any unexpected exceptions propagate unless the program absolutely must continue, especially when debugging. I read that that would happen, but print (sys.exc_info()[:2]) didn't even yield a blank line. It must have executed, because the print statement on the line before it executed, and there wasn't a loop or a jump (and also execution continued normally [the code still has bugs] afterward even if the finally isn't included). -- Charles Hixson -- http://mail.python.org/mailman/listinfo/python-list
exception problem
The code: print(pre-chunkLine) chunks=[] try: chunks=self.chunkLine (l) except: print(caught exception) print (sys.exc_info()[:2]) finally: print (at finally) print (chunks =) print (repr(chunks), ., end = :) produces this result: . . ., by pre-chunkLine caught exception at finally path 3... Any suggestions as to what's wrong with the code? FWIW, chunkLine begins: def chunkLine (self, line): print(chunkLine: ) print (line = , line) ifline == None: return[] assert(isinstance (line, str) ) -- Charles Hixson -- http://mail.python.org/mailman/listinfo/python-list
Re: exception problem
Sorry, I left out: er$ python3 --version Python 3.2.3rc1 On 06/24/2012 03:26 PM, Charles Hixson wrote: The code: print(pre-chunkLine) chunks=[] try: chunks=self.chunkLine (l) except: print(caught exception) print (sys.exc_info()[:2]) finally: print (at finally) print (chunks =) print (repr(chunks), ., end = :) produces this result: . . ., by pre-chunkLine caught exception at finally path 3... Any suggestions as to what's wrong with the code? FWIW, chunkLine begins: def chunkLine (self, line): print(chunkLine: ) print (line = , line) ifline == None: return[] assert(isinstance (line, str) ) -- Charles Hixson -- http://mail.python.org/mailman/listinfo/python-list
Re: exception problem
On 06/24/2012 03:43 PM, MRAB wrote: On 24/06/2012 23:26, Charles Hixson wrote: The code: print(pre-chunkLine) chunks=[] try: chunks=self.chunkLine (l) except: print(caught exception) print (sys.exc_info()[:2]) finally: print (at finally) print (chunks =) print (repr(chunks), ., end = :) produces this result: . . ., by pre-chunkLine caught exception at finally path 3... Any suggestions as to what's wrong with the code? FWIW, chunkLine begins: def chunkLine (self, line): print(chunkLine: ) print (line = , line) ifline == None: return[] assert(isinstance (line, str) ) Don't use a bare except; it'll catch _any__exception. Catch only what you expect. For all I know, it could be that the name l doesn't exist. But what I wanted was to catch any exception. A problem was happening and I had no clue as to what it was. (It turned out to be self is not defined. A silly mistake, but a real one.) The odd thing was that if I ran it without the try block, I didn't get any exceptions at all. (Which I clearly should have, except that since self wasn't defined, I'd usually expect the interpreter to detect the error before trying to execute the code.) -- Charles Hixson -- http://mail.python.org/mailman/listinfo/python-list
Re: exception problem
On 06/24/2012 03:43 PM, Charles Hixson wrote: On 06/24/2012 03:36 PM, Chris Angelico wrote: On Mon, Jun 25, 2012 at 8:26 AM, Charles Hixson charleshi...@earthlink.net wrote: The code: finally: print (at finally) print (chunks =) produces this result: path 3... Can you state more clearly the problem, please? I'm seeing output that can't have come from the code posted (for instance, immediately after the at finally, I'm expecting to see the chunks = line), and I'm not seeing any exception information, so I can't even hazard a guess as to what's throwing the exception. Presumably these are two methods in the same class, since you're calling it as self.chunkLine, but beyond that, it's hard to know. Take off the try/except and let your exception go to console, that's usually the easiest thing to deal with. Chris Angelico Sorry, but it *DID* come from the code posted. Which is why I was so confused. I finally tracked it down to self was not defined by altering the except section to read: except BaseException as ex: print(caught exception) print (ex) finally: print (at finally) The documentation section covering the except statement could stand to be a *LOT* clearer. I read the sections on the except statement and exception handlers several times and couldn't figure out was the as argument of the except statement was for. Target doesn't communicate much to me. The one I finally used as indicated above was modified from some code that I found through Google. I still don't really know what as means, except that if you use it, and you print out the target, you'll get some kind of informative message. (The one that I got said self was not defined .. that's a paraphrase. I can't remember the precise wording.) And that interpretation is based on what the result was, not on anything said in the documentation. IIRC, the Python2 documentation used code examples to indicate what was the right way to write an exception handler. I realize that Python3 is much different, but that approach was a very good one. -- Charles Hixson -- http://mail.python.org/mailman/listinfo/python-list
Unexpected exception thrown in __del__
message excerpt: flush: sql = insert or replace into persists (id, name, data, rdCnt, rdTim, wrCnt, wrTim, deprecation) values (?, ?, ?, ?, ?, ?, ?, ?) Exception TypeError: 'NoneType' object is not callable in bound method Shelve2.__del__ of __main__.Shelve2 object at 0x7ff4c0513f90 ignored flush is being called from within __del__. I've narrowed it down to: print (flush: sql = , sql) curTim=nowI() print (flush: curTim = , curTim) nowI() is a function defined at the top of the file, and before the class, thus: defnowI(): t=int (time() * 100) returnt All I can guess is that there's some reason that an external to the class function shouldn't be called during a __del__. Is this correct? -- Charles Hixson -- http://mail.python.org/mailman/listinfo/python-list
Re: Unexpected exception thrown in __del__
On 05/21/2012 08:29 AM, Charles Hixson wrote: message excerpt: flush: sql = insert or replace into persists (id, name, data, rdCnt, rdTim, wrCnt, wrTim, deprecation) values (?, ?, ?, ?, ?, ?, ?, ?) Exception TypeError: 'NoneType' object is not callable in bound method Shelve2.__del__ of __main__.Shelve2 object at 0x7ff4c0513f90 ignored flush is being called from within __del__. I've narrowed it down to: print (flush: sql = , sql) curTim=nowI() print (flush: curTim = , curTim) nowI() is a function defined at the top of the file, and before the class, thus: defnowI(): t=int (time() * 100) returnt All I can guess is that there's some reason that an external to the class function shouldn't be called during a __del__. Is this correct? That seems to be the answer, as replacing the call to nowI() in flush() with: curTim = int (time() * 100) fixes the problem. Rereading the documentation, I guess that this should have been expected, but if nowI() were a static method of the class, would that have avoided the problem? A class method? -- Charles Hixson -- http://mail.python.org/mailman/listinfo/python-list
Re: Questions on __slots__
On 05/19/2012 06:39 AM, Adam Tauno Williams wrote: On Fri, 2012-05-18 at 09:53 -0700, Charles Hixson wrote: Does __slots__ make access to variables more efficient? Absolutely, yes. If one uses property() to create a few read-only pseudo-variables, does that negate the efficiency advantages of using __slots__? (Somehow I feel the documentation needs a bit of improvement.) If you are tempted to use property, setattr, etc... then do not use __slots__. __slots__ should really only be used for Fly Weight pattern type work, or at least for objects with a limited scope and will not be inherited from. Thank you. What I really wanted was a named list, sort of like a named tuple, only modifiable, but since the only way to do it was to create a class, I started thinking of reasonable operations for it to perform (data hiding, etc.) Sounds like I should go back to the named list idea. -- Charles Hixson -- http://mail.python.org/mailman/listinfo/python-list
Questions on __slots__
Does __slots__ make access to variables more efficient? If one uses property() to create a few read-only pseudo-variables, does that negate the efficiency advantages of using __slots__? (Somehow I feel the documentation needs a bit of improvement.) -- Charles Hixson -- http://mail.python.org/mailman/listinfo/python-list
non-pickle persistance for dicts?
I want to persist simple dicts, but due to the security problems with (un)pickle, I'd prefer to not use shelve, and the only way I could see to persist them onto sqlite also invoked pickle. As (un)pickle allows arbitrary system commands to be issued, I'd really rather just use a simple convert to and from either bytes or strings. repr works well for the conversion into string (I said they were simple), but I'd really rather be able to turn {'a': 'A', 1: 23, 2: ['b', 2]} back into a dict without allowing the execution of arbitrary commands. Any suggestions? -- Charles Hixson -- http://mail.python.org/mailman/listinfo/python-list
Re: non-pickle persistance for dicts?
On 05/16/2012 03:11 PM, Ian Kelly wrote: On Wed, May 16, 2012 at 3:52 PM, Charles Hixson charleshi...@earthlink.net wrote: I want to persist simple dicts, but due to the security problems with (un)pickle, I'd prefer to not use shelve, and the only way I could see to persist them onto sqlite also invoked pickle. As (un)pickle allows arbitrary system commands to be issued, I'd really rather just use a simple convert to and from either bytes or strings. repr works well for the conversion into string (I said they were simple), but I'd really rather be able to turn {'a': 'A', 1: 23, 2: ['b', 2]} back into a dict without allowing the execution of arbitrary commands. Any suggestions? Either json, or repr with ast.literal_eval will be safe. import json d = {'a': 'A', 1: 23, 2: ['b', 2]} json.dumps(d) '{a: A, 1: 23, 2: [b, 2]}' json.loads(json.dumps(d)) {'a': 'A', '1': 23, '2': ['b', 2]} import ast ast.literal_eval(repr(d)) {'a': 'A', 1: 23, 2: ['b', 2]} Cheers, Ian Thanks. It looks like either would do what I need. Any suggestion as to how to choose between them? E.g., is AST better supported? faster? (I'm tending towards AST purely because it seems more tied to Python, but of course that *could* be a disadvantage, if there were more external tools for working with json.) -- Charles Hixson -- http://mail.python.org/mailman/listinfo/python-list
Re: indexed property? Can it be done?
On 05/08/2012 12:50 AM, Peter Otten wrote: Charles Hixson wrote: class Node: def__init__(self, nodeId, key, value, downRight, downLeft, parent): dirty=True dlu=utcnow() self.node=[nodeId, downLeft, [key], [value], [downRight], parent, dirty, dlu] Note that node[3] is a list of keys (initially 1) and node[3] is a list of values, etc. What I'd like to do is to be able to address them thusly: k = node.key[2] v = node.value[2] but if there's a way to do this, I haven't been able to figure it out. Any suggestions? I don't see the problem: class Node(object): ... def __init__(self, key): ... self.node = [foo, bar, [key], baz] ... @property ... def key(self): ... return self.node[2] ... node = Node(42) node.key [42] node.key[0] 42 node.key.append(7) node.key [42, 7] del node.key[0] node.key[:] = [3, 2, 1] node.key [3, 2, 1] node.key = foo Traceback (most recent call last): File stdin, line 1, inmodule AttributeError: can't set attribute But the design proposed by Dan Sommers really is the way to go... That depends on what you're doing. For many, perhaps most, purposes I would agree. Not for this one. And I couldn't use an internal dict, as the order in which the items of the sub-lists occur is significant. The sub-lists need to be lists, though they could be separated out as named variables (which would be lists). The approach of returning the entire list would, indeed, work, but it exposes things that I would prefer to keep internal to the class (i.e., all the, e.g., keys that aren't currently being addressed). I suppose it isn't too inefficient, as IIUC, all you're really passing back and forth are pointers, but it doesn't *feel* like the right answer. So I can handle it by using getter and setter functions that recognize indicies, but it's less elegant than using indexing to access them. So I thought I'd ask. The ActiveState recipe *might* do what I want. I honestly can't tell after a brief study. But it's much too complex to be a worthwhile choice. I was hoping that I'd just overlooked one of the standard features of Python. To be truthful, the main benefit I see from using a class rather than a naked list structure is that I can readily test the type of the data. A secondary benefit would be the nicer syntax, as with the list all manipulation would be done via specialized functions, and for some of the terms indexed access would be syntactically nicer. But it looks like that isn't one of the possibilities. Using a native list structure and manipulatory functions is nicer except in two ways: 1) There's no data hiding, so discipline must substitute for language structure. 2) There's excess names apparent at an upper level. I wouldn't exactly call it namespace pollution, but it's certainly an increase in the higher-level namespace background noise level, even though it's all functional. -- Charles Hixson -- http://mail.python.org/mailman/listinfo/python-list
Re: indexed property? Can it be done?
On 05/08/2012 01:19 PM, Adam Tauno Williams wrote: On Mon, 2012-05-07 at 20:15 -0700, Charles Hixson wrote: class Node: def__init__(self, nodeId, key, value, downRight, downLeft, parent): dirty=True dlu=utcnow() self.node=[nodeId, downLeft, [key], [value], [downRight], parent, dirty, dlu] Note that node[3] is a list of keys (initially 1) and node[3] is a list of values, etc. What I'd like to do is to be able to address them thusly: k = node.key[2] v = node.value[2] but if there's a way to do this, I haven't been able to figure it out. Any suggestions? Do not do this; this is bad code in any language. I'm sorry, but why do you say that? In D or Eiffel it is a standard approach, with compiler support. I will admit that one shouldn't do it in C++, or, it appears, in Python. This is far from justifying saying one should never do it. -- Charles Hixson -- http://mail.python.org/mailman/listinfo/python-list
indexed property? Can it be done?
class Node: def__init__(self, nodeId, key, value, downRight, downLeft, parent): dirty=True dlu=utcnow() self.node=[nodeId, downLeft, [key], [value], [downRight], parent, dirty, dlu] Note that node[3] is a list of keys (initially 1) and node[3] is a list of values, etc. What I'd like to do is to be able to address them thusly: k = node.key[2] v = node.value[2] but if there's a way to do this, I haven't been able to figure it out. Any suggestions? -- Charles Hixson -- http://mail.python.org/mailman/listinfo/python-list
Re: indexed property? Can it be done?
On 05/07/2012 08:33 PM, Chris Rebert wrote: On Mon, May 7, 2012 at 8:15 PM, Charles Hixson charleshi...@earthlink.net wrote: class Node: def__init__(self, nodeId, key, value, downRight, downLeft, parent): dirty=True dlu=utcnow() self.node=[nodeId, downLeft, [key], [value], [downRight], parent, dirty, dlu] Why are you using a single opaque list instead of separate, meaningful attributes for each datum? Cheers, Chris Because that's the most reasonable implementation. The various list items would not be the same from instance to instance. I could pull the top-level list items off as separate variables, but this would leave the problem exactly where it is, and ordinary properties allow me to address the entries like id, and dlu without problem. But the list variables are a separate problem, and not so readily soluble. FWIW, if I must I can operate with only a list, and define functions to do the access and manipulation. I'd rather not, which is why I'm exploring whether an indexed property is feasible. Note that I *could* return, e.g., the entire keys list, but I'd rather use a bit more data protection than that. Which is what an indexed setter property would allow. And node.key[3] is as fully informative a name as I can construct for that entry. But the number of items in the keys list varies from node to node, so defining a key3 property is not reasonable. (Besides, that's so ugly that I'd rather use a function, even though indexing in Python really should be done with brackets rather than parens.) -- Charles Hixson -- http://mail.python.org/mailman/listinfo/python-list
Re: indexed property? Can it be done?
On 05/07/2012 08:44 PM, Dan Sommers wrote: On Mon, 07 May 2012 20:15:36 -0700 Charles Hixsoncharleshi...@earthlink.net wrote: class Node: def__init__(self, nodeId, key, value, downRight, downLeft, parent): dirty=True dlu=utcnow() self.node=[nodeId, downLeft, [key], [value], [downRight], parent, dirty, dlu] Note that node[3] is a list of keys (initially 1) and node[3] is a list of values, etc. What I'd like to do is to be able to address them thusly: k = node.key[2] v = node.value[2] but if there's a way to do this, I haven't been able to figure it out. Any suggestions? Untested: def __init__(self, nodeId, key, value, downRight, downLeft, parent): dirty = True dlu = utcnow() self.node = [nodeId, downLeft, dict(key=value), [downRight], parent, dirty, dlu] Now you can use self.node[2][key] to get/set value. But why not make the elements of node their own attributes? Untested: def __init__(self, nodeId, key, value, downRight, downLeft, parent): self.dirty = True self.dlu = utcnow() self.nodeId = nodeId self.downLeft = downLeft self.downRight = downRight self.values = dict(key=value) self.parent = parent And then you don't have to remember that node[2] is the key/value pairs (note the typo (the two 3s) in your original post). With each attribute in its own, well, attribute, you can always use node.values[key] to access the value associated with a particular key. HTH, Dan Did you notice that the node list contained sublists? I can access the top level node items through ordinary properties, and that is my intent. So I don't need to remember what top level index represents what item. But the second level items are variable in length, so I really want to do an indexed access to them. Yes, I admit that in the snipped defined by the __init__ method those secondary lists only received one entry. Other method would extend their length, to a variable amount for different class instances. A part of the reason that the class retains that top level list is so that if I can't create an indexed property to get and set them, I can revert to an alternative that is a bit uglier than this, but might be more efficient. (It would have methods that operated directly on the list rather than using properties for ANY of the approach...and avoid creating a class that they handle. Not as clean as what I'm hoping for, but so far I haven't come up with any way except functions that doesn't directly expose the data...and if I must use that approach, then the class doesn't buy me anything for the overhead.) -- Charles Hixson -- http://mail.python.org/mailman/listinfo/python-list
Re: Possible bug in string handling (with kludgy work-around)
That was it! Thanks. On 12/26/2011 02:44 PM, Chris Angelico wrote: On Tue, Dec 27, 2011 at 9:23 AM, Charles Hixson charleshi...@earthlink.net wrote: This doesn't cause a crash, but rather incorrect results. You may need to be a bit clearer. What line of code (or what expression)? What did you expect to see, and what did you see? From examining your code, I've come up with one most-likely scenario. In Python, indexing is zero-based and, in effect, indexes the boundaries between items rather than the items themselves. Referencing string[-1] actually means asking for the boundary between the second-last and last characters; using that as your end marker actually trims off the last character. What you may want is simply: self.wordList[i][1:] which means from character position 1 to the end of the string. Hope that helps! Chris Angelico Sorry I didn't specify things more clearly. -- Charles Hixson -- http://mail.python.org/mailman/listinfo/python-list
Possible bug in string handling (with kludgy work-around)
This doesn't cause a crash, but rather incorrect results. self.wordList=[The, quick, brown, fox, carefully, jumps, over, the, lazy, dog, as, it, stealthily, wends, its, way, homewards, '\b.'] foriinrange (len (self.wordList) ): ifnot isinstance(self.wordList[i], str): self.wordList = elif self.wordList[i] != and self.wordList[i][0] == \b: print (0: wordList[, i, ] = \, self.wordList[i], \, sep = ) print (0a: wordList[, i, ][1] = \, self.wordList[i][1], \, sep = ) tmp=self.wordList[i][1] ## !! Kludge -- remove tmp to see the error self.wordList[i]=tmp + self.wordList[i][1:-1] ## !! Kludge -- remove tmp + to see the error print (1: wordList[, i, ] = \, self.wordList[i], \, sep = ) print(len(wordList[, i, ]) = , len(self.wordList[i]) ) -- Charles Hixson -- http://mail.python.org/mailman/listinfo/python-list
Re: Python and Flaming Thunder
On Thursday 22 May 2008 13:30:07 Nick Craig-Wood wrote: ... From Armstrong's book: The expression Pattern = Expression causes Expression to be evaluated and the result matched against Pattern. The match either succeeds or fails. If the match succeeds any variables occurring in Pattern become bound. It is a very powerful idea and one which (along with the concurrency and message passing from Erlang) has been implemented for python :- http://candygram.sourceforge.net/ I've been reading the Erlang book and I have to say it has given me a lot of insight into python... Although when comparing Candygram with Erlang it's worth noting that Candygram is bound to one processor, where Erlang can operate on multiple processors. (I'd been planning on using Candygram for a project at one point, but this made it unusable.) -- http://mail.python.org/mailman/listinfo/python-list
comparison puzzle? bug?
I hesitate to call this a bug, as at my level of expertise that seems ... unlikely. But I can't think of any other explanation: This is an extract from some longer code: printitem = , item printitem[0] lvl = %d %d = %(item[0], lvl), bool(item[0] lvl) printitem[0] == lvl = %d == %d = %(item[0], lvl), bool(item[0] == lvl) printitem[0] lvl = %d %d = %(item[0], lvl), bool(item[0] == lvl) yields: item = [1, 'A', '/home/.../data/n1a.gif', Surface(102x78x32 SW)] tem[0] lvl = 1 0 = False item[0] == lvl = 1 == 0 = False item[0] lvl = 1 0 = False I abbreviated that file path. Any ideas what's going on? -- http://mail.python.org/mailman/listinfo/python-list
Re: Boo who? (was Re: newbie question)
Terry Reedy wrote: Luis M. Gonzalez [EMAIL PROTECTED] wrote in message news:[EMAIL PROTECTED] ... It is as important and python related as other projects such as PyPy, Stackless, but I think this is silly. PyPy is an alternate implementation of Python, not a different language. Stackless is a compiled extension, like many others, that works with the standard implementation or maybe still a minor modification thereof. Where would you classify Pyrex? Language boundaries are somewhat artificial, but Pyrex clearly doesn't intend to be as similar to Python as PyPy does. Still, it's close enough to almost be considered a language extension. If one wanted to bother, one could probably construct a language slightly more similar to Python than Pyrex, and another slightly less similar. This couldn't continue forever, as the domain is discrete. But it could go a long!! way. One could probably arrive at a graded series of languages between Python and C (probably along several different transformation vectors). And slightly off to the side would be Python 2.5 and C2006 (or whatever year the next version is defined). But some of the languages in the series would be more similar to current Python than is Python 2.5. So. A language is a series of specifications made at differnt times, and has a fuzzy surround of implementations which nearly meet the specifications. And this is true even where one of the implementations itself is designated as the primary specification (because people will argue that this feature or that is wrongly implemented). Still, even given all that, Boo is clearly outside the area that is Python. (One could have a minimal acceptable distance which could be thought of as running correctly most of the programs that the core language would run correctly.) -- http://mail.python.org/mailman/listinfo/python-list
Re: Boo who? (was Re: newbie question)
Grant Edwards wrote: That seems to imply that you think market sucess == technical merits. Unless you mean that Prothon was a technical failure rather than a market-share failure... As Prothon never got as far as an alpha stage product, I don't think you could call it a technical success. It may well not have been a technical failure, as it didn't get far enough to become one, but it certainly was NOT a technical success. -- http://mail.python.org/mailman/listinfo/python-list