[issue32554] random.seed(tuple) uses the randomized hash function and so is not reproductible

2018-07-16 Thread Lee Griffiths


Lee Griffiths  added the comment:

a) This below issue added doc to py2.7 that calls out PYTHONHASHSEED, but py 
doesn't currently contain those words

https://bugs.python.org/issue27706

It'd be useful to have the something whether the "behaviour" is fixed or not, 
as providing other objects (like a tuple) will still be non-deterministic.

b) I don't know if this is the correct issue to heap this on, but I think it 
might as you're looking at changing the seed function? 

The documentation for `object.__hash__` calls out `str`, `bytes` and `datetime` 
as being affected by `PYTHONHASHSEED`. Doesn't it seem odd that there's a 
workaround in the seed function for str and bytes, but not for datetime?

https://docs.python.org/3/reference/datamodel.html#object.__hash__

I mainly point this out as seeding random with the current date/time is 
idiomatic in many languages and environments (usually used when you log the 
seed to be able to recreate things later, or just blindly copying the 
historical use `srand(time(NULL))` from C programs!). Anyone shoving a datetime 
straight into seed() is going to find it non-deterministic and might not 
understand why, or even notice, especially as the documentation for seed() 
doesn't call this out. 

Those "in the know" will get a unix timestamp out of the datetime and put that 
in seed instead, but I feel that falls under the same argument as 
users-in-the-know SHA512ing a string, mentioned above, which is undesirable and 
apparently something the function should implement and not users.

Would it be wise for datetime to have a specific implementation as well?

--
nosy: +poddster

___
Python tracker 
<https://bugs.python.org/issue32554>
___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue29372] RotatingFileHandler rotates empty logfile if it emits a large string

2017-01-25 Thread Lee Griffiths

New submission from Lee Griffiths:

If you write a really big string to an empty file, and that string is > 
maxBytes, then `RotatingFileHandler` (or even `BaseRotatingHandler`) will roll 
that empty file into the backup queue.

I think it should instead use that empty file for the mega-string. By not doing 
so it "wastes" a slot in the backup queue.

It's a very minor issue: I doubt it really happens IRL, but I noticed it when 
extending RotatingFileHandler in py2.7 to add gzip stuff and my test cases used 
a really small size (16 bytes!)


Here's a test file:

#!/usr/bin/env python3
# coding=utf-8

import logging
import os
import tempfile

from logging.handlers import RotatingFileHandler


class MockRecord(object):
def __init__(self, msg):
self.msg = msg
self.stack_info = None
self.exc_info = None
self.exc_text = None

def getMessage(self):
return self.msg


def test_file_rollover_from_mega_string(temp_dir_path):
# This is a pretty weird test.
# It tests that writing a huge string to a blank file causes the blank
# file to be archived and the huge string written to the next log file.
#
# Normally the log files would have a large max bytes so we'd have to
# be writing a giant string to an empty file for this to happen.
# But, even if it does, it's what BaseRotatingHandler does, so...

log_path = os.path.join(temp_dir_path, "mylog.log")

handler = RotatingFileHandler(log_path, maxBytes=16, backupCount=5)
handler.setFormatter(logging.Formatter())
with open(log_path) as log:
assert log.read() == ""

# --
handler.emit(MockRecord("There once was a test from bitbucket"))
with open(log_path) as log:
log_read = log.read()
assert log_read == "There once was a test from bitbucket\n"

with open(log_path + ".1") as log:
log_read = log.read()
assert log_read == ""

# --
handler.emit(MockRecord("11 chars"))
with open(log_path) as log:
log_read = log.read()
assert log_read == "11 chars\n"

with open(log_path + ".1") as log:
log_read = log.read()
assert log_read == "There once was a test from bitbucket\n"

with open(log_path + ".2") as log:
log_read = log.read()
assert log_read == ""

handler.close()


test_file_rollover_from_mega_string(tempfile.mkdtemp())


and here's a patch that I think will fix it:

~/src/others/cpython (master *%=)$ cat empty_rollover.patch 
diff --git a/Lib/logging/handlers.py b/Lib/logging/handlers.py
index 7d77973..0dabfd7 100644
--- a/Lib/logging/handlers.py
+++ b/Lib/logging/handlers.py
@@ -186,7 +186,11 @@ class RotatingFileHandler(BaseRotatingHandler):
 if self.maxBytes > 0:   # are we rolling over?
 msg = "%s\n" % self.format(record)
 self.stream.seek(0, 2)  #due to non-posix-compliant Windows feature
-if self.stream.tell() + len(msg) >= self.maxBytes:
+size = self.stream.tell()
+if size == 0:
+# No point rolling-over an empty file
+return 0
+elif size + len(msg) >= self.maxBytes:
 return 1
 return 0

--
components: Library (Lib)
messages: 286265
nosy: Poddster, vinay.sajip
priority: normal
severity: normal
status: open
title: RotatingFileHandler rotates empty logfile if it emits a large string
type: resource usage
versions: Python 2.7, Python 3.7

___
Python tracker 
<http://bugs.python.org/issue29372>
___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com