We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Add flag to build environment.yml without build strings
https://gitter.im/conda/conda?at=59ef54ebe44c43700a70e9a4
https://twitter.com/drvinceknight/status/922837449092542464?ref_src=twsrc%5Etfw

> Due to hashes of packages being introduced in `envinronment.yml` I'm getting all sorts of issues with building envs from file. (Very new problem)

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `conda_env/env.py`
Content:
```
1 from __future__ import absolute_import, print_function
2 
3 import os
4 from collections import OrderedDict
5 from conda.base.context import context
6 from conda.cli import common  # TODO: this should never have to import form conda.cli
7 from conda.core.linked_data import linked
8 from copy import copy
9 from itertools import chain
10 
11 from . import compat, exceptions, yaml
12 from .pip_util import add_pip_installed
13 
14 def load_from_directory(directory):
15     """Load and return an ``Environment`` from a given ``directory``"""
16     files = ['environment.yml', 'environment.yaml']
17     while True:
18         for f in files:
19             try:
20                 return from_file(os.path.join(directory, f))
21             except exceptions.EnvironmentFileNotFound:
22                 pass
23         old_directory = directory
24         directory = os.path.dirname(directory)
25         if directory == old_directory:
26             break
27     raise exceptions.EnvironmentFileNotFound(files[0])
28 
29 
30 # TODO This should lean more on conda instead of divining it from the outside
31 # TODO tests!!!
32 def from_environment(name, prefix, no_builds=False, ignore_channels=False):
33     """
34         Get environment object from prefix
35     Args:
36         name: The name of environment
37         prefix: The path of prefix
38         no_builds: Whether has build requirement
39         ignore_channels: whether ignore_channels
40 
41     Returns:     Environment object
42     """
43     installed = linked(prefix, ignore_channels=ignore_channels)
44     conda_pkgs = copy(installed)
45     # json=True hides the output, data is added to installed
46     add_pip_installed(prefix, installed, json=True)
47 
48     pip_pkgs = sorted(installed - conda_pkgs)
49 
50     if no_builds:
51         dependencies = ['='.join(a.quad[0:3]) for a in sorted(conda_pkgs)]
52     else:
53         dependencies = ['='.join(a.quad[0:3]) for a in sorted(conda_pkgs)]
54     if len(pip_pkgs) > 0:
55         dependencies.append({'pip': ['=='.join(a.rsplit('-', 2)[:2]) for a in pip_pkgs]})
56     # conda uses ruamel_yaml which returns a ruamel_yaml.comments.CommentedSeq
57     # this doesn't dump correctly using pyyaml
58     channels = list(context.channels)
59     if not ignore_channels:
60         for dist in conda_pkgs:
61             if dist.channel not in channels:
62                 channels.insert(0, dist.channel)
63     return Environment(name=name, dependencies=dependencies, channels=channels, prefix=prefix)
64 
65 
66 def from_yaml(yamlstr, **kwargs):
67     """Load and return a ``Environment`` from a given ``yaml string``"""
68     data = yaml.load(yamlstr)
69     if kwargs is not None:
70         for key, value in kwargs.items():
71             data[key] = value
72     return Environment(**data)
73 
74 
75 def from_file(filename):
76     if not os.path.exists(filename):
77         raise exceptions.EnvironmentFileNotFound(filename)
78     with open(filename, 'r') as fp:
79         yamlstr = fp.read()
80         return from_yaml(yamlstr, filename=filename)
81 
82 
83 # TODO test explicitly
84 class Dependencies(OrderedDict):
85     def __init__(self, raw, *args, **kwargs):
86         super(Dependencies, self).__init__(*args, **kwargs)
87         self.raw = raw
88         self.parse()
89 
90     def parse(self):
91         if not self.raw:
92             return
93 
94         self.update({'conda': []})
95 
96         for line in self.raw:
97             if isinstance(line, dict):
98                 self.update(line)
99             else:
100                 self['conda'].append(common.arg2spec(line))
101 
102     # TODO only append when it's not already present
103     def add(self, package_name):
104         self.raw.append(package_name)
105         self.parse()
106 
107 
108 def unique(seq, key=None):
109     """ Return only unique elements of a sequence
110     >>> tuple(unique((1, 2, 3)))
111     (1, 2, 3)
112     >>> tuple(unique((1, 2, 1, 3)))
113     (1, 2, 3)
114     Uniqueness can be defined by key keyword
115     >>> tuple(unique(['cat', 'mouse', 'dog', 'hen'], key=len))
116     ('cat', 'mouse')
117     """
118     seen = set()
119     seen_add = seen.add
120     if key is None:
121         for item in seq:
122             if item not in seen:
123                 seen_add(item)
124                 yield item
125     else:  # calculate key
126         for item in seq:
127             val = key(item)
128             if val not in seen:
129                 seen_add(val)
130                 yield item
131 
132 
133 class Environment(object):
134     def __init__(self, name=None, filename=None, channels=None,
135                  dependencies=None, prefix=None):
136         self.name = name
137         self.filename = filename
138         self.prefix = prefix
139         self.dependencies = Dependencies(dependencies)
140 
141         if channels is None:
142             channels = []
143         self.channels = channels
144 
145     def add_channels(self, channels):
146         self.channels = list(unique(chain.from_iterable((channels, self.channels))))
147 
148     def remove_channels(self):
149         self.channels = []
150 
151     def to_dict(self):
152         d = yaml.dict([('name', self.name)])
153         if self.channels:
154             d['channels'] = self.channels
155         if self.dependencies:
156             d['dependencies'] = self.dependencies.raw
157         if self.prefix:
158             d['prefix'] = self.prefix
159         return d
160 
161     def to_yaml(self, stream=None):
162         d = self.to_dict()
163         out = compat.u(yaml.dump(d, default_flow_style=False))
164         if stream is None:
165             return out
166         stream.write(compat.b(out, encoding="utf-8"))
167 
168     def save(self):
169         with open(self.filename, "wb") as fp:
170             self.to_yaml(stream=fp)
171
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/conda_env/env.py b/conda_env/env.py
--- a/conda_env/env.py
+++ b/conda_env/env.py
@@ -48,9 +48,9 @@
     pip_pkgs = sorted(installed - conda_pkgs)
 
     if no_builds:
-        dependencies = ['='.join(a.quad[0:3]) for a in sorted(conda_pkgs)]
+        dependencies = ['='.join((a.name, a.version)) for a in sorted(conda_pkgs)]
     else:
-        dependencies = ['='.join(a.quad[0:3]) for a in sorted(conda_pkgs)]
+        dependencies = ['='.join((a.name, a.version, a.build)) for a in sorted(conda_pkgs)]
     if len(pip_pkgs) > 0:
         dependencies.append({'pip': ['=='.join(a.rsplit('-', 2)[:2]) for a in pip_pkgs]})
     # conda uses ruamel_yaml which returns a ruamel_yaml.comments.CommentedSeq

{"golden_diff": "diff --git a/conda_env/env.py b/conda_env/env.py\n--- a/conda_env/env.py\n+++ b/conda_env/env.py\n@@ -48,9 +48,9 @@\n     pip_pkgs = sorted(installed - conda_pkgs)\n \n     if no_builds:\n-        dependencies = ['='.join(a.quad[0:3]) for a in sorted(conda_pkgs)]\n+        dependencies = ['='.join((a.name, a.version)) for a in sorted(conda_pkgs)]\n     else:\n-        dependencies = ['='.join(a.quad[0:3]) for a in sorted(conda_pkgs)]\n+        dependencies = ['='.join((a.name, a.version, a.build)) for a in sorted(conda_pkgs)]\n     if len(pip_pkgs) > 0:\n         dependencies.append({'pip': ['=='.join(a.rsplit('-', 2)[:2]) for a in pip_pkgs]})\n     # conda uses ruamel_yaml which returns a ruamel_yaml.comments.CommentedSeq\n", "issue": "Add flag to build environment.yml without build strings\nhttps://gitter.im/conda/conda?at=59ef54ebe44c43700a70e9a4\r\nhttps://twitter.com/drvinceknight/status/922837449092542464?ref_src=twsrc%5Etfw\r\n\r\n> Due to hashes of packages being introduced in `envinronment.yml` I'm getting all sorts of issues with building envs from file. (Very new problem)\n", "before_files": [{"content": "from __future__ import absolute_import, print_function\n\nimport os\nfrom collections import OrderedDict\nfrom conda.base.context import context\nfrom conda.cli import common  # TODO: this should never have to import form conda.cli\nfrom conda.core.linked_data import linked\nfrom copy import copy\nfrom itertools import chain\n\nfrom . import compat, exceptions, yaml\nfrom .pip_util import add_pip_installed\n\ndef load_from_directory(directory):\n    \"\"\"Load and return an ``Environment`` from a given ``directory``\"\"\"\n    files = ['environment.yml', 'environment.yaml']\n    while True:\n        for f in files:\n            try:\n                return from_file(os.path.join(directory, f))\n            except exceptions.EnvironmentFileNotFound:\n                pass\n        old_directory = directory\n        directory = os.path.dirname(directory)\n        if directory == old_directory:\n            break\n    raise exceptions.EnvironmentFileNotFound(files[0])\n\n\n# TODO This should lean more on conda instead of divining it from the outside\n# TODO tests!!!\ndef from_environment(name, prefix, no_builds=False, ignore_channels=False):\n    \"\"\"\n        Get environment object from prefix\n    Args:\n        name: The name of environment\n        prefix: The path of prefix\n        no_builds: Whether has build requirement\n        ignore_channels: whether ignore_channels\n\n    Returns:     Environment object\n    \"\"\"\n    installed = linked(prefix, ignore_channels=ignore_channels)\n    conda_pkgs = copy(installed)\n    # json=True hides the output, data is added to installed\n    add_pip_installed(prefix, installed, json=True)\n\n    pip_pkgs = sorted(installed - conda_pkgs)\n\n    if no_builds:\n        dependencies = ['='.join(a.quad[0:3]) for a in sorted(conda_pkgs)]\n    else:\n        dependencies = ['='.join(a.quad[0:3]) for a in sorted(conda_pkgs)]\n    if len(pip_pkgs) > 0:\n        dependencies.append({'pip': ['=='.join(a.rsplit('-', 2)[:2]) for a in pip_pkgs]})\n    # conda uses ruamel_yaml which returns a ruamel_yaml.comments.CommentedSeq\n    # this doesn't dump correctly using pyyaml\n    channels = list(context.channels)\n    if not ignore_channels:\n        for dist in conda_pkgs:\n            if dist.channel not in channels:\n                channels.insert(0, dist.channel)\n    return Environment(name=name, dependencies=dependencies, channels=channels, prefix=prefix)\n\n\ndef from_yaml(yamlstr, **kwargs):\n    \"\"\"Load and return a ``Environment`` from a given ``yaml string``\"\"\"\n    data = yaml.load(yamlstr)\n    if kwargs is not None:\n        for key, value in kwargs.items():\n            data[key] = value\n    return Environment(**data)\n\n\ndef from_file(filename):\n    if not os.path.exists(filename):\n        raise exceptions.EnvironmentFileNotFound(filename)\n    with open(filename, 'r') as fp:\n        yamlstr = fp.read()\n        return from_yaml(yamlstr, filename=filename)\n\n\n# TODO test explicitly\nclass Dependencies(OrderedDict):\n    def __init__(self, raw, *args, **kwargs):\n        super(Dependencies, self).__init__(*args, **kwargs)\n        self.raw = raw\n        self.parse()\n\n    def parse(self):\n        if not self.raw:\n            return\n\n        self.update({'conda': []})\n\n        for line in self.raw:\n            if isinstance(line, dict):\n                self.update(line)\n            else:\n                self['conda'].append(common.arg2spec(line))\n\n    # TODO only append when it's not already present\n    def add(self, package_name):\n        self.raw.append(package_name)\n        self.parse()\n\n\ndef unique(seq, key=None):\n    \"\"\" Return only unique elements of a sequence\n    >>> tuple(unique((1, 2, 3)))\n    (1, 2, 3)\n    >>> tuple(unique((1, 2, 1, 3)))\n    (1, 2, 3)\n    Uniqueness can be defined by key keyword\n    >>> tuple(unique(['cat', 'mouse', 'dog', 'hen'], key=len))\n    ('cat', 'mouse')\n    \"\"\"\n    seen = set()\n    seen_add = seen.add\n    if key is None:\n        for item in seq:\n            if item not in seen:\n                seen_add(item)\n                yield item\n    else:  # calculate key\n        for item in seq:\n            val = key(item)\n            if val not in seen:\n                seen_add(val)\n                yield item\n\n\nclass Environment(object):\n    def __init__(self, name=None, filename=None, channels=None,\n                 dependencies=None, prefix=None):\n        self.name = name\n        self.filename = filename\n        self.prefix = prefix\n        self.dependencies = Dependencies(dependencies)\n\n        if channels is None:\n            channels = []\n        self.channels = channels\n\n    def add_channels(self, channels):\n        self.channels = list(unique(chain.from_iterable((channels, self.channels))))\n\n    def remove_channels(self):\n        self.channels = []\n\n    def to_dict(self):\n        d = yaml.dict([('name', self.name)])\n        if self.channels:\n            d['channels'] = self.channels\n        if self.dependencies:\n            d['dependencies'] = self.dependencies.raw\n        if self.prefix:\n            d['prefix'] = self.prefix\n        return d\n\n    def to_yaml(self, stream=None):\n        d = self.to_dict()\n        out = compat.u(yaml.dump(d, default_flow_style=False))\n        if stream is None:\n            return out\n        stream.write(compat.b(out, encoding=\"utf-8\"))\n\n    def save(self):\n        with open(self.filename, \"wb\") as fp:\n            self.to_yaml(stream=fp)\n", "path": "conda_env/env.py"}], "after_files": [{"content": "from __future__ import absolute_import, print_function\n\nimport os\nfrom collections import OrderedDict\nfrom conda.base.context import context\nfrom conda.cli import common  # TODO: this should never have to import form conda.cli\nfrom conda.core.linked_data import linked\nfrom copy import copy\nfrom itertools import chain\n\nfrom . import compat, exceptions, yaml\nfrom .pip_util import add_pip_installed\n\ndef load_from_directory(directory):\n    \"\"\"Load and return an ``Environment`` from a given ``directory``\"\"\"\n    files = ['environment.yml', 'environment.yaml']\n    while True:\n        for f in files:\n            try:\n                return from_file(os.path.join(directory, f))\n            except exceptions.EnvironmentFileNotFound:\n                pass\n        old_directory = directory\n        directory = os.path.dirname(directory)\n        if directory == old_directory:\n            break\n    raise exceptions.EnvironmentFileNotFound(files[0])\n\n\n# TODO This should lean more on conda instead of divining it from the outside\n# TODO tests!!!\ndef from_environment(name, prefix, no_builds=False, ignore_channels=False):\n    \"\"\"\n        Get environment object from prefix\n    Args:\n        name: The name of environment\n        prefix: The path of prefix\n        no_builds: Whether has build requirement\n        ignore_channels: whether ignore_channels\n\n    Returns:     Environment object\n    \"\"\"\n    installed = linked(prefix, ignore_channels=ignore_channels)\n    conda_pkgs = copy(installed)\n    # json=True hides the output, data is added to installed\n    add_pip_installed(prefix, installed, json=True)\n\n    pip_pkgs = sorted(installed - conda_pkgs)\n\n    if no_builds:\n        dependencies = ['='.join((a.name, a.version)) for a in sorted(conda_pkgs)]\n    else:\n        dependencies = ['='.join((a.name, a.version, a.build)) for a in sorted(conda_pkgs)]\n    if len(pip_pkgs) > 0:\n        dependencies.append({'pip': ['=='.join(a.rsplit('-', 2)[:2]) for a in pip_pkgs]})\n    # conda uses ruamel_yaml which returns a ruamel_yaml.comments.CommentedSeq\n    # this doesn't dump correctly using pyyaml\n    channels = list(context.channels)\n    if not ignore_channels:\n        for dist in conda_pkgs:\n            if dist.channel not in channels:\n                channels.insert(0, dist.channel)\n    return Environment(name=name, dependencies=dependencies, channels=channels, prefix=prefix)\n\n\ndef from_yaml(yamlstr, **kwargs):\n    \"\"\"Load and return a ``Environment`` from a given ``yaml string``\"\"\"\n    data = yaml.load(yamlstr)\n    if kwargs is not None:\n        for key, value in kwargs.items():\n            data[key] = value\n    return Environment(**data)\n\n\ndef from_file(filename):\n    if not os.path.exists(filename):\n        raise exceptions.EnvironmentFileNotFound(filename)\n    with open(filename, 'r') as fp:\n        yamlstr = fp.read()\n        return from_yaml(yamlstr, filename=filename)\n\n\n# TODO test explicitly\nclass Dependencies(OrderedDict):\n    def __init__(self, raw, *args, **kwargs):\n        super(Dependencies, self).__init__(*args, **kwargs)\n        self.raw = raw\n        self.parse()\n\n    def parse(self):\n        if not self.raw:\n            return\n\n        self.update({'conda': []})\n\n        for line in self.raw:\n            if isinstance(line, dict):\n                self.update(line)\n            else:\n                self['conda'].append(common.arg2spec(line))\n\n    # TODO only append when it's not already present\n    def add(self, package_name):\n        self.raw.append(package_name)\n        self.parse()\n\n\ndef unique(seq, key=None):\n    \"\"\" Return only unique elements of a sequence\n    >>> tuple(unique((1, 2, 3)))\n    (1, 2, 3)\n    >>> tuple(unique((1, 2, 1, 3)))\n    (1, 2, 3)\n    Uniqueness can be defined by key keyword\n    >>> tuple(unique(['cat', 'mouse', 'dog', 'hen'], key=len))\n    ('cat', 'mouse')\n    \"\"\"\n    seen = set()\n    seen_add = seen.add\n    if key is None:\n        for item in seq:\n            if item not in seen:\n                seen_add(item)\n                yield item\n    else:  # calculate key\n        for item in seq:\n            val = key(item)\n            if val not in seen:\n                seen_add(val)\n                yield item\n\n\nclass Environment(object):\n    def __init__(self, name=None, filename=None, channels=None,\n                 dependencies=None, prefix=None):\n        self.name = name\n        self.filename = filename\n        self.prefix = prefix\n        self.dependencies = Dependencies(dependencies)\n\n        if channels is None:\n            channels = []\n        self.channels = channels\n\n    def add_channels(self, channels):\n        self.channels = list(unique(chain.from_iterable((channels, self.channels))))\n\n    def remove_channels(self):\n        self.channels = []\n\n    def to_dict(self):\n        d = yaml.dict([('name', self.name)])\n        if self.channels:\n            d['channels'] = self.channels\n        if self.dependencies:\n            d['dependencies'] = self.dependencies.raw\n        if self.prefix:\n            d['prefix'] = self.prefix\n        return d\n\n    def to_yaml(self, stream=None):\n        d = self.to_dict()\n        out = compat.u(yaml.dump(d, default_flow_style=False))\n        if stream is None:\n            return out\n        stream.write(compat.b(out, encoding=\"utf-8\"))\n\n    def save(self):\n        with open(self.filename, \"wb\") as fp:\n            self.to_yaml(stream=fp)\n", "path": "conda_env/env.py"}]}