nebius/SWE-rebench-V2-PRs huggingface dataset:
Repository: python-babel/babel
Pull request #289 (2015-12-20 13:08:04)

Allow passing a callable to `extract()`
This makes it much easier to do create custom extraction machinery without having to bother with external configuration files or Setuptools entry points.

sils1297: @akx hey, thanks for trying to help us! Please note that we're short of manpower, if you'd like to help please also consider reviewing other peoples PRs.

Your commit seems not to be compatible with Python 3.3 and lower, see https://travis-ci.org/python-babel/babel/jobs/97957737 . Could you fix that?

Patch:
diff --git a/babel/messages/extract.py b/babel/messages/extract.py
index 2f8084a..a0608d7 100644
--- a/babel/messages/extract.py
+++ b/babel/messages/extract.py
@@ -212,7 +212,8 @@ def extract(method, fileobj, keywords=DEFAULT_KEYWORDS, comment_tags=(),
     ...     print message
     (3, u'Hello, world!', [], None)
 
-    :param method: a string specifying the extraction method (.e.g. "python");
+    :param method: an extraction method (a callable), or
+                   a string specifying the extraction method (.e.g. "python");
                    if this is a simple name, the extraction function will be
                    looked up by entry point; if it is an explicit reference
                    to a function (of the form ``package.module:funcname`` or
@@ -231,7 +232,9 @@ def extract(method, fileobj, keywords=DEFAULT_KEYWORDS, comment_tags=(),
     :raise ValueError: if the extraction method is not registered
     """
     func = None
-    if ':' in method or '.' in method:
+    if callable(method):
+        func = method
+    elif ':' in method or '.' in method:
         if ':' not in method:
             lastdot = method.rfind('.')
             module, attrname = method[:lastdot], method[lastdot + 1:]
@@ -258,6 +261,7 @@ def extract(method, fileobj, keywords=DEFAULT_KEYWORDS, comment_tags=(),
                 'javascript': extract_javascript
             }
             func = builtin.get(method)
+
     if func is None:
         raise ValueError('Unknown extraction method %r' % method)
 


Test patch:
diff --git a/tests/messages/test_extract.py b/tests/messages/test_extract.py
index ded697f..fa03207 100644
--- a/tests/messages/test_extract.py
+++ b/tests/messages/test_extract.py
@@ -546,3 +546,9 @@ msg = _('')
             assert 'warning: Empty msgid.' in sys.stderr.getvalue()
         finally:
             sys.stderr = stderr
+
+    def test_extract_allows_callable(self):
+        def arbitrary_extractor(fileobj, keywords, comment_tags, options):
+            return [(1, None, (), ())]
+        for x in extract.extract(arbitrary_extractor, BytesIO(b"")):
+            assert x[0] == 1
Repository: python-babel/babel
Pull request #600 (2018-08-15 01:28:46)

add support to util.pathmatch for matching the start of a string
This PR adds support to `util.pathmatch` for forcing the match of the start of a string. This is useful for example if you want to place a `babel.cfg` file in a subdirectory and only extract messages from under that directory. The added (equivalent) syntax looks like so:

```ini
[python: ./**.py]
[python: ^**.py]
```



Patch:
diff --git a/babel/util.py b/babel/util.py
index 0150827..fb93f16 100644
--- a/babel/util.py
+++ b/babel/util.py
@@ -151,6 +151,16 @@ def pathmatch(pattern, filename):
     >>> pathmatch('**.py', 'templates/index.html')
     False
 
+    >>> pathmatch('./foo/**.py', 'foo/bar/baz.py')
+    True
+    >>> pathmatch('./foo/**.py', 'bar/baz.py')
+    False
+
+    >>> pathmatch('^foo/**.py', 'foo/bar/baz.py')
+    True
+    >>> pathmatch('^foo/**.py', 'bar/baz.py')
+    False
+
     >>> pathmatch('**/templates/*.html', 'templates/index.html')
     True
     >>> pathmatch('**/templates/*.html', 'templates/foo/bar.html')
@@ -167,7 +177,16 @@ def pathmatch(pattern, filename):
         '**/': '(?:.+/)*?',
         '**': '(?:.+/)*?[^/]+',
     }
-    buf = []
+
+    if pattern.startswith('^'):
+        buf = ['^']
+        pattern = pattern[1:]
+    elif pattern.startswith('./'):
+        buf = ['^']
+        pattern = pattern[2:]
+    else:
+        buf = []
+
     for idx, part in enumerate(re.split('([?*]+/?)', pattern)):
         if idx % 2:
             buf.append(symbols[part])


Test patch:
diff --git a/tests/test_util.py b/tests/test_util.py
index a3607d5..ef59110 100644
--- a/tests/test_util.py
+++ b/tests/test_util.py
@@ -31,6 +31,11 @@ def test_pathmatch():
     assert not util.pathmatch('**.py', 'templates/index.html')
     assert util.pathmatch('**/templates/*.html', 'templates/index.html')
     assert not util.pathmatch('**/templates/*.html', 'templates/foo/bar.html')
+    assert util.pathmatch('^foo/**.py', 'foo/bar/baz/blah.py')
+    assert not util.pathmatch('^foo/**.py', 'blah/foo/bar/baz.py')
+    assert util.pathmatch('./foo/**.py', 'foo/bar/baz/blah.py')
+    assert util.pathmatch('./blah.py', 'blah.py')
+    assert not util.pathmatch('./foo/**.py', 'blah/foo/bar/baz.py')
 
 
 def test_odict_pop():