internlm/SWE-Fixer-Train-110K huggingface dataset:
Repository: nltk/nltk

Issue:
`TreebankWordDetokenizer` inconsistent with recombining contractions
Hello!

## Details
Some quick tests I ran:
```python
from nltk.tokenize import TreebankWordDetokenizer
>>> TreebankWordDetokenizer().tokenize(["Do", "n't"])
"Do n't"
>>> TreebankWordDetokenizer().tokenize(["Do", "n't", "want"])
"Don't want"
>>> TreebankWordDetokenizer().tokenize(["I", "'ve"])  
"I 've"
>>> TreebankWordDetokenizer().tokenize(["I", "'ve", "seen"])
"I've seen"
```
And a quick testing script I wrote:
```python
from nltk.tokenize import TreebankWordDetokenizer, TreebankWordTokenizer

tests = [
    "Don't",
    "Don't.",
    "Don't bother",
    "I've",
    "I've.",
    "I've not",
]

tokenizer = TreebankWordTokenizer()
detokenizer = TreebankWordDetokenizer()

for test in tests:
    tokenized = tokenizer.tokenize(test)
    tetokenized = detokenizer.detokenize(tokenized)
    
    print(f"{test=}")
    print(f"{tokenized=}")
    print(f"{tetokenized=}\n")
```
With the following output (annotated by me):
```python
test="Don't"
tokenized=['Do', "n't"]
tetokenized="Do n't" # Wrong

test="Don't."
tokenized=['Do', "n't", '.']
tetokenized="Don't." # Right

test="Don't bother"
tokenized=['Do', "n't", 'bother']
tetokenized="Don't bother" # Right

test="I've"
tokenized=['I', "'ve"]
tetokenized="I 've" # Wrong

test="I've."
tokenized=['I', "'ve", '.']
tetokenized="I've." # Right

test="I've not"
tokenized=['I', "'ve", 'not']
tetokenized="I've not" # Right
```

- Tom Aarsen


Discussion:
Additional test outputs:
```python
test="I'd"
tokenized=['I', "'d"]
tetokenized="I 'd"

test="I'd."
tokenized=['I', "'d", '.']
tetokenized="I'd."

test="I'd totally"
tokenized=['I', "'d", 'totally']
tetokenized="I'd totally"
```

Resolving patch:
diff --git a/nltk/tokenize/treebank.py b/nltk/tokenize/treebank.py
--- a/nltk/tokenize/treebank.py
+++ b/nltk/tokenize/treebank.py
@@ -357,6 +357,10 @@ def tokenize(self, tokens: List[str], convert_parentheses: bool = False) -> str:
         :return: str
         """
         text = " ".join(tokens)
+
+        # Add extra space to make things easier
+        text = " " + text + " "
+
         # Reverse the contractions regexes.
         # Note: CONTRACTIONS4 are not used in tokenization.
         for regexp in self.CONTRACTIONS3:


Test patch:
diff --git a/nltk/test/tokenize.doctest b/nltk/test/tokenize.doctest
--- a/nltk/test/tokenize.doctest
+++ b/nltk/test/tokenize.doctest
@@ -132,6 +132,15 @@ Testing treebank's detokenizer
     >>> s = "(Sentence) starting with parentheses."
     >>> detokenizer.detokenize(word_tokenize(s))
     '(Sentence) starting with parentheses.'
+    >>> s = "I've"
+    >>> detokenizer.detokenize(word_tokenize(s))
+    "I've"
+    >>> s = "Don't"
+    >>> detokenizer.detokenize(word_tokenize(s))
+    "Don't"
+    >>> s = "I'd"
+    >>> detokenizer.detokenize(word_tokenize(s))
+    "I'd"
 
 
 Sentence tokenization in word_tokenize:
Repository: nltk/nltk

Issue:
Only return `ax` object by default in `plot` methods, instead of plotting by default
In the following locations:
* https://github.com/nltk/nltk/blob/f989fe65d421e7ea4d1037a00f07eaeee3ad6a29/nltk/probability.py#L247-L249
* https://github.com/nltk/nltk/blob/f989fe65d421e7ea4d1037a00f07eaeee3ad6a29/nltk/probability.py#L1922-L1932
* https://github.com/nltk/nltk/blob/f989fe65d421e7ea4d1037a00f07eaeee3ad6a29/nltk/text.py#L607

We should by default merely return the matplotlib `ax` object, rather than showing the plot. That way, users can still modify the graph themselves, or save it rather than plotting it. As @iliakur rightfully mentioned in the discussion regarding this issue in https://github.com/nltk/nltk/pull/2786#issuecomment-905283065, a Jupyter notebook would still render the plot even if we only return it. In the future, people will have to invoke `.plot()`, and then perform `plt.show()`, where `plt` imported as `import matplotlib.pyplot as plt`. 

These changes can easily be implemented by setting `show=False` as default in the first two method, and adding `return` to the third method.

This issue is planned to be resolved for the next major release.

- Tom Aarsen


Discussion:

Resolving patch:
diff --git a/nltk/probability.py b/nltk/probability.py
--- a/nltk/probability.py
+++ b/nltk/probability.py
@@ -245,7 +245,7 @@ def max(self):
         return self.most_common(1)[0][0]
 
     def plot(
-        self, *args, title="", cumulative=False, percents=False, show=True, **kwargs
+        self, *args, title="", cumulative=False, percents=False, show=False, **kwargs
     ):
         """
         Plot samples from the frequency distribution
@@ -1927,7 +1927,7 @@ def plot(
         cumulative=False,
         percents=False,
         conditions=None,
-        show=True,
+        show=False,
         **kwargs,
     ):
         """


Test patch:
Repository: nltk/nltk

Issue:
SentimentIntensityAnalyzer() from nltk.sentiment.vader does not respond to hashtags. 
Example: 
```
SentimentIntensityAnalyzer.polarity_scores( 'Strings with hashtag #stupid #useless #BAD' )  
... compound: 0.0, 
... neg: 0.0, 
... neu: 1.0, 
... pos: 0.0,
```


Discussion:

Resolving patch:
diff --git a/nltk/sentiment/vader.py b/nltk/sentiment/vader.py
--- a/nltk/sentiment/vader.py
+++ b/nltk/sentiment/vader.py
@@ -356,6 +356,11 @@ def polarity_scores(self, text):
         Return a float for sentiment strength based on the input text.
         Positive values are positive valence, negative value are negative
         valence.
+
+        :note: Hashtags are not taken into consideration (e.g. #BAD is neutral). If you
+            are interested in processing the text in the hashtags too, then we recommend
+            preprocessing your data to remove the #, after which the hashtag text may be
+            matched as if it was a normal word in the sentence.
         """
         # text, words_and_emoticons, is_cap_diff = self.preprocess(text)
         sentitext = SentiText(


Test patch:
Repository: nltk/nltk

Issue:
Safe to use on Python 3.11?
Is nltk 3.8 safe to use on Python 3.11? The [module's description and classifier tags](https://github.com/nltk/nltk/blob/3.8/setup.py#L68) only go up to Python 3.10.


Discussion:
Hello @kinghuang,

I have previously attempted to support Python 3.11 for NLTK officially, but at the time the test suite would fail as one of the dependencies didn't work on Python 3.11 yet. 
However, when re-doing those tests today, everything seems to work as intended.

With other words, feel free to use NLTK 3.8 on Python 3.11. I'll work on adding official support, but that only involves updating the module description, documentation, classifier tags and CI test suite.

- Tom Aarsen

Resolving patch:
diff --git a/nltk/__init__.py b/nltk/__init__.py
--- a/nltk/__init__.py
+++ b/nltk/__init__.py
@@ -52,7 +52,7 @@
 # Description of the toolkit, keywords, and the project's primary URL.
 __longdescr__ = """\
 The Natural Language Toolkit (NLTK) is a Python package for
-natural language processing.  NLTK requires Python 3.7, 3.8, 3.9 or 3.10."""
+natural language processing.  NLTK requires Python 3.7, 3.8, 3.9, 3.10 or 3.11."""
 __keywords__ = [
     "NLP",
     "CL",
@@ -88,6 +88,7 @@
     "Programming Language :: Python :: 3.8",
     "Programming Language :: Python :: 3.9",
     "Programming Language :: Python :: 3.10",
+    "Programming Language :: Python :: 3.11",
     "Topic :: Scientific/Engineering",
     "Topic :: Scientific/Engineering :: Artificial Intelligence",
     "Topic :: Scientific/Engineering :: Human Machine Interfaces",
diff --git a/setup.py b/setup.py
--- a/setup.py
+++ b/setup.py
@@ -67,7 +67,7 @@
     },
     long_description="""\
 The Natural Language Toolkit (NLTK) is a Python package for
-natural language processing.  NLTK requires Python 3.7, 3.8, 3.9 or 3.10.""",
+natural language processing.  NLTK requires Python 3.7, 3.8, 3.9, 3.10 or 3.11.""",
     license="Apache License, Version 2.0",
     keywords=[
         "NLP",
@@ -99,6 +99,7 @@
         "Programming Language :: Python :: 3.8",
         "Programming Language :: Python :: 3.9",
         "Programming Language :: Python :: 3.10",
+        "Programming Language :: Python :: 3.11",
         "Topic :: Scientific/Engineering",
         "Topic :: Scientific/Engineering :: Artificial Intelligence",
         "Topic :: Scientific/Engineering :: Human Machine Interfaces",


Test patch:
Repository: nltk/nltk

Issue:
Open Multilingual Wordnet support
I just noticed, that the documentation on the NLTK website references Open Multilingual Wordnet, however the link given there seems to be broken (https://www.nltk.org/api/nltk.corpus.reader.wordnet.html). This seems to be a long term known issue in the Open Multilingual Wordnet project  (https://github.com/globalwordnet/OMW/issues/110). Thus, maybe a reference to the OMW GitHub guide documenting how to self-host (https://github.com/globalwordnet/OMW/blob/develop/INSTALL.md) and how to work with the self-host with NLTK in the NLTK dokumentation could be a better approach.   




Discussion:
@fcbond, may have better option. 

Resolving patch:
diff --git a/nltk/corpus/reader/wordnet.py b/nltk/corpus/reader/wordnet.py
--- a/nltk/corpus/reader/wordnet.py
+++ b/nltk/corpus/reader/wordnet.py
@@ -26,7 +26,7 @@
 
 This module also allows you to find lemmas in languages
 other than English from the Open Multilingual Wordnet
-http://compling.hss.ntu.edu.sg/omw/
+https://omwn.org/
 
 """
 
@@ -2179,7 +2179,7 @@ def custom_lemmas(self, tab_file, lang):
         language to Princeton WordNet 3.0 synset offsets, allowing NLTK's
         WordNet functions to then be used with that language.
 
-        See the "Tab files" section at http://compling.hss.ntu.edu.sg/omw/ for
+        See the "Tab files" section at https://omwn.org/omw1.html for
         documentation on the Multilingual WordNet tab file format.
 
         :param tab_file: Tab file as a file or file-like object


Test patch:
Repository: nltk/nltk

Issue:
Which Open English Wordnet version is useful?
Unlike the original Princeton WordNet, which has at least two widely used versions (3.0 and 3.1), it may not be relevant for NLTK to support all versions of the OEWN project, because these are not so widely used, and the most recent version tends to supersede all the preceding ones.
NLTK currently supports the 2021 edition of OEWN through the
_nltk_data/corpora/wordnet2021.zip_ package. An official 2022 edition is underway, but its data format has shifted to YAML, and it is not clear whether the OEWN project will also produce a data package in the original data format compatible with NLTK.
Meanwhile, the _wndb_ project by @1313ou at https://github.com/x-englishwordnet/wndb already supplies suitable packages for OEWN 2022, that work well with NLTK.

This raises a few questions:
1. Should the next OEWN package replace the preceding one?
2. Should NLTK prefer the official or an alternative package source for OEWN data?
3. Should _wordnet.py_ aim at supporting YAML?



Discussion:
The OEWN 2022 WNDB package you are referring to is built direct from the YAML files (latest master commit), and does away with the intermediate XML stage. The [OEWNTK](https://github.com/oewntk/project) drives this generation.

Resolving patch:
diff --git a/nltk/corpus/__init__.py b/nltk/corpus/__init__.py
--- a/nltk/corpus/__init__.py
+++ b/nltk/corpus/__init__.py
@@ -405,6 +405,12 @@
     WordNetCorpusReader,
     LazyCorpusLoader("omw-1.4", CorpusReader, r".*/wn-data-.*\.tab", encoding="utf8"),
 )
+# Latest Open English Wordnet:
+wordnet2022: WordNetCorpusReader = LazyCorpusLoader(
+    "wordnet2022",
+    WordNetCorpusReader,
+    LazyCorpusLoader("omw-1.4", CorpusReader, r".*/wn-data-.*\.tab", encoding="utf8"),
+)
 wordnet_ic: WordNetICCorpusReader = LazyCorpusLoader(
     "wordnet_ic", WordNetICCorpusReader, r".*\.dat"
 )


Test patch:
Repository: nltk/nltk

Issue:
TclError resizing download dialog table column
When attempting to resize a column in the downloader dialog, and error is raised and the column does not resize.

Steps to reproduce:
- Run `nltk.download()` to open downloading interface
- Try resizing any of the table columns (e.g. "Identifier" in the first tab)

An example full traceback is as follows:
```
Exception in Tkinter callback
Traceback (most recent call last):
  File "/usr/lib/python3.11/tkinter/__init__.py", line 1948, in __call__
    return self.func(*args)
           ^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.11/site-packages/nltk/draw/table.py", line 196, in _resize_column_motion_cb
    lb["width"] = max(3, lb["width"] + (x1 - x2) // charwidth)
    ~~^^^^^^^^^
  File "/usr/lib/python3.11/tkinter/__init__.py", line 1713, in __setitem__
    self.configure({key: value})
  File "/usr/lib/python3.11/tkinter/__init__.py", line 1702, in configure
    return self._configure('configure', cnf, kw)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.11/tkinter/__init__.py", line 1692, in _configure
    self.tk.call(_flatten((self._w, cmd)) + self._options(cnf))
_tkinter.TclError: expected integer but got "21.0"
```

The fix for this would be to simply change [`draw/table.py:196`](https://github.com/nltk/nltk/blob/56bc4af35906fb/nltk/draw/table.py#L196) from
```lb["width"] = max(3, lb["width"] + (x1 - x2) // charwidth)```
to
```lb["width"] = max(3, int(lb["width"] + (x1 - x2) // charwidth))```
(forcing the result of the floor div to be an int rather than float).


Discussion:

Resolving patch:
diff --git a/nltk/draw/table.py b/nltk/draw/table.py
--- a/nltk/draw/table.py
+++ b/nltk/draw/table.py
@@ -193,7 +193,7 @@ def _resize_column_motion_cb(self, event):
         x1 = event.x + event.widget.winfo_x()
         x2 = lb.winfo_x() + lb.winfo_width()
 
-        lb["width"] = max(3, lb["width"] + (x1 - x2) // charwidth)
+        lb["width"] = max(3, int(lb["width"] + (x1 - x2) // charwidth))
 
     def _resize_column_buttonrelease_cb(self, event):
         event.widget.unbind("<ButtonRelease-%d>" % event.num)


Test patch:
Repository: nltk/nltk

Issue:
Class 'CharTokenizer' is missing attribute '_string'
I think the class `CharTokenizer` is missing the attribute `_string=""`

https://github.com/nltk/nltk/blob/fc53edbf6f0763971afca5855386a2a382da37ac/nltk/tokenize/simple.py#L68-L77

Without this attribute, when trying to use the class, I get the following error:

`TypeError: Can't instantiate abstract class CharTokenizer with abstract method _string`

Example code:

```python
from nltk.tokenize.simple import CharTokenizer


tokenizer = CharTokenizer()
```

Error:

```bash
Traceback (most recent call last):
  File "/home/francis/.local/share/virtualenvs/cafa-challenge-bUqSu2Tm/lib/python3.10/site-packages/IPython/core/interactiveshell.py", line 3508, in run_code
    exec(code_obj, self.user_global_ns, self.user_ns)
  File "<ipython-input-7-803c2e672729>", line 1, in <module>
    tokenizer = CharTokenizer()
TypeError: Can't instantiate abstract class CharTokenizer with abstract method _string
```


Discussion:

Resolving patch:
diff --git a/nltk/tokenize/simple.py b/nltk/tokenize/simple.py
--- a/nltk/tokenize/simple.py
+++ b/nltk/tokenize/simple.py
@@ -70,6 +70,8 @@ class CharTokenizer(StringTokenizer):
     is ever required directly, use ``for char in string``.
     """
 
+    _string = None
+
     def tokenize(self, s):
         return list(s)
 


Test patch:
diff --git a/nltk/test/unit/test_tokenize.py b/nltk/test/unit/test_tokenize.py
--- a/nltk/test/unit/test_tokenize.py
+++ b/nltk/test/unit/test_tokenize.py
@@ -16,6 +16,7 @@
     sent_tokenize,
     word_tokenize,
 )
+from nltk.tokenize.simple import CharTokenizer
 
 
 def load_stanford_segmenter():
@@ -865,3 +866,21 @@ class ExtLangVars(punkt.PunktLanguageVars):
     )
     def test_sent_tokenize(self, sentences: str, expected: List[str]):
         assert sent_tokenize(sentences) == expected
+
+    def test_string_tokenizer(self) -> None:
+        sentence = "Hello there"
+        tokenizer = CharTokenizer()
+        assert tokenizer.tokenize(sentence) == list(sentence)
+        assert list(tokenizer.span_tokenize(sentence)) == [
+            (0, 1),
+            (1, 2),
+            (2, 3),
+            (3, 4),
+            (4, 5),
+            (5, 6),
+            (6, 7),
+            (7, 8),
+            (8, 9),
+            (9, 10),
+            (10, 11),
+        ]
Repository: nltk/nltk

Issue:
`corpus_bleu` function does not catch all the expections when calling `weights[0][0]`
In your codes https://github.com/nltk/nltk/blob/e2d368e00ef806121aaa39f6e5f90d9f8243631b/nltk/translate/bleu_score.py#L201

I pass in `weights = array([0.25, 0.25, 0.25, 0.25])` and find this error:

```
File "/home/cyzhao/miniconda3/envs/prompt/lib/python3.11/site-packages/nltk/translate/bleu_score.py", line 200, in corpus_bleu
    weights[0][0]
    ~~~~~~~~~~^^^
IndexError: invalid index to scalar variable.
"""
```

I then find out the reason why.

Not all exceptions are completely caught. The `weights` passed in by the framework are `array([0.25, 0.25, 0.25, 0.25])`, and for `ndarray` the error is `IndexError: invalid index to scalar variable`. Hence, these codes haven't caught all the exceptions, leading to the situation where one must pass a tuple `(0.25, 0.25, 0.25, 0.25)` to be caught by this try-except block.


Discussion:
Hello!

> The function's parameter is supposed to be a tuple.

It can also be a list of tuples, as explained in the docstring. I suspect that the author of this piece of code lived by the [EAFP](https://docs.python.org/3/glossary.html#term-EAFP) principle for Python, causing this code to not be so strange at all. Beyond that, NLTK lives by a garbage-in-garbage-out rule, so incorrectly typed inputs can't be expected to work. 
That all said, I'll resolve your issue by replacing `except TypeError` with just `except`, but in the future I would watch your writing tone with these bug reports.

- Tom Aarsen
@tomaarsen Oops. Sorry for the wrong tone of bug reports and my carelessness. I changed it. Thanks for your support.

Resolving patch:
diff --git a/nltk/translate/bleu_score.py b/nltk/translate/bleu_score.py
--- a/nltk/translate/bleu_score.py
+++ b/nltk/translate/bleu_score.py
@@ -198,7 +198,7 @@ def corpus_bleu(
 
     try:
         weights[0][0]
-    except TypeError:
+    except:
         weights = [weights]
     max_weight_length = max(len(weight) for weight in weights)
 


Test patch:
diff --git a/nltk/test/unit/translate/test_bleu.py b/nltk/test/unit/translate/test_bleu.py
--- a/nltk/test/unit/translate/test_bleu.py
+++ b/nltk/test/unit/translate/test_bleu.py
@@ -5,6 +5,8 @@
 import io
 import unittest
 
+import numpy as np
+
 from nltk.data import find
 from nltk.translate.bleu_score import (
     SmoothingFunction,
@@ -217,6 +219,14 @@ def test_reference_or_hypothesis_shorter_than_fourgrams(self):
         except AttributeError:
             pass  # unittest.TestCase.assertWarns is only supported in Python >= 3.2.
 
+    def test_numpy_weights(self):
+        # Test case where there's 0 matches
+        references = ["The candidate has no alignment to any of the references".split()]
+        hypothesis = "John loves Mary".split()
+
+        weights = np.array([0.25] * 4)
+        assert sentence_bleu(references, hypothesis, weights) == 0
+
 
 class TestBLEUvsMteval13a(unittest.TestCase):
     def test_corpus_bleu(self):
Repository: Pyomo/pyomo

Issue:
XPRESS Solver Error : AttributeError: 'NoneType' object has no attribute 'problem'
I've pasted the traceback below :

```
Traceback (most recent call last):
  File "model.py", line 15, in <module>
    solver.solve(model)
  File "/Users/$USER/anaconda/lib/python2.7/site-packages/pyomo/opt/base/solvers.py", line 587, in solve
    result = self._postsolve()
  File "/Users/$USER/anaconda/lib/python2.7/site-packages/pyomo/opt/solver/shellcmd.py", line 267, in _postsolve
    results = self.process_output(self._rc)
  File "/Users/$USER/anaconda/lib/python2.7/site-packages/pyomo/opt/solver/shellcmd.py", line 329, in process_output
    self.process_soln_file(results)
  File "/Users/$USER/anaconda/lib/python2.7/site-packages/pyomo/solvers/plugins/solvers/XPRESS.py", line 336, in process_soln_file
    results.problem.number_of_objectives=1
AttributeError: 'NoneType' object has no attribute 'problem'
```



Discussion:

Resolving patch:
diff --git a/pyomo/solvers/plugins/solvers/XPRESS.py b/pyomo/solvers/plugins/solvers/XPRESS.py
--- a/pyomo/solvers/plugins/solvers/XPRESS.py
+++ b/pyomo/solvers/plugins/solvers/XPRESS.py
@@ -198,8 +198,6 @@ def process_logfile(self):
         log_file_contents = "".join(log_file.readlines())
         log_file.close()
 
-        return
-
         for line in log_file_contents.split("\n"):
             tokens = re.split('[ \t]+',line.strip())
 


Test patch:
Repository: Pyomo/pyomo

Issue:
Unclear error from model.write with invalid file extension
The error given by `model.write` when the user provides an invalid file extension with the intention of relying on `guess_format` is unclear. See the following:

```
Python 2.7.12 (default, Nov 19 2016, 06:48:10) 
[GCC 5.4.0 20160609] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> from pyomo.environ import *
>>> m = ConcreteModel()
>>> m.write('file.something')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/gseastre/pyomo/src/pyomo/pyomo/core/base/block.py", line 1647, in write
    io_options)
TypeError: __call__() takes at most 3 arguments (5 given)
```

This appears to be due to the fact that `guess_format` returns `None` when the file extension does not match any know problem format. Thus, `model.write` is calling the return of `WriterFactory(None)`, which is a generic `PluginFactoryFunctor object`.

My feeling is that the error should indicate that no valid format could be determined from `guess_format`. I discovered this issue when I tried to input a .xlsx file without realizing I was not on my excel branch so .xlsx was not a supported format.


Discussion:
I'm sure that a PR with the relevant change would be welcome. =)

Resolving patch:
diff --git a/pyomo/core/base/block.py b/pyomo/core/base/block.py
--- a/pyomo/core/base/block.py
+++ b/pyomo/core/base/block.py
@@ -1633,6 +1633,12 @@ def write(self,
             format = ProblemFormat.cpxlp
         if (filename is not None) and (format is None):
             format = guess_format(filename)
+            if format is None:
+                raise ValueError(
+                    "Could not infer file format from file name '%s'.\n"
+                    "Either provide a name with a recognized extension "
+                    "or specify the format using the 'format' argument."
+                    % filename)
         problem_writer = WriterFactory(format)
         if problem_writer is None:
             raise ValueError(


Test patch:
diff --git a/pyomo/core/tests/unit/test_block.py b/pyomo/core/tests/unit/test_block.py
--- a/pyomo/core/tests/unit/test_block.py
+++ b/pyomo/core/tests/unit/test_block.py
@@ -2088,6 +2088,17 @@ def test_reserved_words(self):
         m.b.foo = 7
         self.assertIs(m.b.foo, 7)
 
+    def test_write_exceptions(self):
+        m = Block()
+        with self.assertRaisesRegexp(
+                ValueError, ".*Could not infer file format from file name"):
+            m.write(filename="foo.bogus")
+
+        with self.assertRaisesRegexp(
+                ValueError, ".*Cannot write model in format"):
+            m.write(format="bogus")
+
+
 
 if __name__ == "__main__":
     unittest.main()