57 import threading |
57 import threading |
58 import killdaemons as killmod |
58 import killdaemons as killmod |
59 import Queue as queue |
59 import Queue as queue |
60 |
60 |
61 processlock = threading.Lock() |
61 processlock = threading.Lock() |
|
62 |
|
63 # subprocess._cleanup can race with any Popen.wait or Popen.poll on py24 |
|
64 # http://bugs.python.org/issue1731717 for details. We shouldn't be producing |
|
65 # zombies but it's pretty harmless even if we do. |
|
66 if sys.version_info[1] < 5: |
|
67 subprocess._cleanup = lambda: None |
62 |
68 |
63 closefds = os.name == 'posix' |
69 closefds = os.name == 'posix' |
64 def Popen4(cmd, wd, timeout, env=None): |
70 def Popen4(cmd, wd, timeout, env=None): |
65 processlock.acquire() |
71 processlock.acquire() |
66 p = subprocess.Popen(cmd, shell=True, bufsize=-1, cwd=wd, env=env, |
72 p = subprocess.Popen(cmd, shell=True, bufsize=-1, cwd=wd, env=env, |
570 |
576 |
571 def pytest(test, wd, options, replacements, env): |
577 def pytest(test, wd, options, replacements, env): |
572 py3kswitch = options.py3k_warnings and ' -3' or '' |
578 py3kswitch = options.py3k_warnings and ' -3' or '' |
573 cmd = '%s%s "%s"' % (PYTHON, py3kswitch, test) |
579 cmd = '%s%s "%s"' % (PYTHON, py3kswitch, test) |
574 vlog("# Running", cmd) |
580 vlog("# Running", cmd) |
575 if os.name == 'nt': |
|
576 replacements.append((r'\r\n', '\n')) |
|
577 return run(cmd, wd, options, replacements, env) |
581 return run(cmd, wd, options, replacements, env) |
578 |
582 |
579 needescape = re.compile(r'[\x00-\x08\x0b-\x1f\x7f-\xff]').search |
583 needescape = re.compile(r'[\x00-\x08\x0b-\x1f\x7f-\xff]').search |
580 escapesub = re.compile(r'[\x00-\x08\x0b-\x1f\\\x7f-\xff]').sub |
584 escapesub = re.compile(r'[\x00-\x08\x0b-\x1f\\\x7f-\xff]').sub |
581 escapemap = dict((chr(i), r'\x%02x' % i) for i in range(256)) |
585 escapemap = dict((chr(i), r'\x%02x' % i) for i in range(256)) |
586 return escapesub(escapef, s) |
590 return escapesub(escapef, s) |
587 |
591 |
588 def rematch(el, l): |
592 def rematch(el, l): |
589 try: |
593 try: |
590 # use \Z to ensure that the regex matches to the end of the string |
594 # use \Z to ensure that the regex matches to the end of the string |
591 if os.name == 'nt': |
|
592 return re.match(el + r'\r?\n\Z', l) |
|
593 return re.match(el + r'\n\Z', l) |
595 return re.match(el + r'\n\Z', l) |
594 except re.error: |
596 except re.error: |
595 # el is an invalid regex |
597 # el is an invalid regex |
596 return False |
598 return False |
597 |
599 |
598 def globmatch(el, l): |
600 def globmatch(el, l): |
599 # The only supported special characters are * and ? plus / which also |
601 # The only supported special characters are * and ? plus / which also |
600 # matches \ on windows. Escaping of these caracters is supported. |
602 # matches \ on windows. Escaping of these caracters is supported. |
601 if el + '\n' == l: |
603 if el + '\n' == l: |
602 if os.name == 'nt': |
604 if os.altsep: |
603 # matching on "/" is not needed for this line |
605 # matching on "/" is not needed for this line |
604 log("\nInfo, unnecessary glob: %s (glob)" % el) |
606 log("\nInfo, unnecessary glob: %s (glob)" % el) |
605 return True |
607 return True |
606 i, n = 0, len(el) |
608 i, n = 0, len(el) |
607 res = '' |
609 res = '' |
625 if el == l: # perfect match (fast) |
627 if el == l: # perfect match (fast) |
626 return True |
628 return True |
627 if el: |
629 if el: |
628 if el.endswith(" (esc)\n"): |
630 if el.endswith(" (esc)\n"): |
629 el = el[:-7].decode('string-escape') + '\n' |
631 el = el[:-7].decode('string-escape') + '\n' |
630 if el == l or os.name == 'nt' and el[:-1] + '\r\n' == l: |
|
631 return True |
|
632 if (el.endswith(" (re)\n") and rematch(el[:-6], l) or |
632 if (el.endswith(" (re)\n") and rematch(el[:-6], l) or |
633 el.endswith(" (glob)\n") and globmatch(el[:-8], l)): |
633 el.endswith(" (glob)\n") and globmatch(el[:-8], l)): |
634 return True |
634 return True |
635 return False |
635 return False |
636 |
636 |
945 (''.join(c.isalpha() and '[%s%s]' % (c.lower(), c.upper()) or |
945 (''.join(c.isalpha() and '[%s%s]' % (c.lower(), c.upper()) or |
946 c in '/\\' and r'[/\\]' or |
946 c in '/\\' and r'[/\\]' or |
947 c.isdigit() and c or |
947 c.isdigit() and c or |
948 '\\' + c |
948 '\\' + c |
949 for c in testtmp), '$TESTTMP')) |
949 for c in testtmp), '$TESTTMP')) |
|
950 replacements.append((r'\r\n', '\n')) |
950 else: |
951 else: |
951 replacements.append((re.escape(testtmp), '$TESTTMP')) |
952 replacements.append((re.escape(testtmp), '$TESTTMP')) |
952 |
953 |
953 env = createenv(options, testtmp, threadtmp, port) |
954 env = createenv(options, testtmp, threadtmp, port) |
954 createhgrc(env['HGRCPATH'], options) |
955 createhgrc(env['HGRCPATH'], options) |